@jsenv/navi 0.29.75 → 0.29.76
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/jsenv_navi.js +81 -8
- package/dist/jsenv_navi.js.map +6 -6
- package/docs/AI_INSTRUCTIONS.md +11 -0
- package/docs/dialog_shape.md +223 -0
- package/docs/z_index.md +35 -9
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -60,7 +60,9 @@ const css$12 = /* css */`
|
|
|
60
60
|
what the page positioned itself, which loses to DOM order otherwise
|
|
61
61
|
(a sticky part is written before what scrolls under it). Box applies
|
|
62
62
|
it by default, isolated, and lets a call site write auto back:
|
|
63
|
-
--box-header-z-index / --box-footer-z-index.
|
|
63
|
+
--box-header-z-index / --box-footer-z-index. <Box sticky> gets it from
|
|
64
|
+
the prop itself, for the same reason and with the same way out (an
|
|
65
|
+
explicit zIndex, "auto" included).
|
|
64
66
|
|
|
65
67
|
"While stuck" is the condition the name states, and it costs something
|
|
66
68
|
to ignore: a sticky part at rest is a block in the flow with nothing
|
|
@@ -16935,6 +16937,28 @@ const DIMENSION_PROPS = {
|
|
|
16935
16937
|
return { transform: `scaleZ(${value})` };
|
|
16936
16938
|
},
|
|
16937
16939
|
};
|
|
16940
|
+
const applyPositionSticky = applyToCssPropWhenTruthy(
|
|
16941
|
+
"position",
|
|
16942
|
+
"sticky",
|
|
16943
|
+
"static",
|
|
16944
|
+
);
|
|
16945
|
+
// A sticky box is one something scrolls under, which is what
|
|
16946
|
+
// --navi-z-index-sticky names; without it the box is a positioned element at
|
|
16947
|
+
// z-index: auto and loses to anything the page raised — a Group member holding
|
|
16948
|
+
// focus (2) is seen passing in front of a sticky submit bar. Like Box's own
|
|
16949
|
+
// header/footer, the band applies always and not only while stuck: a box
|
|
16950
|
+
// written by an app is the generic case, it cannot read its own stuck state
|
|
16951
|
+
// (see docs/z_index.md), and dropping to auto loses to a single
|
|
16952
|
+
// position: relative. An explicit zIndex (including zIndex="auto") wins.
|
|
16953
|
+
const stickyZIndex = (styleContext) => {
|
|
16954
|
+
if (
|
|
16955
|
+
styleContext.styles.zIndex !== undefined ||
|
|
16956
|
+
styleContext.remainingProps.zIndex !== undefined
|
|
16957
|
+
) {
|
|
16958
|
+
return null;
|
|
16959
|
+
}
|
|
16960
|
+
return { zIndex: "var(--navi-z-index-sticky)" };
|
|
16961
|
+
};
|
|
16938
16962
|
const POSITION_PROPS = {
|
|
16939
16963
|
// For row, selfAlignX uses auto margins for positioning
|
|
16940
16964
|
// NOTE: Auto margins only work effectively for positioning individual items.
|
|
@@ -17002,11 +17026,22 @@ const POSITION_PROPS = {
|
|
|
17002
17026
|
}
|
|
17003
17027
|
return undefined;
|
|
17004
17028
|
},
|
|
17005
|
-
position:
|
|
17029
|
+
position: (value, styleContext) => {
|
|
17030
|
+
if (value === "sticky") {
|
|
17031
|
+
return { position: "sticky", ...stickyZIndex(styleContext) };
|
|
17032
|
+
}
|
|
17033
|
+
return { position: value };
|
|
17034
|
+
},
|
|
17006
17035
|
absolute: applyToCssPropWhenTruthy("position", "absolute", "static"),
|
|
17007
17036
|
relative: applyToCssPropWhenTruthy("position", "relative", "static"),
|
|
17008
17037
|
fixed: applyToCssPropWhenTruthy("position", "fixed", "static"),
|
|
17009
|
-
sticky:
|
|
17038
|
+
sticky: (value, styleContext) => {
|
|
17039
|
+
const positionStyles = applyPositionSticky(value, styleContext);
|
|
17040
|
+
if (!value) {
|
|
17041
|
+
return positionStyles;
|
|
17042
|
+
}
|
|
17043
|
+
return { ...positionStyles, ...stickyZIndex(styleContext) };
|
|
17044
|
+
},
|
|
17010
17045
|
zIndex: PASS_THROUGH,
|
|
17011
17046
|
// Keeps the zIndex values used inside this box local to it — see
|
|
17012
17047
|
// docs/z_index.md: a z-index that opens no stacking context competes with
|
|
@@ -30219,6 +30254,24 @@ const css$X = /* css */`
|
|
|
30219
30254
|
outline-color: var(--dialog-outline-color);
|
|
30220
30255
|
outline-offset: 0;
|
|
30221
30256
|
box-shadow: var(--dialog-box-shadow);
|
|
30257
|
+
|
|
30258
|
+
/* Docking answers a different question than --dialog-max-width: a sheet
|
|
30259
|
+
spans its container's full width, flush against the two side edges —
|
|
30260
|
+
that shape IS the mode — while the caller's ceiling was an answer about
|
|
30261
|
+
the *centered* box ("do not sprawl on a wide window"). Applying it here
|
|
30262
|
+
turns the sheet into a small floating box that no longer touches the
|
|
30263
|
+
edges it was docked to, so it is dropped out of the clamp entirely; the
|
|
30264
|
+
container ceiling still holds. --dialog-min-width needs no such rule:
|
|
30265
|
+
the floor is below the full width a docked dialog takes, so it stops
|
|
30266
|
+
mattering on its own. Height is untouched — a sheet is content-tall, not
|
|
30267
|
+
container-tall (expandY cancels docking outright), so --dialog-max-height
|
|
30268
|
+
still means what it meant. */
|
|
30269
|
+
&[data-docked] {
|
|
30270
|
+
--x-dialog-max-width: min(
|
|
30271
|
+
var(--container-position-remaining-width, var(--dialog-maxmax-width)),
|
|
30272
|
+
var(--dialog-maxmax-width)
|
|
30273
|
+
);
|
|
30274
|
+
}
|
|
30222
30275
|
/* The clamped max, not --dialog-maxmax-*: that one is the viewport minus
|
|
30223
30276
|
the spacing, which is only the real ceiling for layer="top". A local
|
|
30224
30277
|
dialog is confined to its positioned ancestor, whose size reaches here
|
|
@@ -30459,7 +30512,15 @@ const css$X = /* css */`
|
|
|
30459
30512
|
* from where the finger just tapped, and size alone would dock a narrow
|
|
30460
30513
|
* desktop window, which is still a mouse. It supplies defaults for
|
|
30461
30514
|
* `positionArea`, `marginWithContainer`, `expandX` and `scrollCapture`, so
|
|
30462
|
-
* any of them can still be pinned explicitly
|
|
30515
|
+
* any of them can still be pinned explicitly — including `expandX={false}`,
|
|
30516
|
+
* which opts the docked dialog out of the full-width stretch and leaves it a
|
|
30517
|
+
* floating box at the bottom. It also withdraws `maxWidth` while docked: a
|
|
30518
|
+
* sheet is container-wide by definition, and a `maxWidth` is an answer about
|
|
30519
|
+
* the *centered* shape, so the two can be stated together (`maxWidth="16rem"
|
|
30520
|
+
* dockedOnSmallTouchScreen`) and each applies where it means something.
|
|
30521
|
+
* `minWidth` needs no such rule — its floor is below the full width — and
|
|
30522
|
+
* `maxHeight`/`minHeight` keep applying, a sheet being content-tall.
|
|
30523
|
+
* Ignored entirely when `expandY`
|
|
30463
30524
|
* (or `expand`) is set: a dialog already filling the height is on the bottom
|
|
30464
30525
|
* edge docking would bring it to, so docking could only take away the shape
|
|
30465
30526
|
* the caller asked for. Re-resolves live as the pointer
|
|
@@ -30481,7 +30542,10 @@ const css$X = /* css */`
|
|
|
30481
30542
|
* @param {boolean} [props.expand] - Shorthand for both `expandX` and `expandY`.
|
|
30482
30543
|
* @param {boolean} [props.expandX] - Stretches the dialog to the full width its
|
|
30483
30544
|
* container allows (`--dialog-maxmax-width`). Set by
|
|
30484
|
-
* `dockedOnSmallTouchScreen` on a small touch screen
|
|
30545
|
+
* `dockedOnSmallTouchScreen` on a small touch screen — so passing `false`
|
|
30546
|
+
* here also opts out of *that* stretch, leaving a docked dialog a floating
|
|
30547
|
+
* box instead of a flush sheet. To keep the sheet flush and merely cap the
|
|
30548
|
+
* centered shape, use `maxWidth`: docking withdraws it on its own.
|
|
30485
30549
|
* @param {boolean} [props.expandY] - Same, vertically
|
|
30486
30550
|
* (`--dialog-maxmax-height`). Cancels `dockedOnSmallTouchScreen`.
|
|
30487
30551
|
* @param {string|number} [props.marginWithContainer="3appw"] - Minimum gap kept
|
|
@@ -30540,7 +30604,9 @@ const css$X = /* css */`
|
|
|
30540
30604
|
* so it can never push the dialog past `--dialog-maxmax-width` (the
|
|
30541
30605
|
* viewport/container-spacing ceiling) regardless of how large a value is
|
|
30542
30606
|
* passed.
|
|
30543
|
-
* @param {string} [props.maxWidth] - Maps to `--dialog-max-width`.
|
|
30607
|
+
* @param {string} [props.maxWidth] - Maps to `--dialog-max-width`. Describes
|
|
30608
|
+
* the centered shape only: a dialog docked by `dockedOnSmallTouchScreen`
|
|
30609
|
+
* ignores it and stays container-wide.
|
|
30544
30610
|
* @param {string} [props.minHeight] - Maps to `--dialog-min-height`, same
|
|
30545
30611
|
* clamping as `minWidth`.
|
|
30546
30612
|
* @param {string} [props.maxHeight] - Maps to `--dialog-max-height`.
|
|
@@ -31458,6 +31524,10 @@ const useDialogProps = props => {
|
|
|
31458
31524
|
// scrolling area, so it says so once, here.
|
|
31459
31525
|
"overflow": "auto",
|
|
31460
31526
|
"data-layer": layer,
|
|
31527
|
+
// The sheet shape is live in CSS, not just a set of resolved defaults:
|
|
31528
|
+
// it is what withdraws the caller's --dialog-max-width (see the stylesheet
|
|
31529
|
+
// above), which is an answer about the centered box only.
|
|
31530
|
+
"data-docked": isDocked ? "" : undefined,
|
|
31461
31531
|
"data-expand-x": expandX ? "" : undefined,
|
|
31462
31532
|
"data-expand-y": expandY ? "" : undefined,
|
|
31463
31533
|
"data-flush-top": flushEdges.top ? "" : undefined,
|
|
@@ -65867,6 +65937,8 @@ const css$l = /* css */`
|
|
|
65867
65937
|
* positionArea?: string,
|
|
65868
65938
|
* popupWidthFitContent?: boolean,
|
|
65869
65939
|
* popoverMaxHeight?: number | string,
|
|
65940
|
+
* dialogMinWidth?: number | string,
|
|
65941
|
+
* dialogMinHeight?: number | string,
|
|
65870
65942
|
* dialogMaxWidth?: number | string,
|
|
65871
65943
|
* dialogMaxHeight?: number | string,
|
|
65872
65944
|
* dialogExpand?: boolean,
|
|
@@ -65916,7 +65988,8 @@ const css$l = /* css */`
|
|
|
65916
65988
|
* popover; a dialog keeps Dialog's own "center".
|
|
65917
65989
|
*
|
|
65918
65990
|
* Every other prop the Picker's popup answers to is forwarded as-is —
|
|
65919
|
-
* `dockedOnSmallTouchScreen`, `dialogExpand*`, `
|
|
65991
|
+
* `dockedOnSmallTouchScreen`, `dialogExpand*`, `dialogMinWidth`/`Height`,
|
|
65992
|
+
* `dialogMaxWidth`/`Height`,
|
|
65920
65993
|
* `marginWithContainer`, `popoverMode`, `popoverSpacing`, `popupLayer`,
|
|
65921
65994
|
* `popupWidthFitContent`, `popoverMaxHeight`, `backdropVariant`,
|
|
65922
65995
|
* `pointerInteractionOutsideEffect`, `escapeEffect`, `closeOnFocusOut`,
|
|
@@ -66121,7 +66194,7 @@ const SplitButton = props => {
|
|
|
66121
66194
|
// What the Picker's popup answers to — Picker's own popup props, named here so
|
|
66122
66195
|
// a caller reaches all of them through the split button (see picker.jsx's JSDoc
|
|
66123
66196
|
// for what each one says).
|
|
66124
|
-
const POPUP_PROP_SET = new Set(["mode", "popupLayer", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdropVariant", "pointerInteractionOutsideEffect", "escapeEffect", "closeOnFocusOut", "scrollCapture", "focusCapture", "popupBackgroundColor", "popupBorderRadius", "animation"]);
|
|
66197
|
+
const POPUP_PROP_SET = new Set(["mode", "popupLayer", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMinWidth", "dialogMinHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdropVariant", "pointerInteractionOutsideEffect", "escapeEffect", "closeOnFocusOut", "scrollCapture", "focusCapture", "popupBackgroundColor", "popupBorderRadius", "animation"]);
|
|
66125
66198
|
const splitPopupProps = props => {
|
|
66126
66199
|
const popupProps = {};
|
|
66127
66200
|
const boxProps = {};
|