mnfst 0.5.261 → 0.5.263
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/lib/manifest.appwrite.data.js +1 -1
- package/lib/manifest.charts.js +20 -3
- package/lib/manifest.colorpicker.js +49 -21
- package/lib/manifest.combobox.js +37 -8
- package/lib/manifest.css +15 -8
- package/lib/manifest.data.js +38 -17
- package/lib/manifest.datepicker.js +52 -15
- package/lib/manifest.defer.js +58 -5
- package/lib/manifest.dialog.css +15 -8
- package/lib/manifest.dropdowns.js +2 -2
- package/lib/manifest.integrity.json +13 -13
- package/lib/manifest.js +11 -2
- package/lib/manifest.min.css +1 -1
- package/lib/manifest.status.js +21 -4
- package/lib/manifest.sw.js +1 -1
- package/lib/manifest.tailwind.js +2 -2
- package/lib/manifest.tooltips.js +21 -7
- package/package.json +1 -1
package/lib/manifest.charts.js
CHANGED
|
@@ -13,6 +13,23 @@
|
|
|
13
13
|
if (!window.ManifestUI) {
|
|
14
14
|
window.ManifestUI = {
|
|
15
15
|
/* Loaded data sources (current locale); never force-loads others. */
|
|
16
|
+
// One cached evaluator per expression: each Alpine.evaluate would register a cleanup on <body>, never run
|
|
17
|
+
_eval(expr) {
|
|
18
|
+
const A = window.Alpine;
|
|
19
|
+
// Magics registered after an evaluator was built stay invisible to it, so a registration drops the cache
|
|
20
|
+
if (!A.magic.__manifestMagicCounted) {
|
|
21
|
+
const magic = A.magic;
|
|
22
|
+
A.magic = function () { window.__manifestMagicVersion = (window.__manifestMagicVersion || 0) + 1; return magic.apply(this, arguments); };
|
|
23
|
+
A.magic.__manifestMagicCounted = true;
|
|
24
|
+
}
|
|
25
|
+
const version = window.__manifestMagicVersion || 0;
|
|
26
|
+
if (!this._evals || this._evalsVersion !== version) { this._evals = new Map(); this._evalsVersion = version; }
|
|
27
|
+
let fn = this._evals.get(expr);
|
|
28
|
+
if (!fn) this._evals.set(expr, fn = A.evaluateLater(document.body, expr));
|
|
29
|
+
let out;
|
|
30
|
+
fn(v => { out = v; });
|
|
31
|
+
return out;
|
|
32
|
+
},
|
|
16
33
|
_loadedSourceNames() {
|
|
17
34
|
try {
|
|
18
35
|
const store = window.ManifestDataStore && window.ManifestDataStore.rawDataStore;
|
|
@@ -24,11 +41,11 @@
|
|
|
24
41
|
resolve(component, fallbacks) {
|
|
25
42
|
const merged = JSON.parse(JSON.stringify(fallbacks || {}));
|
|
26
43
|
try {
|
|
27
|
-
if (!window.Alpine || typeof Alpine.
|
|
28
|
-
try {
|
|
44
|
+
if (!window.Alpine || typeof Alpine.evaluateLater !== 'function') return merged;
|
|
45
|
+
try { this._eval('typeof $locale !== "undefined" && $locale.current'); } catch (_) { } // dep → re-resolve on locale switch
|
|
29
46
|
for (const name of this._loadedSourceNames()) {
|
|
30
47
|
let ui;
|
|
31
|
-
try { ui =
|
|
48
|
+
try { ui = this._eval(`$x['${name}'] && $x['${name}']._ui && $x['${name}']._ui['${component}']`); } catch (_) { ui = null; }
|
|
32
49
|
if (ui && typeof ui === 'object' && !Array.isArray(ui)) this._deepOverlay(merged, ui);
|
|
33
50
|
}
|
|
34
51
|
} catch (_) { }
|
|
@@ -10,6 +10,23 @@ function initializeColorpickerPlugin() {
|
|
|
10
10
|
if (!window.ManifestUI) {
|
|
11
11
|
window.ManifestUI = {
|
|
12
12
|
// Names of loaded data sources (current locale); never force-loads others.
|
|
13
|
+
// One cached evaluator per expression: each Alpine.evaluate would register a cleanup on <body>, never run
|
|
14
|
+
_eval(expr) {
|
|
15
|
+
const A = window.Alpine;
|
|
16
|
+
// Magics registered after an evaluator was built stay invisible to it, so a registration drops the cache
|
|
17
|
+
if (!A.magic.__manifestMagicCounted) {
|
|
18
|
+
const magic = A.magic;
|
|
19
|
+
A.magic = function () { window.__manifestMagicVersion = (window.__manifestMagicVersion || 0) + 1; return magic.apply(this, arguments); };
|
|
20
|
+
A.magic.__manifestMagicCounted = true;
|
|
21
|
+
}
|
|
22
|
+
const version = window.__manifestMagicVersion || 0;
|
|
23
|
+
if (!this._evals || this._evalsVersion !== version) { this._evals = new Map(); this._evalsVersion = version; }
|
|
24
|
+
let fn = this._evals.get(expr);
|
|
25
|
+
if (!fn) this._evals.set(expr, fn = A.evaluateLater(document.body, expr));
|
|
26
|
+
let out;
|
|
27
|
+
fn(v => { out = v; });
|
|
28
|
+
return out;
|
|
29
|
+
},
|
|
13
30
|
_loadedSourceNames() {
|
|
14
31
|
try {
|
|
15
32
|
const store = window.ManifestDataStore && window.ManifestDataStore.rawDataStore;
|
|
@@ -22,11 +39,11 @@ function initializeColorpickerPlugin() {
|
|
|
22
39
|
resolve(component, fallbacks) {
|
|
23
40
|
const merged = JSON.parse(JSON.stringify(fallbacks || {}));
|
|
24
41
|
try {
|
|
25
|
-
if (!window.Alpine || typeof Alpine.
|
|
26
|
-
try {
|
|
42
|
+
if (!window.Alpine || typeof Alpine.evaluateLater !== 'function') return merged;
|
|
43
|
+
try { this._eval('typeof $locale !== "undefined" && $locale.current'); } catch (_) { } // dep → re-resolve on locale switch
|
|
27
44
|
for (const name of this._loadedSourceNames()) {
|
|
28
45
|
let ui;
|
|
29
|
-
try { ui =
|
|
46
|
+
try { ui = this._eval(`$x['${name}'] && $x['${name}']._ui && $x['${name}']._ui['${component}']`); } catch (_) { ui = null; }
|
|
30
47
|
if (ui && typeof ui === 'object' && !Array.isArray(ui)) this._deepOverlay(merged, ui);
|
|
31
48
|
}
|
|
32
49
|
} catch (_) { }
|
|
@@ -563,7 +580,7 @@ function initializeColorpickerPlugin() {
|
|
|
563
580
|
try {
|
|
564
581
|
if (window.Alpine?.evaluate) {
|
|
565
582
|
const expr = isBareRef && !hasInterp ? trimmed : '`' + trimmed + '`';
|
|
566
|
-
const out = Alpine.evaluate(document.body, expr);
|
|
583
|
+
const out = window.ManifestUI?._eval ? window.ManifestUI._eval(expr) : Alpine.evaluate(document.body, expr);
|
|
567
584
|
if (out == null) return val;
|
|
568
585
|
return typeof out === 'string' ? out : String(out);
|
|
569
586
|
}
|
|
@@ -1068,6 +1085,8 @@ function initializeColorpickerPlugin() {
|
|
|
1068
1085
|
|
|
1069
1086
|
const state = {
|
|
1070
1087
|
rootEl,
|
|
1088
|
+
_effects: [],
|
|
1089
|
+
_observers: [],
|
|
1071
1090
|
pickerUid,
|
|
1072
1091
|
|
|
1073
1092
|
// Data
|
|
@@ -1615,9 +1634,9 @@ function initializeColorpickerPlugin() {
|
|
|
1615
1634
|
if (this.libraryRootValue && window.Alpine?.effect && window.Alpine?.evaluateLater) {
|
|
1616
1635
|
// Explicit expression — bypass discovery, re-render on dep change.
|
|
1617
1636
|
const evalFn = Alpine.evaluateLater(evalHost, this.libraryRootValue);
|
|
1618
|
-
Alpine.effect(() => {
|
|
1637
|
+
this._effects.push(Alpine.effect(() => {
|
|
1619
1638
|
evalFn(v => { this._libraryResolvedData = v; this._doRenderLibrary(); });
|
|
1620
|
-
});
|
|
1639
|
+
}));
|
|
1621
1640
|
} else if (window.Alpine?.effect) {
|
|
1622
1641
|
// Zero-config — scan $x.manifest.data for `colorpicker:`-flagged
|
|
1623
1642
|
// entries, collect their $x.<name> values, merge in declaration
|
|
@@ -1644,12 +1663,12 @@ function initializeColorpickerPlugin() {
|
|
|
1644
1663
|
// `colorpicker` key flagged on the data entry itself (back-compat).
|
|
1645
1664
|
const names = [];
|
|
1646
1665
|
try {
|
|
1647
|
-
const ptr = Alpine.evaluate(evalCtx, '$x && $x.manifest && $x.manifest.colorpicker');
|
|
1666
|
+
const ptr = (window.ManifestUI?._eval ? (x) => window.ManifestUI._eval(x) : (x) => Alpine.evaluate(evalCtx, x))('$x && $x.manifest && $x.manifest.colorpicker');
|
|
1648
1667
|
if (typeof ptr === 'string' && ptr) names.push(ptr);
|
|
1649
1668
|
else if (Array.isArray(ptr)) ptr.forEach(n => { if (typeof n === 'string' && n) names.push(n); });
|
|
1650
1669
|
} catch {}
|
|
1651
1670
|
let dataMap = null;
|
|
1652
|
-
try { dataMap = Alpine.evaluate(evalCtx, '$x && $x.manifest && $x.manifest.data'); } catch {}
|
|
1671
|
+
try { dataMap = (window.ManifestUI?._eval ? (x) => window.ManifestUI._eval(x) : (x) => Alpine.evaluate(evalCtx, x))('$x && $x.manifest && $x.manifest.data'); } catch {}
|
|
1653
1672
|
if (dataMap && typeof dataMap === 'object') {
|
|
1654
1673
|
for (const name of Object.keys(dataMap)) {
|
|
1655
1674
|
if (name.startsWith('$') || name.startsWith('_')) continue;
|
|
@@ -1663,7 +1682,7 @@ function initializeColorpickerPlugin() {
|
|
|
1663
1682
|
}
|
|
1664
1683
|
}
|
|
1665
1684
|
const collected = names.map(name => {
|
|
1666
|
-
try { return Alpine.evaluate(evalCtx, '$x.' + name); } catch { return null; }
|
|
1685
|
+
try { return (window.ManifestUI?._eval ? (x) => window.ManifestUI._eval(x) : (x) => Alpine.evaluate(evalCtx, x))('$x.' + name); } catch { return null; }
|
|
1667
1686
|
});
|
|
1668
1687
|
const ready = names.length === 0 || collected.every(src => {
|
|
1669
1688
|
if (!src || typeof src !== 'object') return false;
|
|
@@ -1688,9 +1707,9 @@ function initializeColorpickerPlugin() {
|
|
|
1688
1707
|
};
|
|
1689
1708
|
|
|
1690
1709
|
// Reactive deps trigger re-runs on locale switch / manifest load.
|
|
1691
|
-
Alpine.effect(() => {
|
|
1692
|
-
try { Alpine.evaluate(evalCtx, 'typeof $locale !== "undefined" && $locale.current'); } catch {}
|
|
1693
|
-
try { Alpine.evaluate(evalCtx, '$x && $x.manifest && $x.manifest._loadedFrom'); } catch {}
|
|
1710
|
+
this._effects.push(Alpine.effect(() => {
|
|
1711
|
+
try { (window.ManifestUI?._eval ? (x) => window.ManifestUI._eval(x) : (x) => Alpine.evaluate(evalCtx, x))('typeof $locale !== "undefined" && $locale.current'); } catch {}
|
|
1712
|
+
try { (window.ManifestUI?._eval ? (x) => window.ManifestUI._eval(x) : (x) => Alpine.evaluate(evalCtx, x))('$x && $x.manifest && $x.manifest._loadedFrom'); } catch {}
|
|
1694
1713
|
runDiscovery();
|
|
1695
1714
|
// Re-localize the whole picker on locale switch.
|
|
1696
1715
|
this._applyUi(this.rootEl);
|
|
@@ -1705,7 +1724,7 @@ function initializeColorpickerPlugin() {
|
|
|
1705
1724
|
}
|
|
1706
1725
|
}, 150);
|
|
1707
1726
|
}
|
|
1708
|
-
});
|
|
1727
|
+
}));
|
|
1709
1728
|
} else {
|
|
1710
1729
|
this._doRenderLibrary();
|
|
1711
1730
|
}
|
|
@@ -2022,6 +2041,7 @@ function initializeColorpickerPlugin() {
|
|
|
2022
2041
|
if (r.width > 0 && r.height > 0) { self.drawCanvas(); self.updateCanvasMarker(); }
|
|
2023
2042
|
});
|
|
2024
2043
|
ro.observe(refs.canvas);
|
|
2044
|
+
self._observers.push(ro);
|
|
2025
2045
|
}
|
|
2026
2046
|
|
|
2027
2047
|
if (refs.hueSlider) {
|
|
@@ -2453,10 +2473,17 @@ function initializeColorpickerPlugin() {
|
|
|
2453
2473
|
|
|
2454
2474
|
// Defer mount so child directives register first. setTimeout (not rAF)
|
|
2455
2475
|
// so it still fires when backgrounded.
|
|
2456
|
-
setTimeout(() => state.mount(), 0);
|
|
2476
|
+
setTimeout(() => { if (!state._destroyed) state.mount(); }, 0);
|
|
2457
2477
|
|
|
2458
2478
|
cleanup(() => {
|
|
2459
2479
|
if (el.id) delete _pickerRegistry[el.id];
|
|
2480
|
+
state._destroyed = true;
|
|
2481
|
+
state._effects.forEach((fx) => Alpine.release(fx));
|
|
2482
|
+
state._effects.length = 0;
|
|
2483
|
+
state._observers.forEach((ro) => ro.disconnect());
|
|
2484
|
+
state._observers.length = 0;
|
|
2485
|
+
clearInterval(state._libraryPollTimer);
|
|
2486
|
+
state._libraryPollTimer = null;
|
|
2460
2487
|
delete el._colorpickerState;
|
|
2461
2488
|
});
|
|
2462
2489
|
return;
|
|
@@ -2468,18 +2495,12 @@ function initializeColorpickerPlugin() {
|
|
|
2468
2495
|
// Swatches trigger OUTSIDE any picker — handle before the ancestor check.
|
|
2469
2496
|
// We assign IDs + the popover tag; x-dropdown owns popover mechanics.
|
|
2470
2497
|
if (role === 'swatch') {
|
|
2471
|
-
if (el._cpSwatchWired) return; // guard against re-firing via initTree
|
|
2472
|
-
el._cpSwatchWired = true;
|
|
2473
|
-
|
|
2474
|
-
// ---- Optional x-model binding ----
|
|
2475
|
-
// x-model is the swatch's source of truth: reactive background preview,
|
|
2476
|
-
// plus read (open) / write (close) accessors the picker uses.
|
|
2477
2498
|
const modelExpr = el.getAttribute('x-model');
|
|
2478
2499
|
if (modelExpr && window.Alpine?.evaluateLater && window.Alpine?.effect) {
|
|
2479
2500
|
try {
|
|
2480
2501
|
const readFn = Alpine.evaluateLater(el, modelExpr);
|
|
2481
2502
|
// Reactive background preview
|
|
2482
|
-
Alpine.effect(() => {
|
|
2503
|
+
const modelEffect = Alpine.effect(() => {
|
|
2483
2504
|
readFn(v => {
|
|
2484
2505
|
if (typeof v === 'string' && v.length) {
|
|
2485
2506
|
el.style.setProperty('--color-picker-swatch', v);
|
|
@@ -2487,6 +2508,7 @@ function initializeColorpickerPlugin() {
|
|
|
2487
2508
|
}
|
|
2488
2509
|
});
|
|
2489
2510
|
});
|
|
2511
|
+
cleanup(() => Alpine.release(modelEffect));
|
|
2490
2512
|
el._cpModelGetter = (cb) => readFn(cb);
|
|
2491
2513
|
// Writer: `<modelExpr> = <JSON value>` (color/gradient strings are JSON-safe).
|
|
2492
2514
|
el._cpModelSetter = (v) => {
|
|
@@ -2495,6 +2517,12 @@ function initializeColorpickerPlugin() {
|
|
|
2495
2517
|
} catch {}
|
|
2496
2518
|
}
|
|
2497
2519
|
|
|
2520
|
+
if (el._cpSwatchWired) return; // guard against re-firing via initTree
|
|
2521
|
+
el._cpSwatchWired = true;
|
|
2522
|
+
|
|
2523
|
+
// ---- Optional x-model binding ----
|
|
2524
|
+
// x-model is the swatch's source of truth: reactive background preview,
|
|
2525
|
+
// plus read (open) / write (close) accessors the picker uses.
|
|
2498
2526
|
// ---- Initial color via `value` attribute ----
|
|
2499
2527
|
// Mirrors native <input type=color>: seeds the picker on first open and
|
|
2500
2528
|
// the swatch CSS var so border-color paints before interaction.
|
package/lib/manifest.combobox.js
CHANGED
|
@@ -12,6 +12,23 @@
|
|
|
12
12
|
* ------------------------------------------------------------------ */
|
|
13
13
|
if (!window.ManifestUI) {
|
|
14
14
|
window.ManifestUI = {
|
|
15
|
+
// One cached evaluator per expression: each Alpine.evaluate would register a cleanup on <body>, never run
|
|
16
|
+
_eval(expr) {
|
|
17
|
+
const A = window.Alpine;
|
|
18
|
+
// Magics registered after an evaluator was built stay invisible to it, so a registration drops the cache
|
|
19
|
+
if (!A.magic.__manifestMagicCounted) {
|
|
20
|
+
const magic = A.magic;
|
|
21
|
+
A.magic = function () { window.__manifestMagicVersion = (window.__manifestMagicVersion || 0) + 1; return magic.apply(this, arguments); };
|
|
22
|
+
A.magic.__manifestMagicCounted = true;
|
|
23
|
+
}
|
|
24
|
+
const version = window.__manifestMagicVersion || 0;
|
|
25
|
+
if (!this._evals || this._evalsVersion !== version) { this._evals = new Map(); this._evalsVersion = version; }
|
|
26
|
+
let fn = this._evals.get(expr);
|
|
27
|
+
if (!fn) this._evals.set(expr, fn = A.evaluateLater(document.body, expr));
|
|
28
|
+
let out;
|
|
29
|
+
fn(v => { out = v; });
|
|
30
|
+
return out;
|
|
31
|
+
},
|
|
15
32
|
_loadedSourceNames() {
|
|
16
33
|
try {
|
|
17
34
|
const store = window.ManifestDataStore && window.ManifestDataStore.rawDataStore;
|
|
@@ -22,11 +39,11 @@ if (!window.ManifestUI) {
|
|
|
22
39
|
resolve(component, fallbacks) {
|
|
23
40
|
const merged = JSON.parse(JSON.stringify(fallbacks || {}));
|
|
24
41
|
try {
|
|
25
|
-
if (!window.Alpine || typeof Alpine.
|
|
26
|
-
try {
|
|
42
|
+
if (!window.Alpine || typeof Alpine.evaluateLater !== 'function') return merged;
|
|
43
|
+
try { this._eval('typeof $locale !== "undefined" && $locale.current'); } catch (_) { }
|
|
27
44
|
for (const name of this._loadedSourceNames()) {
|
|
28
45
|
let ui;
|
|
29
|
-
try { ui =
|
|
46
|
+
try { ui = this._eval(`$x['${name}'] && $x['${name}']._ui && $x['${name}']._ui['${component}']`); } catch (_) { ui = null; }
|
|
30
47
|
if (ui && typeof ui === 'object' && !Array.isArray(ui)) this._deepOverlay(merged, ui);
|
|
31
48
|
}
|
|
32
49
|
} catch (_) { }
|
|
@@ -165,7 +182,9 @@ function initializeComboboxPlugin() {
|
|
|
165
182
|
Alpine.directive('combobox', (el, { modifiers, expression }, { cleanup }) => {
|
|
166
183
|
captureModel(el); // fallback for any path that bypasses the above
|
|
167
184
|
// Build after the current tick so sibling sources (datalist/menu) exist.
|
|
168
|
-
|
|
185
|
+
let removed = false;
|
|
186
|
+
cleanup(() => { removed = true; });
|
|
187
|
+
setTimeout(() => { if (!removed) build(el, modifiers, expression || '', cleanup); }, 0);
|
|
169
188
|
});
|
|
170
189
|
|
|
171
190
|
// Resolve the menu's owning top-layer context fresh, every time — never cache it.
|
|
@@ -201,6 +220,8 @@ function initializeComboboxPlugin() {
|
|
|
201
220
|
// it into wherever the owner lives now. Harmless no-op otherwise.
|
|
202
221
|
const m = el.__mnfstComboboxMenu;
|
|
203
222
|
if (m) reattach(el, m);
|
|
223
|
+
// A re-initialized field: its cleanup released these
|
|
224
|
+
el.__cbBindEffects?.(cleanup);
|
|
204
225
|
return;
|
|
205
226
|
}
|
|
206
227
|
el.__mnfstCombobox = true;
|
|
@@ -941,6 +962,8 @@ function initializeComboboxPlugin() {
|
|
|
941
962
|
disabledObserver.observe(el, { attributes: true, attributeFilter: ['disabled'] });
|
|
942
963
|
if (cleanup) cleanup(() => disabledObserver.disconnect());
|
|
943
964
|
|
|
965
|
+
const effectFactories = [];
|
|
966
|
+
|
|
944
967
|
// ----- Reactive model (x-model) -----
|
|
945
968
|
// Render chips from the bound value on init and external change; write back on
|
|
946
969
|
// add/remove. Read inside an Alpine effect so $x / nested state stay reactive.
|
|
@@ -951,7 +974,7 @@ function initializeComboboxPlugin() {
|
|
|
951
974
|
: (modelArrayShape === false ? vals.join(',') : vals.slice());
|
|
952
975
|
try { Alpine.evaluate(el, `${modelExpr} = ${JSON.stringify(out)}`); } catch (_) { }
|
|
953
976
|
};
|
|
954
|
-
Alpine.effect(() => {
|
|
977
|
+
effectFactories.push(() => Alpine.effect(() => {
|
|
955
978
|
read(raw => {
|
|
956
979
|
if (modelArrayShape === null && raw != null && raw !== '') modelArrayShape = Array.isArray(raw);
|
|
957
980
|
const incoming = modelToValues(raw);
|
|
@@ -960,20 +983,26 @@ function initializeComboboxPlugin() {
|
|
|
960
983
|
if (!multiple && selected.length > 1) selected = selected.slice(-1);
|
|
961
984
|
render();
|
|
962
985
|
});
|
|
963
|
-
});
|
|
986
|
+
}));
|
|
964
987
|
}
|
|
965
988
|
|
|
966
989
|
// ----- Reactive locked list (config-object form, so `locked` can gate on state) -----
|
|
967
990
|
if (expr.startsWith('{')) {
|
|
968
|
-
Alpine.effect(() => {
|
|
991
|
+
effectFactories.push(() => Alpine.effect(() => {
|
|
969
992
|
let c; try { c = Alpine.evaluate(el, expr); } catch (_) { return; }
|
|
970
993
|
const next = computeLocked(c && typeof c === 'object' && !Array.isArray(c) ? c : null);
|
|
971
994
|
if (next.size === lockedSet.size && [...next].every(v => lockedSet.has(v))) return;
|
|
972
995
|
lockedSet = next;
|
|
973
996
|
render();
|
|
974
|
-
});
|
|
997
|
+
}));
|
|
975
998
|
}
|
|
976
999
|
|
|
1000
|
+
el.__cbBindEffects = (onCleanup) => {
|
|
1001
|
+
const effects = effectFactories.map((make) => make());
|
|
1002
|
+
if (onCleanup) onCleanup(() => effects.forEach((fx) => Alpine.release(fx)));
|
|
1003
|
+
};
|
|
1004
|
+
el.__cbBindEffects(cleanup);
|
|
1005
|
+
|
|
977
1006
|
// ----- Dynamic options: re-read when x-for / $x fills the source after build,
|
|
978
1007
|
// keeping the menu, chip labels, and data-locked flags current. -----
|
|
979
1008
|
if (src) {
|
package/lib/manifest.css
CHANGED
|
@@ -2580,14 +2580,21 @@
|
|
|
2580
2580
|
background-color: rgba(0, 0, 0, 0.35)
|
|
2581
2581
|
}
|
|
2582
2582
|
|
|
2583
|
-
/* Hide dropdowns when dialogs are open */
|
|
2583
|
+
/* Hide dropdowns when dialogs are open: <html> sets flags, menus read them via style queries */
|
|
2584
2584
|
html:has(dialog:popover-open) {
|
|
2585
|
+
--dialog-open: 1;
|
|
2586
|
+
}
|
|
2585
2587
|
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2588
|
+
html:has(dialog:popover-open ~ dialog:popover-open) {
|
|
2589
|
+
--dialog-stacked: 1;
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
/* Hide dropdowns outside of any dialog. A generated popover (a datepicker
|
|
2593
|
+
calendar, a colorpicker panel) is appended to <body>, so DOM position alone
|
|
2594
|
+
can't tell page chrome from a menu the dialog itself opened —
|
|
2595
|
+
data-popover-nested marks the latter, which CSS has no way to work out. */
|
|
2596
|
+
@container style(--dialog-open: 1) {
|
|
2597
|
+
menu[popover]:not(dialog *):not([data-popover-nested]) {
|
|
2591
2598
|
opacity: 0;
|
|
2592
2599
|
scale: .9;
|
|
2593
2600
|
pointer-events: none;
|
|
@@ -2600,8 +2607,8 @@
|
|
|
2600
2607
|
}
|
|
2601
2608
|
|
|
2602
2609
|
/* When multiple dialogs are open, hide dropdowns in all but closest dialog */
|
|
2603
|
-
|
|
2604
|
-
|
|
2610
|
+
@container style(--dialog-stacked: 1) {
|
|
2611
|
+
dialog:popover-open:not(:last-of-type) menu[popover] {
|
|
2605
2612
|
opacity: 0;
|
|
2606
2613
|
scale: .9;
|
|
2607
2614
|
pointer-events: none;
|
package/lib/manifest.data.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
(function () {
|
|
4
4
|
|
|
5
|
-
const MANIFEST_BUILD_VERSION = '0.5.
|
|
5
|
+
const MANIFEST_BUILD_VERSION = '0.5.263';
|
|
6
6
|
|
|
7
7
|
/* Manifest Data Sources - Configuration */
|
|
8
8
|
|
|
@@ -784,7 +784,8 @@ function createReactiveReferences(data, dataSourceName = null) {
|
|
|
784
784
|
dataSourceName,
|
|
785
785
|
data.$id,
|
|
786
786
|
bucketName,
|
|
787
|
-
columnName
|
|
787
|
+
columnName,
|
|
788
|
+
{ owner: newObj }
|
|
788
789
|
);
|
|
789
790
|
|
|
790
791
|
// Assign computed array to entry
|
|
@@ -6011,13 +6012,9 @@ const routeProxyCache = new Map();
|
|
|
6011
6012
|
// Clear route proxy cache for a specific data source (called when store updates)
|
|
6012
6013
|
function clearRouteProxyCacheForDataSource(dataSourceName) {
|
|
6013
6014
|
if (!dataSourceName) return;
|
|
6014
|
-
const
|
|
6015
|
-
|
|
6016
|
-
if (key.startsWith(`${dataSourceName}:`)) {
|
|
6017
|
-
keysToDelete.push(key);
|
|
6018
|
-
}
|
|
6015
|
+
for (const [key, entry] of routeProxyCache.entries()) {
|
|
6016
|
+
if (key.startsWith(`${dataSourceName}:`)) entry.stale = true;
|
|
6019
6017
|
}
|
|
6020
|
-
keysToDelete.forEach(key => routeProxyCache.delete(key));
|
|
6021
6018
|
}
|
|
6022
6019
|
|
|
6023
6020
|
// Create proxy for route-specific lookups
|
|
@@ -6025,8 +6022,13 @@ function createRouteProxy(dataSourceData, pathKey, dataSourceName) {
|
|
|
6025
6022
|
// Use cache if dataSourceName is provided to avoid recreating proxies
|
|
6026
6023
|
if (dataSourceName && pathKey) {
|
|
6027
6024
|
const cacheKey = `${dataSourceName}:${pathKey}`;
|
|
6028
|
-
|
|
6029
|
-
|
|
6025
|
+
const cached = routeProxyCache.get(cacheKey);
|
|
6026
|
+
if (cached) {
|
|
6027
|
+
if (cached.stale) {
|
|
6028
|
+
cached.stale = false;
|
|
6029
|
+
cached.refresh(dataSourceData);
|
|
6030
|
+
}
|
|
6031
|
+
return cached.proxy;
|
|
6030
6032
|
}
|
|
6031
6033
|
}
|
|
6032
6034
|
|
|
@@ -6271,7 +6273,15 @@ function createRouteProxy(dataSourceData, pathKey, dataSourceName) {
|
|
|
6271
6273
|
// Cache the proxy if dataSourceName and pathKey are provided
|
|
6272
6274
|
if (dataSourceName && pathKey) {
|
|
6273
6275
|
const cacheKey = `${dataSourceName}:${pathKey}`;
|
|
6274
|
-
routeProxyCache.set(cacheKey,
|
|
6276
|
+
routeProxyCache.set(cacheKey, {
|
|
6277
|
+
proxy,
|
|
6278
|
+
stale: false,
|
|
6279
|
+
refresh(data) {
|
|
6280
|
+
dataSourceData = data;
|
|
6281
|
+
lastUpdateUrl = null;
|
|
6282
|
+
updateReactiveTarget();
|
|
6283
|
+
}
|
|
6284
|
+
});
|
|
6275
6285
|
}
|
|
6276
6286
|
|
|
6277
6287
|
return proxy;
|
|
@@ -6299,7 +6309,10 @@ const reactiveFileManagers = new Map();
|
|
|
6299
6309
|
|
|
6300
6310
|
// Create a computed files array for an entry that filters the bucket array by fileIds
|
|
6301
6311
|
// This is the new single-source-of-truth approach
|
|
6302
|
-
|
|
6312
|
+
// owner: the row object holding this array; the effect releases itself once the row leaves its table
|
|
6313
|
+
function createComputedFilesArray(tableName, entryId, bucketName, columnName = 'fileIds', options = {}) {
|
|
6314
|
+
const owner = options.owner || null;
|
|
6315
|
+
|
|
6303
6316
|
if (typeof Alpine === 'undefined') {
|
|
6304
6317
|
// Return empty array proxy if Alpine not available
|
|
6305
6318
|
return new Proxy([], {
|
|
@@ -6405,8 +6418,9 @@ function createComputedFilesArray(tableName, entryId, bucketName, columnName = '
|
|
|
6405
6418
|
};
|
|
6406
6419
|
|
|
6407
6420
|
// Set up Alpine effect to watch both bucket array and entry's fileIds
|
|
6421
|
+
let filesEffect = null;
|
|
6408
6422
|
if (typeof Alpine !== 'undefined' && Alpine.effect) {
|
|
6409
|
-
Alpine.effect(() => {
|
|
6423
|
+
filesEffect = Alpine.effect(() => {
|
|
6410
6424
|
// Access store to track changes
|
|
6411
6425
|
const store = Alpine.store('data');
|
|
6412
6426
|
if (!store) {
|
|
@@ -6414,6 +6428,14 @@ function createComputedFilesArray(tableName, entryId, bucketName, columnName = '
|
|
|
6414
6428
|
return;
|
|
6415
6429
|
}
|
|
6416
6430
|
|
|
6431
|
+
if (owner) {
|
|
6432
|
+
const rows = store[tableName];
|
|
6433
|
+
if (Array.isArray(rows) && !rows.some(row => (Alpine.raw ? Alpine.raw(row) : row) === owner)) {
|
|
6434
|
+
queueMicrotask(() => { if (filesEffect) Alpine.release(filesEffect); });
|
|
6435
|
+
return;
|
|
6436
|
+
}
|
|
6437
|
+
}
|
|
6438
|
+
|
|
6417
6439
|
// Track bucket array changes - access the array itself and iterate to track all elements
|
|
6418
6440
|
const bucketFiles = store[bucketName];
|
|
6419
6441
|
if (bucketFiles && Array.isArray(bucketFiles)) {
|
|
@@ -6460,7 +6482,7 @@ function createComputedFilesArray(tableName, entryId, bucketName, columnName = '
|
|
|
6460
6482
|
recomputeFiles();
|
|
6461
6483
|
|
|
6462
6484
|
// Create proxy that adds loading/error properties
|
|
6463
|
-
|
|
6485
|
+
const computedProxy = new Proxy(computedFiles, {
|
|
6464
6486
|
get(target, key) {
|
|
6465
6487
|
if (key === '$loading') return loadingState.value;
|
|
6466
6488
|
if (key === '$error') return errorState.value;
|
|
@@ -6475,6 +6497,7 @@ function createComputedFilesArray(tableName, entryId, bucketName, columnName = '
|
|
|
6475
6497
|
return key in target || key === '$loading' || key === '$error';
|
|
6476
6498
|
}
|
|
6477
6499
|
});
|
|
6500
|
+
return computedProxy;
|
|
6478
6501
|
}
|
|
6479
6502
|
|
|
6480
6503
|
// Create reactive file array that watches a function/expression for entryId changes
|
|
@@ -6908,9 +6931,7 @@ function createReactiveFileManager(tableName, entryId, bucketName, columnName) {
|
|
|
6908
6931
|
});
|
|
6909
6932
|
|
|
6910
6933
|
unsubscribeCallbacks.push(() => {
|
|
6911
|
-
if (unwatch
|
|
6912
|
-
unwatch();
|
|
6913
|
-
}
|
|
6934
|
+
if (unwatch) Alpine.release(unwatch);
|
|
6914
6935
|
});
|
|
6915
6936
|
};
|
|
6916
6937
|
|