@jirawatpyk/aura-react 5.72.0 → 5.73.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/README.md +6 -0
- package/dist/aura.bundle.js +88 -37
- package/dist/cjs/index.cjs +88 -37
- package/dist/esm/ActionBar.js +5 -16
- package/dist/esm/PageHeaderClient.js +16 -23
- package/dist/esm/internal.js +70 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -186,6 +186,12 @@ DataTable with sort and page in the URL (4.17): `onStateChange={({ sort, page })
|
|
|
186
186
|
- **Time zone**: `timeZone` on AuraProvider, DatePicker, DateRangePicker and Calendar decides "today" (the marker, `min`/`max="today"`, the first month shown); or pass `today` as an ISO date. `todayIn('Asia/Bangkok')` is exported from the root and `/server`.
|
|
187
187
|
- **Toasts** queue past three instead of dropping: six in a row all show, in order, three at a time.
|
|
188
188
|
|
|
189
|
+
## 5.73 — Chamber-OS addendum 93 follow-up (#192)
|
|
190
|
+
|
|
191
|
+
- **Hidden bars, every way a tab panel hides them:** the edge ActionBar and PageHeader's `actionsBarBelow` bar now share one rule. The newest bar that is pinned and on screen sets the page's clearance (`--aura-actionbar-height`, `--aura-page-actions-height`). A bar with no box (`display: none`), `visibility: hidden`, or inside `content-visibility: hidden` (`hidden="until-found"`) is skipped. A visibility switch resizes nothing, so the bars are re-read after any click, key press, focus move, transition, find-in-page reveal (`beforematch`) or history change; a switch made by a timer or a resolved request is caught at the next of those.
|
|
192
|
+
- **When no bar is on screen:** a pinned bar hidden only by `visibility` (a gate that may lift with no event) keeps its room — too much space is cosmetic, too little hides content; with every pinned bar boxless (`display: none` tab panels) the variable is `0px`, so the page keeps no space for a strip that isn't there (5.72 removed it, and the CSS then reserved its 60px / 7rem fallback). With no bar pinned (a wide or short screen) it is removed, as before.
|
|
193
|
+
- **PageHeader in tab panels:** one PageHeader with `actionsBarBelow` per tab panel now works like the ActionBars: the shown one's bar counts, where before the newest one — shown or not — set the height. The development warning now fires only when two bars are on screen at once.
|
|
194
|
+
|
|
189
195
|
## 5.72 — Chamber-OS addendum 93 (#192)
|
|
190
196
|
|
|
191
197
|
- **An edge ActionBar in a hidden tab no longer zeroes the page's clearance:** a bar with `look="edge"` / `edgeBelow` inside a `display: none` parent (an inactive tab panel) still computes `position: fixed` but has no box; it is now skipped, so `--aura-actionbar-height` (and with it the page's end padding and `scroll-padding-bottom`) is the visible bar's height. Switching tabs moves it to the bar now shown; with none shown it is removed. Mounting one bar for the active tab is still the simplest shape.
|
package/dist/aura.bundle.js
CHANGED
|
@@ -418,6 +418,75 @@ window.Aura = (() => {
|
|
|
418
418
|
}
|
|
419
419
|
return false;
|
|
420
420
|
}
|
|
421
|
+
function onScreen(el) {
|
|
422
|
+
if (el.offsetHeight <= 0 || el.getClientRects().length === 0) return false;
|
|
423
|
+
const check = el.checkVisibility;
|
|
424
|
+
if (typeof check === "function") return check.call(el, { visibilityProperty: true });
|
|
425
|
+
const v = getComputedStyle(el).visibility;
|
|
426
|
+
return v !== "hidden" && v !== "collapse";
|
|
427
|
+
}
|
|
428
|
+
function barStack(name, onMany) {
|
|
429
|
+
const els = [];
|
|
430
|
+
let frame = 0;
|
|
431
|
+
const docEvents = ["click", "keydown", "focusin", "transitionend", "beforematch"];
|
|
432
|
+
const winEvents = ["hashchange", "popstate"];
|
|
433
|
+
function write() {
|
|
434
|
+
if (frame) cancelAnimationFrame(frame);
|
|
435
|
+
frame = 0;
|
|
436
|
+
const root = document.documentElement;
|
|
437
|
+
let shown = null, boxed = null, pinned2 = false, many = 0;
|
|
438
|
+
for (let i = els.length - 1; i >= 0; i--) {
|
|
439
|
+
const el = els[i];
|
|
440
|
+
if (getComputedStyle(el).position !== "fixed") continue;
|
|
441
|
+
pinned2 = true;
|
|
442
|
+
if (onScreen(el)) {
|
|
443
|
+
many++;
|
|
444
|
+
if (!shown) shown = el;
|
|
445
|
+
} else if (!boxed && el.offsetHeight > 0) boxed = el;
|
|
446
|
+
}
|
|
447
|
+
if (many > 1 && onMany) onMany();
|
|
448
|
+
const use = shown || boxed;
|
|
449
|
+
if (use) root.style.setProperty(name, use.offsetHeight + "px");
|
|
450
|
+
else if (pinned2) root.style.setProperty(name, "0px");
|
|
451
|
+
else root.style.removeProperty(name);
|
|
452
|
+
}
|
|
453
|
+
function later() {
|
|
454
|
+
if (!frame) frame = requestAnimationFrame(write);
|
|
455
|
+
}
|
|
456
|
+
function now() {
|
|
457
|
+
write();
|
|
458
|
+
later();
|
|
459
|
+
}
|
|
460
|
+
function listen(on) {
|
|
461
|
+
docEvents.forEach(function(t) {
|
|
462
|
+
const f = t === "focusin" ? now : later;
|
|
463
|
+
if (on) document.addEventListener(t, f, true);
|
|
464
|
+
else document.removeEventListener(t, f, true);
|
|
465
|
+
});
|
|
466
|
+
winEvents.forEach(function(t) {
|
|
467
|
+
if (on) window.addEventListener(t, later);
|
|
468
|
+
else window.removeEventListener(t, later);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
return {
|
|
472
|
+
add: function(el) {
|
|
473
|
+
els.push(el);
|
|
474
|
+
if (els.length === 1) listen(true);
|
|
475
|
+
write();
|
|
476
|
+
},
|
|
477
|
+
remove: function(el) {
|
|
478
|
+
const i = els.indexOf(el);
|
|
479
|
+
if (i >= 0) els.splice(i, 1);
|
|
480
|
+
if (!els.length) {
|
|
481
|
+
listen(false);
|
|
482
|
+
if (frame) cancelAnimationFrame(frame);
|
|
483
|
+
frame = 0;
|
|
484
|
+
}
|
|
485
|
+
write();
|
|
486
|
+
},
|
|
487
|
+
write
|
|
488
|
+
};
|
|
489
|
+
}
|
|
421
490
|
|
|
422
491
|
// src/display.tsx
|
|
423
492
|
var React4 = __toESM(require_react(), 1);
|
|
@@ -8158,8 +8227,12 @@ window.Aura = (() => {
|
|
|
8158
8227
|
});
|
|
8159
8228
|
|
|
8160
8229
|
// src/PageHeaderClient.tsx
|
|
8161
|
-
var
|
|
8162
|
-
|
|
8230
|
+
var bars = barStack("--aura-page-actions-height", function() {
|
|
8231
|
+
devWarnOnce(
|
|
8232
|
+
"pageheader-bar-twice",
|
|
8233
|
+
"PageHeader actionsBarBelow: two bars are on screen at once and overlap at the bottom of the screen. Give it to one PageHeader per page (one per tab panel is fine: only the shown one counts)."
|
|
8234
|
+
);
|
|
8235
|
+
});
|
|
8163
8236
|
var PageHeader3 = React45.forwardRef(function PageHeader4(props, ref) {
|
|
8164
8237
|
const own = React45.useRef(null);
|
|
8165
8238
|
const merged = useMergedRef(ref, own);
|
|
@@ -8173,35 +8246,24 @@ window.Aura = (() => {
|
|
|
8173
8246
|
split ? ":scope > .aura-page-header__actions > .aura-page-header__bar" : ":scope > .aura-page-header__actions"
|
|
8174
8247
|
);
|
|
8175
8248
|
if (!el) return;
|
|
8176
|
-
const root = document.documentElement;
|
|
8177
8249
|
let checked = false;
|
|
8178
8250
|
function sync() {
|
|
8179
|
-
|
|
8180
|
-
if (getComputedStyle(el).position === "fixed")
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
"PageHeader actionsBarBelow: an ancestor has a transform, filter, will-change or paint containment, so the fixed bar is placed against it instead of the screen. Remove it from the page header's ancestors."
|
|
8186
|
-
);
|
|
8187
|
-
} else root.style.removeProperty(NAME);
|
|
8251
|
+
bars.write();
|
|
8252
|
+
if (!checked && getComputedStyle(el).position === "fixed" && (checked = true, fixedTrapped(el)))
|
|
8253
|
+
devWarnOnce(
|
|
8254
|
+
"pageheader-bar-trapped",
|
|
8255
|
+
"PageHeader actionsBarBelow: an ancestor has a transform, filter, will-change or paint containment, so the fixed bar is placed against it instead of the screen. Remove it from the page header's ancestors."
|
|
8256
|
+
);
|
|
8188
8257
|
}
|
|
8189
|
-
|
|
8190
|
-
devWarnOnce(
|
|
8191
|
-
"pageheader-bar-twice",
|
|
8192
|
-
"PageHeader actionsBarBelow: two bars on one page overlap at the bottom of the screen. Give it to one PageHeader per page."
|
|
8193
|
-
);
|
|
8194
|
-
bars.push(sync);
|
|
8258
|
+
bars.add(el);
|
|
8195
8259
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
8196
|
-
if (ro) ro.observe(el);
|
|
8260
|
+
if (ro) ro.observe(el, { box: "border-box" });
|
|
8197
8261
|
window.addEventListener("resize", sync);
|
|
8198
8262
|
sync();
|
|
8199
8263
|
return function() {
|
|
8200
8264
|
if (ro) ro.disconnect();
|
|
8201
8265
|
window.removeEventListener("resize", sync);
|
|
8202
|
-
bars.
|
|
8203
|
-
if (bars.length) bars[bars.length - 1]();
|
|
8204
|
-
else root.style.removeProperty(NAME);
|
|
8266
|
+
bars.remove(el);
|
|
8205
8267
|
};
|
|
8206
8268
|
},
|
|
8207
8269
|
[bar, hasActions, split]
|
|
@@ -8722,17 +8784,7 @@ window.Aura = (() => {
|
|
|
8722
8784
|
|
|
8723
8785
|
// src/ActionBar.tsx
|
|
8724
8786
|
var React50 = __toESM(require_react(), 1);
|
|
8725
|
-
var
|
|
8726
|
-
var edges = [];
|
|
8727
|
-
function writeHeight() {
|
|
8728
|
-
const root = document.documentElement;
|
|
8729
|
-
for (let i = edges.length - 1; i >= 0; i--)
|
|
8730
|
-
if (edges[i].getClientRects().length > 0 && edges[i].offsetHeight > 0 && getComputedStyle(edges[i]).position === "fixed") {
|
|
8731
|
-
root.style.setProperty(HEIGHT, edges[i].offsetHeight + "px");
|
|
8732
|
-
return;
|
|
8733
|
-
}
|
|
8734
|
-
root.style.removeProperty(HEIGHT);
|
|
8735
|
-
}
|
|
8787
|
+
var edges = barStack("--aura-actionbar-height");
|
|
8736
8788
|
var ActionBar = React50.forwardRef(function ActionBar2(props, ref) {
|
|
8737
8789
|
const t = useStrings();
|
|
8738
8790
|
const bulk = props.selected != null;
|
|
@@ -8756,14 +8808,14 @@ window.Aura = (() => {
|
|
|
8756
8808
|
if (!edge || !el) return;
|
|
8757
8809
|
let checked = false;
|
|
8758
8810
|
function sync() {
|
|
8759
|
-
|
|
8811
|
+
edges.write();
|
|
8760
8812
|
if (!checked && getComputedStyle(el).position === "fixed" && (checked = true, fixedTrapped(el)))
|
|
8761
8813
|
devWarnOnce(
|
|
8762
8814
|
"actionbar-edge-trapped",
|
|
8763
8815
|
`ActionBar look="edge": an ancestor has a transform, filter, will-change or paint containment, so the fixed strip is placed against it instead of the screen. Remove it from the bar's ancestors.`
|
|
8764
8816
|
);
|
|
8765
8817
|
}
|
|
8766
|
-
edges.
|
|
8818
|
+
edges.add(el);
|
|
8767
8819
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
8768
8820
|
if (ro) ro.observe(el, { box: "border-box" });
|
|
8769
8821
|
window.addEventListener("resize", sync);
|
|
@@ -8771,8 +8823,7 @@ window.Aura = (() => {
|
|
|
8771
8823
|
return function() {
|
|
8772
8824
|
if (ro) ro.disconnect();
|
|
8773
8825
|
window.removeEventListener("resize", sync);
|
|
8774
|
-
edges.
|
|
8775
|
-
writeHeight();
|
|
8826
|
+
edges.remove(el);
|
|
8776
8827
|
};
|
|
8777
8828
|
},
|
|
8778
8829
|
[edge, idle]
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -400,6 +400,75 @@ function fixedTrapped(el) {
|
|
|
400
400
|
}
|
|
401
401
|
return false;
|
|
402
402
|
}
|
|
403
|
+
function onScreen(el) {
|
|
404
|
+
if (el.offsetHeight <= 0 || el.getClientRects().length === 0) return false;
|
|
405
|
+
const check = el.checkVisibility;
|
|
406
|
+
if (typeof check === "function") return check.call(el, { visibilityProperty: true });
|
|
407
|
+
const v = getComputedStyle(el).visibility;
|
|
408
|
+
return v !== "hidden" && v !== "collapse";
|
|
409
|
+
}
|
|
410
|
+
function barStack(name, onMany) {
|
|
411
|
+
const els = [];
|
|
412
|
+
let frame = 0;
|
|
413
|
+
const docEvents = ["click", "keydown", "focusin", "transitionend", "beforematch"];
|
|
414
|
+
const winEvents = ["hashchange", "popstate"];
|
|
415
|
+
function write() {
|
|
416
|
+
if (frame) cancelAnimationFrame(frame);
|
|
417
|
+
frame = 0;
|
|
418
|
+
const root = document.documentElement;
|
|
419
|
+
let shown = null, boxed = null, pinned2 = false, many = 0;
|
|
420
|
+
for (let i = els.length - 1; i >= 0; i--) {
|
|
421
|
+
const el = els[i];
|
|
422
|
+
if (getComputedStyle(el).position !== "fixed") continue;
|
|
423
|
+
pinned2 = true;
|
|
424
|
+
if (onScreen(el)) {
|
|
425
|
+
many++;
|
|
426
|
+
if (!shown) shown = el;
|
|
427
|
+
} else if (!boxed && el.offsetHeight > 0) boxed = el;
|
|
428
|
+
}
|
|
429
|
+
if (many > 1 && onMany) onMany();
|
|
430
|
+
const use = shown || boxed;
|
|
431
|
+
if (use) root.style.setProperty(name, use.offsetHeight + "px");
|
|
432
|
+
else if (pinned2) root.style.setProperty(name, "0px");
|
|
433
|
+
else root.style.removeProperty(name);
|
|
434
|
+
}
|
|
435
|
+
function later() {
|
|
436
|
+
if (!frame) frame = requestAnimationFrame(write);
|
|
437
|
+
}
|
|
438
|
+
function now() {
|
|
439
|
+
write();
|
|
440
|
+
later();
|
|
441
|
+
}
|
|
442
|
+
function listen(on) {
|
|
443
|
+
docEvents.forEach(function(t) {
|
|
444
|
+
const f = t === "focusin" ? now : later;
|
|
445
|
+
if (on) document.addEventListener(t, f, true);
|
|
446
|
+
else document.removeEventListener(t, f, true);
|
|
447
|
+
});
|
|
448
|
+
winEvents.forEach(function(t) {
|
|
449
|
+
if (on) window.addEventListener(t, later);
|
|
450
|
+
else window.removeEventListener(t, later);
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
return {
|
|
454
|
+
add: function(el) {
|
|
455
|
+
els.push(el);
|
|
456
|
+
if (els.length === 1) listen(true);
|
|
457
|
+
write();
|
|
458
|
+
},
|
|
459
|
+
remove: function(el) {
|
|
460
|
+
const i = els.indexOf(el);
|
|
461
|
+
if (i >= 0) els.splice(i, 1);
|
|
462
|
+
if (!els.length) {
|
|
463
|
+
listen(false);
|
|
464
|
+
if (frame) cancelAnimationFrame(frame);
|
|
465
|
+
frame = 0;
|
|
466
|
+
}
|
|
467
|
+
write();
|
|
468
|
+
},
|
|
469
|
+
write
|
|
470
|
+
};
|
|
471
|
+
}
|
|
403
472
|
|
|
404
473
|
// src/display.tsx
|
|
405
474
|
var React4 = __toESM(require("react"), 1);
|
|
@@ -8140,8 +8209,12 @@ var PageHeader = React44.forwardRef(function PageHeader2(props, ref) {
|
|
|
8140
8209
|
});
|
|
8141
8210
|
|
|
8142
8211
|
// src/PageHeaderClient.tsx
|
|
8143
|
-
var
|
|
8144
|
-
|
|
8212
|
+
var bars = barStack("--aura-page-actions-height", function() {
|
|
8213
|
+
devWarnOnce(
|
|
8214
|
+
"pageheader-bar-twice",
|
|
8215
|
+
"PageHeader actionsBarBelow: two bars are on screen at once and overlap at the bottom of the screen. Give it to one PageHeader per page (one per tab panel is fine: only the shown one counts)."
|
|
8216
|
+
);
|
|
8217
|
+
});
|
|
8145
8218
|
var PageHeader3 = React45.forwardRef(function PageHeader4(props, ref) {
|
|
8146
8219
|
const own = React45.useRef(null);
|
|
8147
8220
|
const merged = useMergedRef(ref, own);
|
|
@@ -8155,35 +8228,24 @@ var PageHeader3 = React45.forwardRef(function PageHeader4(props, ref) {
|
|
|
8155
8228
|
split ? ":scope > .aura-page-header__actions > .aura-page-header__bar" : ":scope > .aura-page-header__actions"
|
|
8156
8229
|
);
|
|
8157
8230
|
if (!el) return;
|
|
8158
|
-
const root = document.documentElement;
|
|
8159
8231
|
let checked = false;
|
|
8160
8232
|
function sync() {
|
|
8161
|
-
|
|
8162
|
-
if (getComputedStyle(el).position === "fixed")
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
"PageHeader actionsBarBelow: an ancestor has a transform, filter, will-change or paint containment, so the fixed bar is placed against it instead of the screen. Remove it from the page header's ancestors."
|
|
8168
|
-
);
|
|
8169
|
-
} else root.style.removeProperty(NAME);
|
|
8233
|
+
bars.write();
|
|
8234
|
+
if (!checked && getComputedStyle(el).position === "fixed" && (checked = true, fixedTrapped(el)))
|
|
8235
|
+
devWarnOnce(
|
|
8236
|
+
"pageheader-bar-trapped",
|
|
8237
|
+
"PageHeader actionsBarBelow: an ancestor has a transform, filter, will-change or paint containment, so the fixed bar is placed against it instead of the screen. Remove it from the page header's ancestors."
|
|
8238
|
+
);
|
|
8170
8239
|
}
|
|
8171
|
-
|
|
8172
|
-
devWarnOnce(
|
|
8173
|
-
"pageheader-bar-twice",
|
|
8174
|
-
"PageHeader actionsBarBelow: two bars on one page overlap at the bottom of the screen. Give it to one PageHeader per page."
|
|
8175
|
-
);
|
|
8176
|
-
bars.push(sync);
|
|
8240
|
+
bars.add(el);
|
|
8177
8241
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
8178
|
-
if (ro) ro.observe(el);
|
|
8242
|
+
if (ro) ro.observe(el, { box: "border-box" });
|
|
8179
8243
|
window.addEventListener("resize", sync);
|
|
8180
8244
|
sync();
|
|
8181
8245
|
return function() {
|
|
8182
8246
|
if (ro) ro.disconnect();
|
|
8183
8247
|
window.removeEventListener("resize", sync);
|
|
8184
|
-
bars.
|
|
8185
|
-
if (bars.length) bars[bars.length - 1]();
|
|
8186
|
-
else root.style.removeProperty(NAME);
|
|
8248
|
+
bars.remove(el);
|
|
8187
8249
|
};
|
|
8188
8250
|
},
|
|
8189
8251
|
[bar, hasActions, split]
|
|
@@ -8704,17 +8766,7 @@ var AppShell = React49.forwardRef(function AppShell2(props, ref) {
|
|
|
8704
8766
|
|
|
8705
8767
|
// src/ActionBar.tsx
|
|
8706
8768
|
var React50 = __toESM(require("react"), 1);
|
|
8707
|
-
var
|
|
8708
|
-
var edges = [];
|
|
8709
|
-
function writeHeight() {
|
|
8710
|
-
const root = document.documentElement;
|
|
8711
|
-
for (let i = edges.length - 1; i >= 0; i--)
|
|
8712
|
-
if (edges[i].getClientRects().length > 0 && edges[i].offsetHeight > 0 && getComputedStyle(edges[i]).position === "fixed") {
|
|
8713
|
-
root.style.setProperty(HEIGHT, edges[i].offsetHeight + "px");
|
|
8714
|
-
return;
|
|
8715
|
-
}
|
|
8716
|
-
root.style.removeProperty(HEIGHT);
|
|
8717
|
-
}
|
|
8769
|
+
var edges = barStack("--aura-actionbar-height");
|
|
8718
8770
|
var ActionBar = React50.forwardRef(function ActionBar2(props, ref) {
|
|
8719
8771
|
const t = useStrings();
|
|
8720
8772
|
const bulk = props.selected != null;
|
|
@@ -8738,14 +8790,14 @@ var ActionBar = React50.forwardRef(function ActionBar2(props, ref) {
|
|
|
8738
8790
|
if (!edge || !el) return;
|
|
8739
8791
|
let checked = false;
|
|
8740
8792
|
function sync() {
|
|
8741
|
-
|
|
8793
|
+
edges.write();
|
|
8742
8794
|
if (!checked && getComputedStyle(el).position === "fixed" && (checked = true, fixedTrapped(el)))
|
|
8743
8795
|
devWarnOnce(
|
|
8744
8796
|
"actionbar-edge-trapped",
|
|
8745
8797
|
`ActionBar look="edge": an ancestor has a transform, filter, will-change or paint containment, so the fixed strip is placed against it instead of the screen. Remove it from the bar's ancestors.`
|
|
8746
8798
|
);
|
|
8747
8799
|
}
|
|
8748
|
-
edges.
|
|
8800
|
+
edges.add(el);
|
|
8749
8801
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
8750
8802
|
if (ro) ro.observe(el, { box: "border-box" });
|
|
8751
8803
|
window.addEventListener("resize", sync);
|
|
@@ -8753,8 +8805,7 @@ var ActionBar = React50.forwardRef(function ActionBar2(props, ref) {
|
|
|
8753
8805
|
return function() {
|
|
8754
8806
|
if (ro) ro.disconnect();
|
|
8755
8807
|
window.removeEventListener("resize", sync);
|
|
8756
|
-
edges.
|
|
8757
|
-
writeHeight();
|
|
8808
|
+
edges.remove(el);
|
|
8758
8809
|
};
|
|
8759
8810
|
},
|
|
8760
8811
|
[edge, idle]
|
package/dist/esm/ActionBar.js
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Button } from "./Button.js";
|
|
4
|
-
import { cx, devWarnOnce, fixedTrapped } from "./internal.js";
|
|
4
|
+
import { barStack, cx, devWarnOnce, fixedTrapped } from "./internal.js";
|
|
5
5
|
import { useStrings } from "./locale.js";
|
|
6
|
-
const
|
|
7
|
-
const edges = [];
|
|
8
|
-
function writeHeight() {
|
|
9
|
-
const root = document.documentElement;
|
|
10
|
-
for (let i = edges.length - 1; i >= 0; i--)
|
|
11
|
-
if (edges[i].getClientRects().length > 0 && edges[i].offsetHeight > 0 && getComputedStyle(edges[i]).position === "fixed") {
|
|
12
|
-
root.style.setProperty(HEIGHT, edges[i].offsetHeight + "px");
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
root.style.removeProperty(HEIGHT);
|
|
16
|
-
}
|
|
6
|
+
const edges = barStack("--aura-actionbar-height");
|
|
17
7
|
const ActionBar = React.forwardRef(function ActionBar2(props, ref) {
|
|
18
8
|
const t = useStrings();
|
|
19
9
|
const bulk = props.selected != null;
|
|
@@ -37,14 +27,14 @@ const ActionBar = React.forwardRef(function ActionBar2(props, ref) {
|
|
|
37
27
|
if (!edge || !el) return;
|
|
38
28
|
let checked = false;
|
|
39
29
|
function sync() {
|
|
40
|
-
|
|
30
|
+
edges.write();
|
|
41
31
|
if (!checked && getComputedStyle(el).position === "fixed" && (checked = true, fixedTrapped(el)))
|
|
42
32
|
devWarnOnce(
|
|
43
33
|
"actionbar-edge-trapped",
|
|
44
34
|
`ActionBar look="edge": an ancestor has a transform, filter, will-change or paint containment, so the fixed strip is placed against it instead of the screen. Remove it from the bar's ancestors.`
|
|
45
35
|
);
|
|
46
36
|
}
|
|
47
|
-
edges.
|
|
37
|
+
edges.add(el);
|
|
48
38
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
49
39
|
if (ro) ro.observe(el, { box: "border-box" });
|
|
50
40
|
window.addEventListener("resize", sync);
|
|
@@ -52,8 +42,7 @@ const ActionBar = React.forwardRef(function ActionBar2(props, ref) {
|
|
|
52
42
|
return function() {
|
|
53
43
|
if (ro) ro.disconnect();
|
|
54
44
|
window.removeEventListener("resize", sync);
|
|
55
|
-
edges.
|
|
56
|
-
writeHeight();
|
|
45
|
+
edges.remove(el);
|
|
57
46
|
};
|
|
58
47
|
},
|
|
59
48
|
[edge, idle]
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { PageHeader as StaticPageHeader } from "./PageHeader.js";
|
|
4
|
-
import { devWarnOnce, fixedTrapped as trapped, useMergedRef } from "./internal.js";
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
import { barStack, devWarnOnce, fixedTrapped as trapped, useMergedRef } from "./internal.js";
|
|
5
|
+
const bars = barStack("--aura-page-actions-height", function() {
|
|
6
|
+
devWarnOnce(
|
|
7
|
+
"pageheader-bar-twice",
|
|
8
|
+
"PageHeader actionsBarBelow: two bars are on screen at once and overlap at the bottom of the screen. Give it to one PageHeader per page (one per tab panel is fine: only the shown one counts)."
|
|
9
|
+
);
|
|
10
|
+
});
|
|
7
11
|
const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
|
|
8
12
|
const own = React.useRef(null);
|
|
9
13
|
const merged = useMergedRef(ref, own);
|
|
@@ -17,35 +21,24 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
|
|
|
17
21
|
split ? ":scope > .aura-page-header__actions > .aura-page-header__bar" : ":scope > .aura-page-header__actions"
|
|
18
22
|
);
|
|
19
23
|
if (!el) return;
|
|
20
|
-
const root = document.documentElement;
|
|
21
24
|
let checked = false;
|
|
22
25
|
function sync() {
|
|
23
|
-
|
|
24
|
-
if (getComputedStyle(el).position === "fixed")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"PageHeader actionsBarBelow: an ancestor has a transform, filter, will-change or paint containment, so the fixed bar is placed against it instead of the screen. Remove it from the page header's ancestors."
|
|
30
|
-
);
|
|
31
|
-
} else root.style.removeProperty(NAME);
|
|
26
|
+
bars.write();
|
|
27
|
+
if (!checked && getComputedStyle(el).position === "fixed" && (checked = true, trapped(el)))
|
|
28
|
+
devWarnOnce(
|
|
29
|
+
"pageheader-bar-trapped",
|
|
30
|
+
"PageHeader actionsBarBelow: an ancestor has a transform, filter, will-change or paint containment, so the fixed bar is placed against it instead of the screen. Remove it from the page header's ancestors."
|
|
31
|
+
);
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
devWarnOnce(
|
|
35
|
-
"pageheader-bar-twice",
|
|
36
|
-
"PageHeader actionsBarBelow: two bars on one page overlap at the bottom of the screen. Give it to one PageHeader per page."
|
|
37
|
-
);
|
|
38
|
-
bars.push(sync);
|
|
33
|
+
bars.add(el);
|
|
39
34
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
40
|
-
if (ro) ro.observe(el);
|
|
35
|
+
if (ro) ro.observe(el, { box: "border-box" });
|
|
41
36
|
window.addEventListener("resize", sync);
|
|
42
37
|
sync();
|
|
43
38
|
return function() {
|
|
44
39
|
if (ro) ro.disconnect();
|
|
45
40
|
window.removeEventListener("resize", sync);
|
|
46
|
-
bars.
|
|
47
|
-
if (bars.length) bars[bars.length - 1]();
|
|
48
|
-
else root.style.removeProperty(NAME);
|
|
41
|
+
bars.remove(el);
|
|
49
42
|
};
|
|
50
43
|
},
|
|
51
44
|
[bar, hasActions, split]
|
package/dist/esm/internal.js
CHANGED
|
@@ -117,10 +117,80 @@ function fixedTrapped(el) {
|
|
|
117
117
|
}
|
|
118
118
|
return false;
|
|
119
119
|
}
|
|
120
|
+
function onScreen(el) {
|
|
121
|
+
if (el.offsetHeight <= 0 || el.getClientRects().length === 0) return false;
|
|
122
|
+
const check = el.checkVisibility;
|
|
123
|
+
if (typeof check === "function") return check.call(el, { visibilityProperty: true });
|
|
124
|
+
const v = getComputedStyle(el).visibility;
|
|
125
|
+
return v !== "hidden" && v !== "collapse";
|
|
126
|
+
}
|
|
127
|
+
function barStack(name, onMany) {
|
|
128
|
+
const els = [];
|
|
129
|
+
let frame = 0;
|
|
130
|
+
const docEvents = ["click", "keydown", "focusin", "transitionend", "beforematch"];
|
|
131
|
+
const winEvents = ["hashchange", "popstate"];
|
|
132
|
+
function write() {
|
|
133
|
+
if (frame) cancelAnimationFrame(frame);
|
|
134
|
+
frame = 0;
|
|
135
|
+
const root = document.documentElement;
|
|
136
|
+
let shown = null, boxed = null, pinned = false, many = 0;
|
|
137
|
+
for (let i = els.length - 1; i >= 0; i--) {
|
|
138
|
+
const el = els[i];
|
|
139
|
+
if (getComputedStyle(el).position !== "fixed") continue;
|
|
140
|
+
pinned = true;
|
|
141
|
+
if (onScreen(el)) {
|
|
142
|
+
many++;
|
|
143
|
+
if (!shown) shown = el;
|
|
144
|
+
} else if (!boxed && el.offsetHeight > 0) boxed = el;
|
|
145
|
+
}
|
|
146
|
+
if (many > 1 && onMany) onMany();
|
|
147
|
+
const use = shown || boxed;
|
|
148
|
+
if (use) root.style.setProperty(name, use.offsetHeight + "px");
|
|
149
|
+
else if (pinned) root.style.setProperty(name, "0px");
|
|
150
|
+
else root.style.removeProperty(name);
|
|
151
|
+
}
|
|
152
|
+
function later() {
|
|
153
|
+
if (!frame) frame = requestAnimationFrame(write);
|
|
154
|
+
}
|
|
155
|
+
function now() {
|
|
156
|
+
write();
|
|
157
|
+
later();
|
|
158
|
+
}
|
|
159
|
+
function listen(on) {
|
|
160
|
+
docEvents.forEach(function(t) {
|
|
161
|
+
const f = t === "focusin" ? now : later;
|
|
162
|
+
if (on) document.addEventListener(t, f, true);
|
|
163
|
+
else document.removeEventListener(t, f, true);
|
|
164
|
+
});
|
|
165
|
+
winEvents.forEach(function(t) {
|
|
166
|
+
if (on) window.addEventListener(t, later);
|
|
167
|
+
else window.removeEventListener(t, later);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
add: function(el) {
|
|
172
|
+
els.push(el);
|
|
173
|
+
if (els.length === 1) listen(true);
|
|
174
|
+
write();
|
|
175
|
+
},
|
|
176
|
+
remove: function(el) {
|
|
177
|
+
const i = els.indexOf(el);
|
|
178
|
+
if (i >= 0) els.splice(i, 1);
|
|
179
|
+
if (!els.length) {
|
|
180
|
+
listen(false);
|
|
181
|
+
if (frame) cancelAnimationFrame(frame);
|
|
182
|
+
frame = 0;
|
|
183
|
+
}
|
|
184
|
+
write();
|
|
185
|
+
},
|
|
186
|
+
write
|
|
187
|
+
};
|
|
188
|
+
}
|
|
120
189
|
export {
|
|
121
190
|
FOCUSABLE,
|
|
122
191
|
FilterSheet,
|
|
123
192
|
TAB_STOPS,
|
|
193
|
+
barStack,
|
|
124
194
|
collator,
|
|
125
195
|
compare,
|
|
126
196
|
cx,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.73.0",
|
|
4
4
|
"description": "AURA Design System — React components (Enterprise Standard, Human Creative). Thai-first: Buddhist-era dates, Thai collation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|