UI: drop tab-bar tap highlight; don't slide the first screen on launch #45
+12
-3
@@ -32,8 +32,9 @@
|
||||
|
||||
// Screen transitions: the lobby is the navigation root. Entering a screen from the
|
||||
// lobby slides it in from the right (forward); returning to the lobby slides the
|
||||
// screen out to the right and reveals the lobby (back). Transitions are local, so
|
||||
// they do not play on the initial mount, and collapse to nothing under reduce-motion.
|
||||
// screen out to the right and reveals the lobby (back). The first pane shown after boot
|
||||
// does not slide (the `started` gate below), and transitions collapse to nothing under
|
||||
// reduce-motion.
|
||||
// Slide direction by route depth: going deeper (lobby → game → chat/check) slides forward,
|
||||
// returning to a shallower screen slides back. A plain "lobby is back" rule slid the chat/check
|
||||
// back-to-the-game the wrong way. dir is read with the previous depth (the effect updates it
|
||||
@@ -52,7 +53,15 @@
|
||||
const enterSign = $derived(dir === 'forward' ? 1 : -1);
|
||||
const leaveSign = $derived(dir === 'forward' ? -1 : 1);
|
||||
const routeKey = $derived(router.route.name + (router.route.params.id ?? ''));
|
||||
const animMs = $derived(app.reduceMotion ? 0 : 260);
|
||||
// The first pane shown once the app is ready must not slide: it would look like the app
|
||||
// was navigated into rather than launched. The pane is a local transition inside a {#key}
|
||||
// block, so it plays on that block's own first mount anyway — hold the duration at 0 until
|
||||
// just after that mount (the effect runs post-render), then animate every later change.
|
||||
let started = $state(false);
|
||||
$effect(() => {
|
||||
if (app.ready) started = true;
|
||||
});
|
||||
const animMs = $derived(!started || app.reduceMotion ? 0 : 260);
|
||||
|
||||
// slideX slides a pane horizontally by a full width. sign>0 enters from / exits to
|
||||
// the right; sign<0 the left. Percentage keeps it viewport-relative without reading
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
width: 100%;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-webkit-tap-highlight-color: transparent; /* no WebKit flash on tap */
|
||||
}
|
||||
:global(.tab:disabled) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
/* The icon square hugs the emoji (just a little padding) so it is the press-highlight
|
||||
target and the badge can sit on its corner. */
|
||||
/* The icon square hugs the emoji (just a little padding) so the badge can sit on its
|
||||
corner. */
|
||||
:global(.tab .sq) {
|
||||
position: relative;
|
||||
display: inline-grid;
|
||||
@@ -50,12 +51,9 @@
|
||||
line-height: 1;
|
||||
transition: background-color 0.12s;
|
||||
}
|
||||
:global(.tab:active:not(:disabled) .sq) {
|
||||
background: var(--surface-2);
|
||||
}
|
||||
/* A tab that navigates between peer views (Settings / Comms hubs) stays highlighted
|
||||
while selected: a filled square with an accent underline, distinct from the
|
||||
momentary press tint above. */
|
||||
while selected: a filled square with an accent underline. A tap itself leaves no
|
||||
highlight — there is no press tint, and the WebKit tap flash is disabled on .tab. */
|
||||
:global(.tab.active .sq) {
|
||||
background: var(--surface-2);
|
||||
box-shadow: inset 0 -2px 0 var(--accent);
|
||||
|
||||
Reference in New Issue
Block a user