@jsenv/navi 0.29.236 → 0.29.238
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/dev/jsenv_navi.js +134 -71
- package/dist/dev/jsenv_navi.js.map +6 -6
- package/dist/jsenv_navi.js +76 -71
- package/dist/jsenv_navi.js.map +6 -6
- package/docs/AI_INSTRUCTIONS.md +5 -3
- package/docs/css_architecture.md +82 -10
- package/package.json +4 -4
package/dist/jsenv_navi.js
CHANGED
|
@@ -18654,6 +18654,20 @@ const resolveSpacingSize = (size, element, property = "padding") => {
|
|
|
18654
18654
|
}
|
|
18655
18655
|
return normalizeStyle(SIZE_MAP[size] || size, property, "js", element);
|
|
18656
18656
|
};
|
|
18657
|
+
// Whether a spacing is nothing at all, answered without resolving it. A
|
|
18658
|
+
// viewport or container length resolves through a computed-style read, and
|
|
18659
|
+
// asked during a render that read forces the browser to compute the style of
|
|
18660
|
+
// a tree still being built, stylesheets still being adopted. Zero is a fact
|
|
18661
|
+
// about the number written, whatever the unit; a scale keyword is never zero.
|
|
18662
|
+
const isZeroSpacingSize = (size) => {
|
|
18663
|
+
if (typeof size === "number") {
|
|
18664
|
+
return size === 0;
|
|
18665
|
+
}
|
|
18666
|
+
if (typeof size !== "string") {
|
|
18667
|
+
return false;
|
|
18668
|
+
}
|
|
18669
|
+
return parseFloat(size) === 0;
|
|
18670
|
+
};
|
|
18657
18671
|
|
|
18658
18672
|
const COLOR_KEYWORD_MAP = {
|
|
18659
18673
|
primary: "var(--navi-color-primary)",
|
|
@@ -39403,47 +39417,35 @@ const LoadingIndicatorFluid = ({
|
|
|
39403
39417
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
39404
39418
|
const [containerHeight, setContainerHeight] = useState(0);
|
|
39405
39419
|
const [containerRadius, setContainerRadius] = useState(0);
|
|
39420
|
+
|
|
39421
|
+
// Sized by the observer alone, first frame included: an element gets an
|
|
39422
|
+
// observation for the size it has when first observed, delivered after the
|
|
39423
|
+
// frame's own layout and before its paint. Measuring here instead would
|
|
39424
|
+
// force a layout in the middle of the commit, on a tree the commit is still
|
|
39425
|
+
// writing to, and the frame would lay it out again. Inside the callback style
|
|
39426
|
+
// and layout are clean, so the radius read there is a lookup, not a recalc.
|
|
39406
39427
|
useLayoutEffect(() => {
|
|
39407
39428
|
const indicatorEl = ref.current;
|
|
39408
39429
|
if (!indicatorEl) {
|
|
39409
39430
|
return null;
|
|
39410
39431
|
}
|
|
39411
|
-
const {
|
|
39412
|
-
|
|
39413
|
-
|
|
39414
|
-
|
|
39415
|
-
|
|
39416
|
-
|
|
39417
|
-
|
|
39418
|
-
|
|
39419
|
-
|
|
39420
|
-
|
|
39421
|
-
|
|
39422
|
-
|
|
39423
|
-
|
|
39424
|
-
|
|
39425
|
-
let animationFrameId = null;
|
|
39426
|
-
// Create a resize observer to detect changes in the container's dimensions
|
|
39427
|
-
const resizeObserver = new ResizeObserver(entries => {
|
|
39428
|
-
// Use requestAnimationFrame to debounce updates
|
|
39429
|
-
if (animationFrameId) {
|
|
39430
|
-
cancelAnimationFrame(animationFrameId);
|
|
39431
|
-
}
|
|
39432
|
-
animationFrameId = requestAnimationFrame(() => {
|
|
39433
|
-
const [containerEntry] = entries;
|
|
39434
|
-
const {
|
|
39435
|
-
width,
|
|
39436
|
-
height
|
|
39437
|
-
} = containerEntry.contentRect;
|
|
39438
|
-
setContainerWidth(width);
|
|
39439
|
-
setContainerHeight(height);
|
|
39440
|
-
});
|
|
39432
|
+
const resizeObserver = new ResizeObserver(([containerEntry]) => {
|
|
39433
|
+
const {
|
|
39434
|
+
width,
|
|
39435
|
+
height
|
|
39436
|
+
} = containerEntry.contentRect;
|
|
39437
|
+
setContainerWidth(width);
|
|
39438
|
+
setContainerHeight(height);
|
|
39439
|
+
if (radius === undefined || radius === "inherit") {
|
|
39440
|
+
const parentEl = indicatorEl.parentElement;
|
|
39441
|
+
// The inline style says the radius as the caller wrote it; the
|
|
39442
|
+
// computed longhand otherwise, the shorthand computing to "" when the
|
|
39443
|
+
// four corners differ.
|
|
39444
|
+
setContainerRadius(parentEl.style.borderRadius || parentEl.style.borderTopLeftRadius || getComputedStyle(parentEl).borderTopLeftRadius || "0px");
|
|
39445
|
+
}
|
|
39441
39446
|
});
|
|
39442
39447
|
resizeObserver.observe(indicatorEl);
|
|
39443
39448
|
return () => {
|
|
39444
|
-
if (animationFrameId) {
|
|
39445
|
-
cancelAnimationFrame(animationFrameId);
|
|
39446
|
-
}
|
|
39447
39449
|
resizeObserver.disconnect();
|
|
39448
39450
|
};
|
|
39449
39451
|
}, []);
|
|
@@ -43776,6 +43778,13 @@ const measureDrawing = ({
|
|
|
43776
43778
|
* Measured rather than declared: a bar's size comes from a prop, a theme
|
|
43777
43779
|
* variable, its own content or the device's notch, and only the used value
|
|
43778
43780
|
* knows all four.
|
|
43781
|
+
*
|
|
43782
|
+
* Written once per task, after every bar has measured. The variable resizes
|
|
43783
|
+
* an ancestor of the bars — the scroll container takes its padding from it —
|
|
43784
|
+
* so a write landing between two measurements turns the second one into a
|
|
43785
|
+
* style recalc and a layout of the whole page. Sizes are queued, and the queue
|
|
43786
|
+
* lands in a microtask: still before the browser paints, so the content is
|
|
43787
|
+
* never seen under a bar, and after every read of the commit that queued them.
|
|
43779
43788
|
*/
|
|
43780
43789
|
|
|
43781
43790
|
// Several bars can share an edge — during a page transition the outgoing and
|
|
@@ -43789,10 +43798,14 @@ const sizeMapByArea = new Map();
|
|
|
43789
43798
|
// size again — the ones for the smaller bars, and the second half of a page
|
|
43790
43799
|
// transition.
|
|
43791
43800
|
const writtenValueByArea = new Map();
|
|
43801
|
+
// Sizes said and not yet written. One queue for both callers below: a bar
|
|
43802
|
+
// saying its size twice before the write keeps the last word, whoever said it.
|
|
43803
|
+
const pendingSizeMapByArea = new Map();
|
|
43804
|
+
let flushMicrotaskQueued = false;
|
|
43805
|
+
let flushFrame = null;
|
|
43792
43806
|
|
|
43793
|
-
// A size
|
|
43794
|
-
// the room it takes is given back
|
|
43795
|
-
// painted under it.
|
|
43807
|
+
// A size a render produced: a prop, the children or a theme variable changed
|
|
43808
|
+
// the bar, and the room it takes is given back before that commit is painted.
|
|
43796
43809
|
/**
|
|
43797
43810
|
* @param {"top"|"bottom"|"left"|"right"} area
|
|
43798
43811
|
* @param {Element} barElement - Which bar this size belongs to.
|
|
@@ -43800,41 +43813,47 @@ const writtenValueByArea = new Map();
|
|
|
43800
43813
|
* content.
|
|
43801
43814
|
*/
|
|
43802
43815
|
const setFixedBarSpace = (area, barElement, size) => {
|
|
43803
|
-
|
|
43804
|
-
|
|
43805
|
-
|
|
43806
|
-
}
|
|
43807
|
-
|
|
43808
|
-
|
|
43809
|
-
|
|
43810
|
-
|
|
43811
|
-
|
|
43812
|
-
|
|
43813
|
-
|
|
43814
|
-
//
|
|
43816
|
+
queueSize(area, barElement, size);
|
|
43817
|
+
if (flushMicrotaskQueued) {
|
|
43818
|
+
return;
|
|
43819
|
+
}
|
|
43820
|
+
flushMicrotaskQueued = true;
|
|
43821
|
+
queueMicrotask(() => {
|
|
43822
|
+
flushMicrotaskQueued = false;
|
|
43823
|
+
flushPendingSizes();
|
|
43824
|
+
});
|
|
43825
|
+
};
|
|
43826
|
+
|
|
43827
|
+
// A size nothing asked for, coming from a ResizeObserver. Mutating layout from
|
|
43828
|
+
// inside a resize callback is what makes the browser report "ResizeObserver
|
|
43829
|
+
// loop completed with undelivered notifications", so this write waits for the
|
|
43830
|
+
// frame that resize produced.
|
|
43815
43831
|
/**
|
|
43816
43832
|
* @param {"top"|"bottom"|"left"|"right"} area
|
|
43817
43833
|
* @param {Element} barElement - Which bar this size belongs to.
|
|
43818
43834
|
* @param {number} size - In px.
|
|
43819
43835
|
*/
|
|
43820
43836
|
const requestFixedBarSpace = (area, barElement, size) => {
|
|
43837
|
+
queueSize(area, barElement, size);
|
|
43838
|
+
if (flushFrame !== null) {
|
|
43839
|
+
return;
|
|
43840
|
+
}
|
|
43841
|
+
flushFrame = requestAnimationFrame(() => {
|
|
43842
|
+
flushFrame = null;
|
|
43843
|
+
flushPendingSizes();
|
|
43844
|
+
});
|
|
43845
|
+
};
|
|
43846
|
+
|
|
43847
|
+
const queueSize = (area, barElement, size) => {
|
|
43821
43848
|
let pendingSizeMap = pendingSizeMapByArea.get(area);
|
|
43822
43849
|
if (!pendingSizeMap) {
|
|
43823
43850
|
pendingSizeMap = new Map();
|
|
43824
43851
|
pendingSizeMapByArea.set(area, pendingSizeMap);
|
|
43825
43852
|
}
|
|
43826
43853
|
pendingSizeMap.set(barElement, size);
|
|
43827
|
-
if (flushFrame !== null) {
|
|
43828
|
-
return;
|
|
43829
|
-
}
|
|
43830
|
-
flushFrame = requestAnimationFrame(flushPendingSizes);
|
|
43831
43854
|
};
|
|
43832
43855
|
|
|
43833
|
-
const pendingSizeMapByArea = new Map();
|
|
43834
|
-
let flushFrame = null;
|
|
43835
|
-
|
|
43836
43856
|
const flushPendingSizes = () => {
|
|
43837
|
-
flushFrame = null;
|
|
43838
43857
|
for (const [area, pendingSizeMap] of pendingSizeMapByArea) {
|
|
43839
43858
|
for (const [barElement, size] of pendingSizeMap) {
|
|
43840
43859
|
storeSize(area, barElement, size);
|
|
@@ -43844,20 +43863,6 @@ const flushPendingSizes = () => {
|
|
|
43844
43863
|
pendingSizeMapByArea.clear();
|
|
43845
43864
|
};
|
|
43846
43865
|
|
|
43847
|
-
// What the bar itself just said wins over what its observer had queued about
|
|
43848
|
-
// it: a bar unmounting gives its room back, and a size queued for it before
|
|
43849
|
-
// that must not put it back.
|
|
43850
|
-
const dropPendingSize = (area, barElement) => {
|
|
43851
|
-
const pendingSizeMap = pendingSizeMapByArea.get(area);
|
|
43852
|
-
if (!pendingSizeMap) {
|
|
43853
|
-
return;
|
|
43854
|
-
}
|
|
43855
|
-
pendingSizeMap.delete(barElement);
|
|
43856
|
-
if (pendingSizeMap.size === 0) {
|
|
43857
|
-
pendingSizeMapByArea.delete(area);
|
|
43858
|
-
}
|
|
43859
|
-
};
|
|
43860
|
-
|
|
43861
43866
|
const storeSize = (area, barElement, size) => {
|
|
43862
43867
|
let sizeMap = sizeMapByArea.get(area);
|
|
43863
43868
|
if (!sizeMap) {
|
|
@@ -58955,7 +58960,7 @@ const useDialogProps = props => {
|
|
|
58955
58960
|
bottom: false,
|
|
58956
58961
|
left: false
|
|
58957
58962
|
};
|
|
58958
|
-
if (
|
|
58963
|
+
if (isZeroSpacingSize(marginWithContainer)) {
|
|
58959
58964
|
const {
|
|
58960
58965
|
y,
|
|
58961
58966
|
x
|