mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-04 08:57:00 +01:00
ui: share view in the shell, icon rail, phone polish
- shared view uses the bar, porthole and status band; outline gets its own window on wide screens; j/k, gg/G, Ctrl-d/u scroll with a vim-style ruler - rail doors are line icons in groups with hover tooltips and keycaps - phone: number-only space pills, no nested rims, icon dock, toast messages, back button and one-line meta in the document header - keycaps (.kbd) wherever keys are shown, styled scrollbars in Chrome, outline tracks position on jumps, breakpoints unified at 767px
This commit is contained in:
1 parent
9391b10af1
commit
ecfbab0eaa
14 files changed
+796
-382
No files matched your search
+15
-93
@@ -5,20 +5,13 @@
|
||||
* the clock. Spaces and crumbs are clickable, because a tree is the one thing
|
||||
* that is genuinely faster to walk with a pointer than with `:cd`.
|
||||
*/
|
||||
import Clock from './Clock.svelte'
|
||||
import { hooks } from './commands'
|
||||
import { workspace } from './store.svelte'
|
||||
|
||||
// The space is the first crumb, and it is already named by its pill.
|
||||
const crumbs = $derived(workspace.path.slice(1))
|
||||
|
||||
let now = $state(new Date())
|
||||
$effect(() => {
|
||||
const timer = setInterval(() => (now = new Date()), 10_000)
|
||||
return () => clearInterval(timer)
|
||||
})
|
||||
const clock = $derived(
|
||||
now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }),
|
||||
)
|
||||
</script>
|
||||
|
||||
<header class="bar">
|
||||
@@ -33,7 +26,7 @@
|
||||
title="{space.name} ({index < 10 ? (index + 1) % 10 : ''})"
|
||||
onclick={() => workspace.guard(() => workspace.enterSpace(space.id))}
|
||||
>
|
||||
{#if index < 10}<span class="n">{(index + 1) % 10}</span>{/if}{space.slug}
|
||||
{#if index < 10}<span class="n">{(index + 1) % 10}</span>{/if}<span class="slug">{space.slug}</span>
|
||||
</button>
|
||||
{/each}
|
||||
<button class="pill add" title="new space (:space! <name>)" onclick={() => hooks.openCommandLine(':space! ')}>
|
||||
@@ -74,50 +67,10 @@
|
||||
<span class="value">{workspace.user}</span>
|
||||
</span>
|
||||
<span class="divider wide"></span>
|
||||
<time class="clock">{clock}</time>
|
||||
<Clock />
|
||||
</header>
|
||||
|
||||
<style>
|
||||
.bar {
|
||||
position: absolute;
|
||||
inset: 0 0 auto 0;
|
||||
height: var(--bar-h);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 0 calc(var(--rail-w) + 4px) 0 calc(var(--frame) + 10px);
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--subtle);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* A ring with a dot in it: the favicon, and the desktop's launcher. */
|
||||
.mark {
|
||||
position: relative;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
flex: none;
|
||||
border: 1.5px solid var(--light);
|
||||
border-radius: 999px;
|
||||
}
|
||||
.mark::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 2px;
|
||||
border-radius: 999px;
|
||||
background: var(--light);
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 1px;
|
||||
height: 14px;
|
||||
flex: none;
|
||||
background: var(--overlay);
|
||||
}
|
||||
|
||||
.spaces, .crumbs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -129,35 +82,10 @@
|
||||
.spaces { flex: none; max-width: 50%; }
|
||||
.crumbs { flex: 0 1 auto; }
|
||||
|
||||
/* Workspace pills: muted at rest, light on hover, inverted when current. */
|
||||
/* The focused pill widens, as the desktop's does, over the slow duration. */
|
||||
.pill {
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-width: 22px;
|
||||
height: 20px;
|
||||
padding: 0 6px;
|
||||
transition:
|
||||
padding var(--t-slow) var(--ease-snap),
|
||||
background-color var(--t-base) var(--ease-glide),
|
||||
color var(--t-base) var(--ease-glide);
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: none;
|
||||
color: var(--muted);
|
||||
background: transparent;
|
||||
}
|
||||
.pill:hover { background: transparent; color: var(--light); }
|
||||
.pill[aria-current='true'] { background: var(--light); color: var(--ink); padding: 0 12px; }
|
||||
.n { color: var(--overlay); font-size: 10px; }
|
||||
.pill:hover .n { color: var(--muted); }
|
||||
.n { color: var(--muted); font-size: 10px; }
|
||||
.pill:hover .n { color: var(--light-dim); }
|
||||
.pill[aria-current='true'] .n { color: var(--ink); opacity: 0.55; }
|
||||
.pill:focus-visible { background: var(--light); color: var(--ink); }
|
||||
.pill.add { color: var(--overlay); }
|
||||
.pill.add { color: var(--muted); }
|
||||
.pill.add:hover { color: var(--light); }
|
||||
|
||||
/* A crumb is a link along the path; a hairline grows under it on hover. */
|
||||
@@ -190,21 +118,15 @@
|
||||
.sep { color: var(--overlay); }
|
||||
span.here { letter-spacing: 0.06em; text-transform: none; }
|
||||
|
||||
.spacer { flex: 1; }
|
||||
|
||||
.readout { display: flex; gap: 8px; font-variant-numeric: tabular-nums; }
|
||||
.key { color: var(--muted); }
|
||||
.value { color: var(--fg); text-transform: none; letter-spacing: 0.06em; }
|
||||
|
||||
.clock {
|
||||
color: var(--light);
|
||||
letter-spacing: 0.12em;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/*
|
||||
* On a phone the other spaces are only their number, like the desktop's
|
||||
* workspace dots, so all of them fit; the current one keeps its name.
|
||||
*/
|
||||
@media (max-width: 767px) {
|
||||
.bar { padding-left: 12px; padding-right: 12px; gap: 10px; }
|
||||
.crumbs, .divider.path, .user, .divider.wide { display: none; }
|
||||
.spaces { max-width: none; flex: 1; }
|
||||
.crumbs, .divider.path, .bar .user, .divider.wide { display: none; }
|
||||
.spaces { max-width: none; flex: 0 1 auto; gap: 2px; }
|
||||
.pill:not([aria-current='true']) .slug { display: none; }
|
||||
.pill:not([aria-current='true']) { min-width: 28px; height: 24px; }
|
||||
.pill:not([aria-current='true']) .n { font-size: 11px; color: var(--subtle); }
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user