feat(*): one task editor, vim navigation and undo
This commit is contained in:
1 parent
0873cbb366
commit
83ca32d98e
37 files changed
+4043
-505
No files matched your search
@@ -0,0 +1,105 @@
|
||||
<script lang="ts">
|
||||
import { fade, fly } from "svelte/transition";
|
||||
import { cubicOut } from "svelte/easing";
|
||||
import { GROUPS, SHORTCUTS } from "../lib/keymap";
|
||||
import type { Group } from "../lib/keymap";
|
||||
import { useView } from "./context";
|
||||
|
||||
const view = useView();
|
||||
const store = view.store;
|
||||
|
||||
function close(): void {
|
||||
store.helpOpen = false;
|
||||
}
|
||||
|
||||
function grab(node: HTMLElement) {
|
||||
node.focus({ preventScroll: true });
|
||||
return { destroy: () => view.focusRoot() };
|
||||
}
|
||||
|
||||
function onkeydown(event: KeyboardEvent): void {
|
||||
if (event.key !== "Escape" && event.key !== "?") return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
close();
|
||||
}
|
||||
|
||||
function rows(group: Group) {
|
||||
return SHORTCUTS.filter((shortcut) => shortcut.group === group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only Moving needs the qualifier: it is the one group where the same key
|
||||
* does two things. The other groups say their scope in the heading.
|
||||
*/
|
||||
function scope(shortcut: (typeof SHORTCUTS)[number]): string {
|
||||
if (shortcut.group !== "Moving") return "";
|
||||
if (shortcut.scopes.includes("task")) return "on a task";
|
||||
if (shortcut.scopes.includes("day")) return "on a day";
|
||||
return "";
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="fixed inset-0 z-50 grid place-items-center bg-black/45 p-4 outline-none backdrop-blur-[2px]"
|
||||
onclick={close}
|
||||
{onkeydown}
|
||||
role="presentation"
|
||||
tabindex="-1"
|
||||
transition:fade={{ duration: 120 }}
|
||||
use:grab
|
||||
>
|
||||
<div
|
||||
class="max-h-full w-full max-w-5xl overflow-y-auto rounded-xl border border-border bg-popover text-popover-foreground shadow-[0_24px_64px_-16px_rgb(0_0_0/55%)] @container"
|
||||
onclick={(event) => event.stopPropagation()}
|
||||
onkeydown={() => {}}
|
||||
role="presentation"
|
||||
transition:fly={{ duration: 180, easing: cubicOut, y: 8 }}
|
||||
>
|
||||
<div class="flex items-baseline gap-3 px-5 pt-4 pb-3">
|
||||
<h2 class="font-semibold text-base">Keyboard</h2>
|
||||
<p class="text-muted-foreground text-xs">
|
||||
The vim block reads the physical key, so it answers on a Cyrillic layout too.
|
||||
</p>
|
||||
<button
|
||||
class="ml-auto shrink-0 rounded-md px-2 py-1 text-muted-foreground text-xs outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring"
|
||||
onclick={close}
|
||||
type="button"
|
||||
>
|
||||
esc
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="gap-x-8 px-5 pb-5 @min-[34rem]:columns-2 @min-[58rem]:columns-3">
|
||||
{#each GROUPS as group (group)}
|
||||
<section class="mb-4 min-w-0 break-inside-avoid">
|
||||
<h3
|
||||
class="pb-1.5 font-semibold text-[10px] text-muted-foreground uppercase tracking-[0.09em]"
|
||||
>
|
||||
{group}
|
||||
</h3>
|
||||
<dl class="grid grid-cols-[1fr_auto] items-center gap-x-3">
|
||||
{#each rows(group) as shortcut, index (`${shortcut.label}-${index}`)}
|
||||
<dt
|
||||
class="min-w-0 truncate border-border/40 border-t py-1 text-xs first:border-t-0"
|
||||
title={shortcut.label}
|
||||
>
|
||||
{shortcut.label}
|
||||
{#if scope(shortcut)}
|
||||
<span class="text-muted-foreground/70">{scope(shortcut)}</span>
|
||||
{/if}
|
||||
</dt>
|
||||
<dd
|
||||
class="flex shrink-0 items-center gap-1 border-border/40 border-t py-1 [&:nth-child(2)]:border-t-0"
|
||||
>
|
||||
{#each shortcut.keys as key (key)}
|
||||
<kbd class="kbd">{key}</kbd>
|
||||
{/each}
|
||||
</dd>
|
||||
{/each}
|
||||
</dl>
|
||||
</section>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in new issue
Block a user