feat(keys): vim keys in any layout, z motions, no Option chords
Keys on a non-Latin layout map to their physical US position, so j, k, gg and / work on the Russian layout. Lists get z z, z t, z b, and the first row scrolls the page to the top. The editor drops Alt chords for Esc then a letter, reorder in groups, piggy banks and subscriptions moves to J and K.
This commit is contained in:
1 parent
63a1971900
commit
a1e7489ad4
9 files changed
+132
-94
No files matched your search
@@ -52,15 +52,15 @@
|
||||
withdrawal: "withdrawal",
|
||||
};
|
||||
const FIELDS: [string, string, string][] = [
|
||||
["alt+d", "description", "description"],
|
||||
["alt+f", "source", "source account"],
|
||||
["alt+t", "destination", "destination account"],
|
||||
["alt+w", "date", "date"],
|
||||
["alt+m", "amount", "amount"],
|
||||
["alt+k", "category", "category"],
|
||||
["alt+b", "budget", "budget"],
|
||||
["alt+g", "tags", "tags"],
|
||||
["alt+r", "notes", "notes"],
|
||||
["d", "description", "description"],
|
||||
["f", "source", "source account"],
|
||||
["t", "destination", "destination account"],
|
||||
["w", "date", "date"],
|
||||
["m", "amount", "amount"],
|
||||
["c", "category", "category"],
|
||||
["b", "budget", "budget"],
|
||||
["#", "tags", "tags"],
|
||||
["r", "notes", "notes"],
|
||||
];
|
||||
const INLINE = new Set([
|
||||
"description",
|
||||
@@ -104,6 +104,7 @@
|
||||
const originalType = start.type;
|
||||
|
||||
let form = $state<Form>(start);
|
||||
let lastSplit = start.splits[0].key;
|
||||
let saved = $state(untrack(() => group));
|
||||
let snapshot = JSON.stringify(start);
|
||||
let errors = $state<Errors>({});
|
||||
@@ -204,9 +205,17 @@
|
||||
tick().then(() => focusField("description", false));
|
||||
});
|
||||
|
||||
function splitOf(target: EventTarget | null): number | null {
|
||||
const holder =
|
||||
target instanceof Element ? target.closest("[data-split]") : null;
|
||||
return holder ? Number(holder.getAttribute("data-split")) : null;
|
||||
}
|
||||
|
||||
function currentKey(): number {
|
||||
const holder = document.activeElement?.closest("[data-split]");
|
||||
return Number(holder?.getAttribute("data-split") ?? form.splits[0].key);
|
||||
const key = splitOf(document.activeElement) ?? lastSplit;
|
||||
return form.splits.some((split) => split.key === key)
|
||||
? key
|
||||
: form.splits[0].key;
|
||||
}
|
||||
|
||||
function focusField(field: string, select = true) {
|
||||
@@ -452,29 +461,25 @@
|
||||
},
|
||||
{
|
||||
group: "Editor",
|
||||
input: true,
|
||||
keys: "mod+alt+Backspace",
|
||||
keys: "X",
|
||||
label: "Remove the current split",
|
||||
run: () => removeSplit(),
|
||||
},
|
||||
...TX_TYPES.map((type, index) => ({
|
||||
group: "Editor",
|
||||
input: true,
|
||||
keys: `alt+${index + 1}`,
|
||||
keys: `${index + 1}`,
|
||||
label: `Make it a ${type}`,
|
||||
run: () => setType(type),
|
||||
})),
|
||||
...FIELDS.map(([keys, field, label]) => ({
|
||||
group: "Editor",
|
||||
input: true,
|
||||
keys,
|
||||
label: `Go to ${label}`,
|
||||
run: () => focusField(field),
|
||||
})),
|
||||
{
|
||||
group: "Editor",
|
||||
input: true,
|
||||
keys: "alt+i",
|
||||
keys: "T",
|
||||
label: "Go to the split transaction title",
|
||||
run: () => document.getElementById("group-title")?.focus(),
|
||||
},
|
||||
@@ -520,7 +525,11 @@
|
||||
{/snippet}
|
||||
</PageHeader>
|
||||
|
||||
<div class="flex flex-col gap-4" bind:this={root}>
|
||||
<div
|
||||
class="flex flex-col gap-4"
|
||||
onfocusin={(event) => (lastSplit = splitOf(event.target) ?? lastSplit)}
|
||||
bind:this={root}
|
||||
>
|
||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2">
|
||||
<div
|
||||
aria-label="Transaction type"
|
||||
@@ -540,9 +549,7 @@
|
||||
type="button"
|
||||
>
|
||||
{TYPE_LABEL[type]}
|
||||
<span class="kbd hidden lg:inline-flex"
|
||||
>{prettyKeys(`alt+${index + 1}`)[0]}</span
|
||||
>
|
||||
<span class="kbd hidden lg:inline-flex">{index + 1}</span>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -614,7 +621,7 @@
|
||||
<Field
|
||||
error={errors.group_title?.[0]}
|
||||
for="group-title"
|
||||
keys="alt+i"
|
||||
keys="T"
|
||||
label="Description of the split transaction"
|
||||
>
|
||||
<input
|
||||
|
||||
Reference in new issue
Block a user