staffa 0.18.0 → 0.18.2

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.
@@ -180,8 +180,8 @@ export interface MainOptions<R = Routes> {
180
180
  * How many panels are *shown* at a time. `"auto"` (the default) shows as
181
181
  * many columns, side by side, as comfortably fit, ending at the current
182
182
  * panel; `"single"` shows only the current panel, however wide the screen
183
- * — one screen at a time at every size, each still at its asked width,
184
- * centred (the nav sidebar still sits beside it). Only the display
183
+ * — one screen at a time at every size, each still at its asked width
184
+ * (the nav sidebar still sits beside it). Only the display
185
185
  * differs: the stack, the breadcrumbs, the URL, Escape and the back
186
186
  * button behave identically in both. Routed mode only.
187
187
  *
@@ -7,7 +7,7 @@ import { drawMenu, isFloatingMenuOpen, consumeBranchNav, anyCurrent, registerMen
7
7
  import { menu as menuIcon, x as closeIcon } from "../icons.js";
8
8
  import { iconButton } from "./button.js";
9
9
  import { isDialogOpen } from "./dialog.js";
10
- import { PanelStackController, SMALL_MAX_PX } from "./panels.js";
10
+ import { PAGE_MS, PanelStackController, SMALL_MAX_PX } from "./panels.js";
11
11
  /** The default nav column, hairline included — see {@link MainOptions.navWidth}. */
12
12
  const NAV_W = 200;
13
13
  A.insertGlobalCss({
@@ -66,7 +66,7 @@ A.insertGlobalCss({
66
66
  // — past the viewport edge. The transition is dormant except for the
67
67
  // incoming half of the nav-panel hand-off (see `slideContentIn`).
68
68
  ".s-body main": "flex:1 min-width:0 min-height:0 overflow-x:hidden overflow-y:auto display:flex flex-direction:column " +
69
- "transition: transform var(--s-panel-ms) ease;",
69
+ `transition: transform ${PAGE_MS}ms ease;`,
70
70
  // A one-shot starting position: parked one screen to the right, with the
71
71
  // transition off so it snaps there. Removing the class animates it home.
72
72
  ".s-body main.s-slide-in": "transform: translateX(100%); transition:none",
@@ -95,14 +95,16 @@ A.insertGlobalCss({
95
95
  // Under the sticky header's 10: they never overlap, but the bar should win.
96
96
  "position:absolute inset:0 z-index:5 display:flex flex-direction:column " +
97
97
  "overflow-y:auto overscroll-behavior:contain border:0 r:0 padding:$2 gap:$1 " +
98
- "transition: transform var(--s-panel-ms) ease, visibility 0s;",
98
+ `transition: transform ${PAGE_MS}ms ease, visibility 0s;`,
99
99
  // Parked one screen left: what the `create=`/`destroy=` hooks transition out
100
100
  // of and back into. On dismissal (this rule's transition) `visibility` flips
101
- // only at the slide's end, so the dismissed page isn't reachable while it
102
- // waits for Aberdeen's removal timer; on entry it flips instantly (the `0s`
103
- // above), or the opening page would refuse the focus handed to it mid-slide.
101
+ // only at the slide's end a delayed zero-length transition, whose constant
102
+ // start value costs nothing per frame so the dismissed page isn't
103
+ // reachable while it waits for Aberdeen's removal timer; on entry it flips
104
+ // instantly (the `0s` above), or the opening page would refuse the focus
105
+ // handed to it mid-slide.
104
106
  "&.s-nav-page-off": "transform:translateX(-100%) pointer-events:none visibility:hidden " +
105
- "transition: transform var(--s-panel-ms) ease, visibility var(--s-panel-ms);",
107
+ `transition: transform ${PAGE_MS}ms ease, visibility 0s ${PAGE_MS}ms;`,
106
108
  // Roomier than the dropdown's: every row here is a thumb target.
107
109
  ".s-menu-item": "padding: $2 $3; min-height:3rem font-size:1.05em gap:$3",
108
110
  },
@@ -175,7 +175,7 @@ export interface Panel<P = Record<string, string | number | string[]>> {
175
175
  * Every size is capped at the content area, so on a phone they all come to
176
176
  * the same thing: one screen at a time. And a width depends only on the
177
177
  * window, never on what else is open, so opening or closing a panel never
178
- * resizes another — the run of columns just recentres in the area.
178
+ * resizes another — the run of columns just shifts over in the area.
179
179
  *
180
180
  * The ask is a ceiling only; there is no matching floor, since the window can
181
181
  * be any width. Aim your layout at 360px — about the narrowest phone still in
@@ -193,10 +193,11 @@ export interface Panel<P = Record<string, string | number | string[]>> {
193
193
  maxWidth?: PanelSize;
194
194
  /**
195
195
  * Set this while you're fetching what the panel needs, and back to `false`
196
- * when you're done. A new panel waits a moment before sliding in, so it can
197
- * arrive with real content instead of empty; if the wait drags on it slides
198
- * in anyway and shows a loading indicator until the flag clears. It only
199
- * affects the animation; the stack and the URL never wait for it.
196
+ * when you're done. A new panel slides into place right away but waits a
197
+ * moment before fading in, so it can appear with real content instead of
198
+ * empty; if the wait drags on it fades in anyway and shows a loading
199
+ * indicator until the flag clears. It only affects the animation; the
200
+ * stack and the URL never wait for it.
200
201
  */
201
202
  loading?: boolean;
202
203
  /**
@@ -286,6 +287,13 @@ export interface Panel<P = Record<string, string | number | string[]>> {
286
287
  */
287
288
  open(href: string, how?: "push" | "replace" | "open"): Promise<boolean>;
288
289
  }
290
+ /**
291
+ * The one duration every bit of shell motion shares: the enter/exit fades, the
292
+ * slides, the narrow-screen nav slide. Interpolated into every transition as a
293
+ * literal — the shared constant is what keeps CSS and JS in step — and also
294
+ * published as the `--s-panel-ms` custom property for app CSS.
295
+ */
296
+ export declare const PAGE_MS = 250;
289
297
  export declare const SMALL_MAX_PX = 540;
290
298
  /** Options the stack needs from its shell. */
291
299
  export interface PanelStackOptions {
@@ -452,6 +460,8 @@ export declare class PanelStackController implements PanelStack {
452
460
  private lastGeom?;
453
461
  private layoutQueued;
454
462
  private timers;
463
+ /** Elements playing their exit fade, each riding its anchor's motion (see `layout`). */
464
+ private exiting;
455
465
  /** The arrangement the navigation in flight is heading for; see {@link intended}. */
456
466
  private intent;
457
467
  /** The navigation the router hasn't settled yet, if any. */
@@ -529,13 +539,21 @@ export declare class PanelStackController implements PanelStack {
529
539
  */
530
540
  private beginClose;
531
541
  /**
532
- * A closed panel's send-off, run by Aberdeen once its scope is gone: it fades
533
- * where it stands, inert, and leaves the DOM on `transitionend`. A fixed timer
534
- * would race the transition and pull the element a frame early, making the
535
- * panel appear to fade half-way and vanish; the timeout is only a fallback for
536
- * when no `transitionend` is coming (transitions off, element never placed).
542
+ * A closed panel's send-off, run by Aberdeen once its scope is gone: it fades,
543
+ * inert, riding its anchor's slide (see `layout`), and leaves the DOM once
544
+ * the fade is over (see {@link afterFade}).
537
545
  */
538
546
  private playExit;
547
+ /**
548
+ * Run `done` once `el`'s transition of `prop` is over. The real signal is
549
+ * `transitionend` — or `transitioncancel`, for one a resize snaps short —
550
+ * so the transition's actual length rules, however long: DevTools' slowed
551
+ * animations stretch it tenfold without touching any timer. The timer only
552
+ * stands in for a transition that never starts at all (transitions off,
553
+ * element never placed, nothing to travel), which is why one proving real
554
+ * (`transitionrun`) disarms it.
555
+ */
556
+ private afterTransition;
539
557
  /**
540
558
  * The arrangement navigation works from: the one we're on the way to while a
541
559
  * change is still settling, the one on screen otherwise. That window is common
@@ -701,7 +719,9 @@ export declare class PanelStackController implements PanelStack {
701
719
  * The motion between two such arrangements is CSS's job.
702
720
  */
703
721
  private layout;
704
- /** Let a `loading` panel's enter animation wait but not indefinitely. */
722
+ /** Start (or skip) a newcomer's fade-in; any slide is already underway. */
723
+ private releaseEnter;
724
+ /** Let a `loading` panel's fade-in wait — but not indefinitely. */
705
725
  private holdEnter;
706
726
  }
707
727
  export {};