@jsenv/navi 0.29.236 → 0.29.298
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 +189 -86
- package/dist/dev/jsenv_navi.js.map +11 -11
- package/dist/dev/jsenv_navi_side_effects.js +1 -1
- package/dist/dev/jsenv_navi_side_effects.js.map +2 -2
- package/dist/jsenv_navi.js +131 -86
- package/dist/jsenv_navi.js.map +11 -11
- package/dist/jsenv_navi_side_effects.js +1 -1
- package/dist/jsenv_navi_side_effects.js.map +2 -2
- package/docs/AI_INSTRUCTIONS.md +5 -3
- package/docs/css_architecture.md +82 -10
- package/docs/popup_open.md +15 -3
- package/package.json +4 -4
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -6984,7 +6984,17 @@ const openCallout = (
|
|
|
6984
6984
|
`append callout into ${getElementSignature(calloutContainer)}`,
|
|
6985
6985
|
);
|
|
6986
6986
|
}
|
|
6987
|
+
let checkCalloutInsertionImpact;
|
|
6988
|
+
{
|
|
6989
|
+
checkCalloutInsertionImpact = startCalloutInsertionImpactCheck(
|
|
6990
|
+
calloutContainer,
|
|
6991
|
+
anchorElement,
|
|
6992
|
+
);
|
|
6993
|
+
}
|
|
6987
6994
|
calloutContainer.appendChild(calloutElement);
|
|
6995
|
+
if (checkCalloutInsertionImpact) {
|
|
6996
|
+
checkCalloutInsertionImpact();
|
|
6997
|
+
}
|
|
6988
6998
|
calloutElement.showPopover();
|
|
6989
6999
|
addTeardown(() => {
|
|
6990
7000
|
calloutElement.remove();
|
|
@@ -7550,6 +7560,54 @@ const canContainCallout = (element) => {
|
|
|
7550
7560
|
return true;
|
|
7551
7561
|
};
|
|
7552
7562
|
|
|
7563
|
+
// A callout is a popover with no layout box of its own, so putting it in the
|
|
7564
|
+
// tree must move nothing. Anything that does move means an app rule counting
|
|
7565
|
+
// element children — :last-child, :nth-child, :only-child, :empty, > * + * —
|
|
7566
|
+
// took the callout for one of them and changed subject. Invisible from the
|
|
7567
|
+
// app, where the rule and the markup both read fine.
|
|
7568
|
+
// Two boxes rather than every child of the container: a callout on a list row
|
|
7569
|
+
// would otherwise measure the whole list on each press.
|
|
7570
|
+
const startCalloutInsertionImpactCheck = (calloutContainer, anchorElement) => {
|
|
7571
|
+
if (!anchorElement) {
|
|
7572
|
+
return null;
|
|
7573
|
+
}
|
|
7574
|
+
const anchorBoxBefore = anchorElement.getBoundingClientRect();
|
|
7575
|
+
const containerBoxBefore = calloutContainer.getBoundingClientRect();
|
|
7576
|
+
return () => {
|
|
7577
|
+
const anchorBoxAfter = anchorElement.getBoundingClientRect();
|
|
7578
|
+
const containerBoxAfter = calloutContainer.getBoundingClientRect();
|
|
7579
|
+
let what;
|
|
7580
|
+
let boxBefore;
|
|
7581
|
+
let boxAfter;
|
|
7582
|
+
if (!isSameBox(anchorBoxBefore, anchorBoxAfter)) {
|
|
7583
|
+
what = "moved it";
|
|
7584
|
+
boxBefore = anchorBoxBefore;
|
|
7585
|
+
boxAfter = anchorBoxAfter;
|
|
7586
|
+
} else if (!isSameBox(containerBoxBefore, containerBoxAfter)) {
|
|
7587
|
+
what = `moved ${getElementSignature(calloutContainer)} around it`;
|
|
7588
|
+
boxBefore = containerBoxBefore;
|
|
7589
|
+
boxAfter = containerBoxAfter;
|
|
7590
|
+
} else {
|
|
7591
|
+
return;
|
|
7592
|
+
}
|
|
7593
|
+
console.warn(
|
|
7594
|
+
`opening a callout on ${getElementSignature(anchorElement)} ${what}: ${formatBox(boxBefore)} -> ${formatBox(boxAfter)}.
|
|
7595
|
+
A callout draws nothing in the flow, but while it is open it is an element child of ${getElementSignature(calloutContainer)}: a rule counting children there (:last-child, :nth-child, :only-child, :empty, > * + *) counts it too and matches something else than what it aims at.
|
|
7596
|
+
Say which children the rule counts: :nth-last-child(1 of S) / :nth-child(An+B of S), where S names yours (a class, or :not([navi-out-of-flow]) — the marker navi's out-of-flow elements carry). A sibling rule takes the marker between its compounds: > *:not([navi-out-of-flow]) + *:not([navi-out-of-flow]).
|
|
7597
|
+
See @jsenv/navi docs/css_architecture.md.`,
|
|
7598
|
+
);
|
|
7599
|
+
};
|
|
7600
|
+
};
|
|
7601
|
+
const isSameBox = (a, b) => {
|
|
7602
|
+
return (
|
|
7603
|
+
a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height
|
|
7604
|
+
);
|
|
7605
|
+
};
|
|
7606
|
+
const formatBox = ({ x, y, width, height }) => {
|
|
7607
|
+
const round = (value) => Math.round(value * 100) / 100;
|
|
7608
|
+
return `${round(width)}x${round(height)} at ${round(x)},${round(y)}`;
|
|
7609
|
+
};
|
|
7610
|
+
|
|
7553
7611
|
const escapeHtml = (string) => {
|
|
7554
7612
|
return string
|
|
7555
7613
|
.replace(/&/g, "&")
|
|
@@ -18950,6 +19008,20 @@ const resolveSpacingSize = (size, element, property = "padding") => {
|
|
|
18950
19008
|
}
|
|
18951
19009
|
return normalizeStyle(SIZE_MAP[size] || size, property, "js", element);
|
|
18952
19010
|
};
|
|
19011
|
+
// Whether a spacing is nothing at all, answered without resolving it. A
|
|
19012
|
+
// viewport or container length resolves through a computed-style read, and
|
|
19013
|
+
// asked during a render that read forces the browser to compute the style of
|
|
19014
|
+
// a tree still being built, stylesheets still being adopted. Zero is a fact
|
|
19015
|
+
// about the number written, whatever the unit; a scale keyword is never zero.
|
|
19016
|
+
const isZeroSpacingSize = (size) => {
|
|
19017
|
+
if (typeof size === "number") {
|
|
19018
|
+
return size === 0;
|
|
19019
|
+
}
|
|
19020
|
+
if (typeof size !== "string") {
|
|
19021
|
+
return false;
|
|
19022
|
+
}
|
|
19023
|
+
return parseFloat(size) === 0;
|
|
19024
|
+
};
|
|
18953
19025
|
|
|
18954
19026
|
const COLOR_KEYWORD_MAP = {
|
|
18955
19027
|
primary: "var(--navi-color-primary)",
|
|
@@ -20605,16 +20677,16 @@ const useComposeElementRef = (syncElement, externalRef) => {
|
|
|
20605
20677
|
const cleanupRef = useRef(null);
|
|
20606
20678
|
const elRef = useRef(null);
|
|
20607
20679
|
const prevSyncElementRef = useRef(undefined);
|
|
20608
|
-
const
|
|
20680
|
+
const holderRef = useRef(null);
|
|
20609
20681
|
const externalRefRef = useRef(externalRef);
|
|
20610
20682
|
const syncElementRef = useRef(syncElement);
|
|
20611
20683
|
syncElementRef.current = syncElement;
|
|
20612
|
-
// Detect external ref identity change between renders. The refCallback
|
|
20613
|
-
//
|
|
20614
|
-
// switches from null to a ref), Preact does NOT re-fire the
|
|
20615
|
-
// the DOM element is unchanged. We must manually clear the
|
|
20616
|
-
// populate the new one with the current element to avoid
|
|
20617
|
-
// ref's `.current` stuck at `null`.
|
|
20684
|
+
// Detect external ref identity change between renders. The refCallback keeps
|
|
20685
|
+
// its identity once it holds the element, so when the parent passes a new
|
|
20686
|
+
// ref object (or switches from null to a ref), Preact does NOT re-fire the
|
|
20687
|
+
// callback while the DOM element is unchanged. We must manually clear the
|
|
20688
|
+
// old ref and populate the new one with the current element to avoid
|
|
20689
|
+
// leaving the new ref's `.current` stuck at `null`.
|
|
20618
20690
|
const prevExternalRefRef = useRef(externalRef);
|
|
20619
20691
|
if (prevExternalRefRef.current !== externalRef) {
|
|
20620
20692
|
const previous = prevExternalRefRef.current;
|
|
@@ -20632,12 +20704,12 @@ const useComposeElementRef = (syncElement, externalRef) => {
|
|
|
20632
20704
|
}
|
|
20633
20705
|
externalRefRef.current = externalRef;
|
|
20634
20706
|
|
|
20635
|
-
if (!
|
|
20636
|
-
// Created once,
|
|
20637
|
-
//
|
|
20638
|
-
//
|
|
20639
|
-
//
|
|
20640
|
-
//
|
|
20707
|
+
if (!holderRef.current) {
|
|
20708
|
+
// Created once, and reading the sync function through a ref for that
|
|
20709
|
+
// reason: the element can be replaced long after the first render — a tag
|
|
20710
|
+
// that changes, a box hidden then shown — and what the new element gets
|
|
20711
|
+
// must be the current render's sync, not the one the first render closed
|
|
20712
|
+
// over.
|
|
20641
20713
|
const runSync = (el) => {
|
|
20642
20714
|
if (cleanupRef.current) {
|
|
20643
20715
|
cleanupRef.current();
|
|
@@ -20650,6 +20722,18 @@ const useComposeElementRef = (syncElement, externalRef) => {
|
|
|
20650
20722
|
cleanupRef.current = cleanup;
|
|
20651
20723
|
}
|
|
20652
20724
|
};
|
|
20725
|
+
holderRef.current = { runSync, refCallback: null };
|
|
20726
|
+
}
|
|
20727
|
+
const { runSync } = holderRef.current;
|
|
20728
|
+
|
|
20729
|
+
// A new callback on every render until Preact has handed it the element,
|
|
20730
|
+
// the same one afterwards. Preact re-applies a ref only when its identity
|
|
20731
|
+
// changes, and a diff that throws with no error boundary above skips
|
|
20732
|
+
// commitRoot: its refs are dropped while its DOM stays and is adopted as
|
|
20733
|
+
// mounted by the next render. A callback that never fired would then never
|
|
20734
|
+
// fire, and a Box would stay raw HTML for the life of the document. Free on
|
|
20735
|
+
// a healthy mount, where the first callback is the only one ever created.
|
|
20736
|
+
if (!elRef.current) {
|
|
20653
20737
|
const refCallback = (el) => {
|
|
20654
20738
|
elRef.current = el;
|
|
20655
20739
|
// Keep .current in sync immediately so useEffect callbacks that read
|
|
@@ -20673,9 +20757,9 @@ const useComposeElementRef = (syncElement, externalRef) => {
|
|
|
20673
20757
|
prevSyncElementRef.current = undefined;
|
|
20674
20758
|
}
|
|
20675
20759
|
};
|
|
20676
|
-
|
|
20760
|
+
holderRef.current.refCallback = refCallback;
|
|
20677
20761
|
}
|
|
20678
|
-
const { refCallback
|
|
20762
|
+
const { refCallback } = holderRef.current;
|
|
20679
20763
|
|
|
20680
20764
|
// If element already mounted, re-sync when syncElement reference changed.
|
|
20681
20765
|
if (elRef.current && syncElement !== prevSyncElementRef.current) {
|
|
@@ -32186,6 +32270,17 @@ registerNaviCommand("--navi-send", (source, event, { requester }) => {
|
|
|
32186
32270
|
return sent;
|
|
32187
32271
|
}
|
|
32188
32272
|
if (isRunning) {
|
|
32273
|
+
// An optimistic control takes its send as done on its own word: what
|
|
32274
|
+
// follows it runs at once and the run goes on detached — still
|
|
32275
|
+
// watched, still able to fail, its error callout then drawn on what
|
|
32276
|
+
// surrounds the closed surface it was typed in (see openCallout's
|
|
32277
|
+
// anchor resolution in callout.js).
|
|
32278
|
+
const sendController = (findControlHost(target) || target)
|
|
32279
|
+
.__uiStateController__;
|
|
32280
|
+
if (sendController?.optimistic) {
|
|
32281
|
+
runAfterSend();
|
|
32282
|
+
return sent;
|
|
32283
|
+
}
|
|
32189
32284
|
// The send is committing but has not finished: leaving now would take
|
|
32190
32285
|
// the form off the screen mid-submission (a popup closing over its own
|
|
32191
32286
|
// running action, a slide moving on before it is answered). What
|
|
@@ -36777,6 +36872,16 @@ const useControlProps = (props, {
|
|
|
36777
36872
|
if (!deferredCommand) {
|
|
36778
36873
|
return;
|
|
36779
36874
|
}
|
|
36875
|
+
if (uiStateController.optimistic) {
|
|
36876
|
+
// An optimistic button takes its action as done on its own word:
|
|
36877
|
+
// the command runs at once and the run goes on detached, the same
|
|
36878
|
+
// release the form counterpart gives the send (see --navi-send in
|
|
36879
|
+
// commands.js). Only a refused press has nothing to follow.
|
|
36880
|
+
if (completion.result !== false) {
|
|
36881
|
+
deferredCommand();
|
|
36882
|
+
}
|
|
36883
|
+
return;
|
|
36884
|
+
}
|
|
36780
36885
|
runWhenActionSucceeded(completion, deferredCommand);
|
|
36781
36886
|
};
|
|
36782
36887
|
return {
|
|
@@ -39989,47 +40094,35 @@ const LoadingIndicatorFluid = ({
|
|
|
39989
40094
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
39990
40095
|
const [containerHeight, setContainerHeight] = useState(0);
|
|
39991
40096
|
const [containerRadius, setContainerRadius] = useState(0);
|
|
40097
|
+
|
|
40098
|
+
// Sized by the observer alone, first frame included: an element gets an
|
|
40099
|
+
// observation for the size it has when first observed, delivered after the
|
|
40100
|
+
// frame's own layout and before its paint. Measuring here instead would
|
|
40101
|
+
// force a layout in the middle of the commit, on a tree the commit is still
|
|
40102
|
+
// writing to, and the frame would lay it out again. Inside the callback style
|
|
40103
|
+
// and layout are clean, so the radius read there is a lookup, not a recalc.
|
|
39992
40104
|
useLayoutEffect(() => {
|
|
39993
40105
|
const indicatorEl = ref.current;
|
|
39994
40106
|
if (!indicatorEl) {
|
|
39995
40107
|
return null;
|
|
39996
40108
|
}
|
|
39997
|
-
const {
|
|
39998
|
-
|
|
39999
|
-
|
|
40000
|
-
|
|
40001
|
-
|
|
40002
|
-
|
|
40003
|
-
|
|
40004
|
-
|
|
40005
|
-
|
|
40006
|
-
|
|
40007
|
-
|
|
40008
|
-
|
|
40009
|
-
|
|
40010
|
-
|
|
40011
|
-
let animationFrameId = null;
|
|
40012
|
-
// Create a resize observer to detect changes in the container's dimensions
|
|
40013
|
-
const resizeObserver = new ResizeObserver(entries => {
|
|
40014
|
-
// Use requestAnimationFrame to debounce updates
|
|
40015
|
-
if (animationFrameId) {
|
|
40016
|
-
cancelAnimationFrame(animationFrameId);
|
|
40017
|
-
}
|
|
40018
|
-
animationFrameId = requestAnimationFrame(() => {
|
|
40019
|
-
const [containerEntry] = entries;
|
|
40020
|
-
const {
|
|
40021
|
-
width,
|
|
40022
|
-
height
|
|
40023
|
-
} = containerEntry.contentRect;
|
|
40024
|
-
setContainerWidth(width);
|
|
40025
|
-
setContainerHeight(height);
|
|
40026
|
-
});
|
|
40109
|
+
const resizeObserver = new ResizeObserver(([containerEntry]) => {
|
|
40110
|
+
const {
|
|
40111
|
+
width,
|
|
40112
|
+
height
|
|
40113
|
+
} = containerEntry.contentRect;
|
|
40114
|
+
setContainerWidth(width);
|
|
40115
|
+
setContainerHeight(height);
|
|
40116
|
+
if (radius === undefined || radius === "inherit") {
|
|
40117
|
+
const parentEl = indicatorEl.parentElement;
|
|
40118
|
+
// The inline style says the radius as the caller wrote it; the
|
|
40119
|
+
// computed longhand otherwise, the shorthand computing to "" when the
|
|
40120
|
+
// four corners differ.
|
|
40121
|
+
setContainerRadius(parentEl.style.borderRadius || parentEl.style.borderTopLeftRadius || getComputedStyle(parentEl).borderTopLeftRadius || "0px");
|
|
40122
|
+
}
|
|
40027
40123
|
});
|
|
40028
40124
|
resizeObserver.observe(indicatorEl);
|
|
40029
40125
|
return () => {
|
|
40030
|
-
if (animationFrameId) {
|
|
40031
|
-
cancelAnimationFrame(animationFrameId);
|
|
40032
|
-
}
|
|
40033
40126
|
resizeObserver.disconnect();
|
|
40034
40127
|
};
|
|
40035
40128
|
}, []);
|
|
@@ -44371,6 +44464,13 @@ const measureDrawing = ({
|
|
|
44371
44464
|
* Measured rather than declared: a bar's size comes from a prop, a theme
|
|
44372
44465
|
* variable, its own content or the device's notch, and only the used value
|
|
44373
44466
|
* knows all four.
|
|
44467
|
+
*
|
|
44468
|
+
* Written once per task, after every bar has measured. The variable resizes
|
|
44469
|
+
* an ancestor of the bars — the scroll container takes its padding from it —
|
|
44470
|
+
* so a write landing between two measurements turns the second one into a
|
|
44471
|
+
* style recalc and a layout of the whole page. Sizes are queued, and the queue
|
|
44472
|
+
* lands in a microtask: still before the browser paints, so the content is
|
|
44473
|
+
* never seen under a bar, and after every read of the commit that queued them.
|
|
44374
44474
|
*/
|
|
44375
44475
|
|
|
44376
44476
|
// Several bars can share an edge — during a page transition the outgoing and
|
|
@@ -44384,10 +44484,14 @@ const sizeMapByArea = new Map();
|
|
|
44384
44484
|
// size again — the ones for the smaller bars, and the second half of a page
|
|
44385
44485
|
// transition.
|
|
44386
44486
|
const writtenValueByArea = new Map();
|
|
44487
|
+
// Sizes said and not yet written. One queue for both callers below: a bar
|
|
44488
|
+
// saying its size twice before the write keeps the last word, whoever said it.
|
|
44489
|
+
const pendingSizeMapByArea = new Map();
|
|
44490
|
+
let flushMicrotaskQueued = false;
|
|
44491
|
+
let flushFrame = null;
|
|
44387
44492
|
|
|
44388
|
-
// A size
|
|
44389
|
-
// the room it takes is given back
|
|
44390
|
-
// painted under it.
|
|
44493
|
+
// A size a render produced: a prop, the children or a theme variable changed
|
|
44494
|
+
// the bar, and the room it takes is given back before that commit is painted.
|
|
44391
44495
|
/**
|
|
44392
44496
|
* @param {"top"|"bottom"|"left"|"right"} area
|
|
44393
44497
|
* @param {Element} barElement - Which bar this size belongs to.
|
|
@@ -44395,41 +44499,47 @@ const writtenValueByArea = new Map();
|
|
|
44395
44499
|
* content.
|
|
44396
44500
|
*/
|
|
44397
44501
|
const setFixedBarSpace = (area, barElement, size) => {
|
|
44398
|
-
|
|
44399
|
-
|
|
44400
|
-
|
|
44401
|
-
}
|
|
44402
|
-
|
|
44403
|
-
|
|
44404
|
-
|
|
44405
|
-
|
|
44406
|
-
|
|
44407
|
-
|
|
44408
|
-
|
|
44409
|
-
//
|
|
44502
|
+
queueSize(area, barElement, size);
|
|
44503
|
+
if (flushMicrotaskQueued) {
|
|
44504
|
+
return;
|
|
44505
|
+
}
|
|
44506
|
+
flushMicrotaskQueued = true;
|
|
44507
|
+
queueMicrotask(() => {
|
|
44508
|
+
flushMicrotaskQueued = false;
|
|
44509
|
+
flushPendingSizes();
|
|
44510
|
+
});
|
|
44511
|
+
};
|
|
44512
|
+
|
|
44513
|
+
// A size nothing asked for, coming from a ResizeObserver. Mutating layout from
|
|
44514
|
+
// inside a resize callback is what makes the browser report "ResizeObserver
|
|
44515
|
+
// loop completed with undelivered notifications", so this write waits for the
|
|
44516
|
+
// frame that resize produced.
|
|
44410
44517
|
/**
|
|
44411
44518
|
* @param {"top"|"bottom"|"left"|"right"} area
|
|
44412
44519
|
* @param {Element} barElement - Which bar this size belongs to.
|
|
44413
44520
|
* @param {number} size - In px.
|
|
44414
44521
|
*/
|
|
44415
44522
|
const requestFixedBarSpace = (area, barElement, size) => {
|
|
44523
|
+
queueSize(area, barElement, size);
|
|
44524
|
+
if (flushFrame !== null) {
|
|
44525
|
+
return;
|
|
44526
|
+
}
|
|
44527
|
+
flushFrame = requestAnimationFrame(() => {
|
|
44528
|
+
flushFrame = null;
|
|
44529
|
+
flushPendingSizes();
|
|
44530
|
+
});
|
|
44531
|
+
};
|
|
44532
|
+
|
|
44533
|
+
const queueSize = (area, barElement, size) => {
|
|
44416
44534
|
let pendingSizeMap = pendingSizeMapByArea.get(area);
|
|
44417
44535
|
if (!pendingSizeMap) {
|
|
44418
44536
|
pendingSizeMap = new Map();
|
|
44419
44537
|
pendingSizeMapByArea.set(area, pendingSizeMap);
|
|
44420
44538
|
}
|
|
44421
44539
|
pendingSizeMap.set(barElement, size);
|
|
44422
|
-
if (flushFrame !== null) {
|
|
44423
|
-
return;
|
|
44424
|
-
}
|
|
44425
|
-
flushFrame = requestAnimationFrame(flushPendingSizes);
|
|
44426
44540
|
};
|
|
44427
44541
|
|
|
44428
|
-
const pendingSizeMapByArea = new Map();
|
|
44429
|
-
let flushFrame = null;
|
|
44430
|
-
|
|
44431
44542
|
const flushPendingSizes = () => {
|
|
44432
|
-
flushFrame = null;
|
|
44433
44543
|
for (const [area, pendingSizeMap] of pendingSizeMapByArea) {
|
|
44434
44544
|
for (const [barElement, size] of pendingSizeMap) {
|
|
44435
44545
|
storeSize(area, barElement, size);
|
|
@@ -44439,20 +44549,6 @@ const flushPendingSizes = () => {
|
|
|
44439
44549
|
pendingSizeMapByArea.clear();
|
|
44440
44550
|
};
|
|
44441
44551
|
|
|
44442
|
-
// What the bar itself just said wins over what its observer had queued about
|
|
44443
|
-
// it: a bar unmounting gives its room back, and a size queued for it before
|
|
44444
|
-
// that must not put it back.
|
|
44445
|
-
const dropPendingSize = (area, barElement) => {
|
|
44446
|
-
const pendingSizeMap = pendingSizeMapByArea.get(area);
|
|
44447
|
-
if (!pendingSizeMap) {
|
|
44448
|
-
return;
|
|
44449
|
-
}
|
|
44450
|
-
pendingSizeMap.delete(barElement);
|
|
44451
|
-
if (pendingSizeMap.size === 0) {
|
|
44452
|
-
pendingSizeMapByArea.delete(area);
|
|
44453
|
-
}
|
|
44454
|
-
};
|
|
44455
|
-
|
|
44456
44552
|
const storeSize = (area, barElement, size) => {
|
|
44457
44553
|
let sizeMap = sizeMapByArea.get(area);
|
|
44458
44554
|
if (!sizeMap) {
|
|
@@ -48732,6 +48828,7 @@ const COMMAND_DEFAULT_PROPS_FACTORIES = {
|
|
|
48732
48828
|
* replace?: boolean,
|
|
48733
48829
|
* actionStandalone?: boolean,
|
|
48734
48830
|
* actionAbortable?: boolean,
|
|
48831
|
+
* optimistic?: boolean,
|
|
48735
48832
|
* [key: string]: any,
|
|
48736
48833
|
* }>}
|
|
48737
48834
|
* @param {boolean} [replace] Go where the press leads — an `href`, a
|
|
@@ -48775,6 +48872,12 @@ const COMMAND_DEFAULT_PROPS_FACTORIES = {
|
|
|
48775
48872
|
* running, which the app watches from somewhere else; never for one holding
|
|
48776
48873
|
* an answer the screen is the only place to read (see
|
|
48777
48874
|
* docs/interactions.md#the-fourth-question-whose-wait-is-it).
|
|
48875
|
+
* @param {boolean} [optimistic] The action is taken as done on the button's own
|
|
48876
|
+
* word: no busy state, a second press queues behind the run, and its
|
|
48877
|
+
* `command` runs at once — the popup it sits in closes over the run, which
|
|
48878
|
+
* goes on behind. A failure then has no popup to be read in: `resetOnError`
|
|
48879
|
+
* puts the button back and the error callout is drawn on what surrounds the
|
|
48880
|
+
* closed popup (see docs/popup_open.md#the-popup-owns-its-open-state).
|
|
48778
48881
|
* @param {boolean} [actionAbortable] The person waiting may give up on this
|
|
48779
48882
|
* button's action: closing the popup the run holds calls it off and goes
|
|
48780
48883
|
* through, instead of being refused. For a run whose answer may never come —
|
|
@@ -59662,7 +59765,7 @@ const useDialogProps = props => {
|
|
|
59662
59765
|
bottom: false,
|
|
59663
59766
|
left: false
|
|
59664
59767
|
};
|
|
59665
|
-
if (
|
|
59768
|
+
if (isZeroSpacingSize(marginWithContainer)) {
|
|
59666
59769
|
const {
|
|
59667
59770
|
y,
|
|
59668
59771
|
x
|