zenno/doc/spark: make spark select searchable

This commit is contained in:
2026-07-09 15:40:07 -04:00
parent bc395a0788
commit fca43e64b5
2 changed files with 46 additions and 29 deletions
+22
View File
@@ -144,3 +144,25 @@ export async function sparks(): Promise<Spark[]> {
const resp = await fetch('/api/global/spark'); const resp = await fetch('/api/global/spark');
return resp.json(); return resp.json();
} }
export interface SparkGroup {
spark_group: number;
name: string;
description: string;
type: Type;
effects: Effect[][];
spark_ids: number[];
}
export function byGroup(sparks: Spark[]): SparkGroup[] {
const r = new Map<number, SparkGroup>();
for (const {spark_id, name, description, spark_group, type, effects} of sparks) {
let g = r.get(spark_group);
if (g == null) {
g = {spark_group, name, description, type, effects, spark_ids: []};
r.set(spark_group, g);
}
g.spark_ids.push(spark_id);
}
return [...r.values()];
}
+24 -29
View File
@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import * as skill from '$lib/data/skill'; import * as skill from '$lib/data/skill';
import * as spark from '$lib/data/spark'; import * as spark from '$lib/data/spark';
import Pick from '$lib/Pick.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { SvelteMap } from 'svelte/reactivity'; import { SvelteMap } from 'svelte/reactivity';
@@ -14,17 +15,9 @@
} }
}); });
let group = $state(1); let group: spark.SparkGroup | undefined = $state();
const groups = $derived.by(() => { const groups = $derived(spark.byGroup(sparks));
const m = new SvelteMap<number, spark.Spark[]>();
for (const s of sparks) {
const l = m.get(s.spark_group) ?? [];
l.push(s);
m.set(s.spark_group, l);
}
return [...m.entries()];
});
function describe(eff: spark.Effect) { function describe(eff: spark.Effect) {
if (eff.target === spark.Target.Skill) { if (eff.target === spark.Target.Skill) {
const sk = skills.get(eff.value1); const sk = skills.get(eff.value1);
@@ -32,14 +25,13 @@
} }
return `${spark.TARGET_NAMES[eff.target]} +${eff.value1}`; return `${spark.TARGET_NAMES[eff.target]} +${eff.value1}`;
} }
const cur = $derived(sparks.find((s) => s.spark_group === group)); const curEffectGroups = $derived(group?.effects ?? []);
const curEffectGroups = $derived(cur?.effects ?? []);
const curDescriptions = $derived(curEffectGroups.map((g) => g.map((e) => describe(e)))); const curDescriptions = $derived(curEffectGroups.map((g) => g.map((e) => describe(e))));
const curClass = $derived.by(() => { function sparkClass(t: spark.Type | null | undefined): string[] {
if (cur == null) { if (t == null) {
return []; return [];
} }
switch (cur.type) { switch (t) {
case 1: case 1:
return ['stat']; return ['stat'];
case 2: case 2:
@@ -57,16 +49,19 @@
default: default:
return []; return [];
} }
}); }
const curClass = $derived(sparkClass(group?.type));
const key = (v: spark.SparkGroup) => ({id: v.spark_group, name: v.name})
</script> </script>
<h1 class="text-4xl">Spark Explorer</h1> <h1 class="text-4xl">Spark Explorer</h1>
<form class="mx-auto mt-8 rounded-md p-4 text-center shadow-md ring md:max-w-2xl"> <form class="mx-auto mt-8 rounded-md p-4 text-center shadow-md ring md:max-w-2xl">
<select class="w-full" bind:value={group}> <Pick id="spark" items={groups} class="w-full" {key} bind:value={group} required>
{#each groups as [id, s] (id)} {#snippet option(g)}
<option value={id}>{s[0].name}</option> <span class={['spark px-2 py-1 rounded', sparkClass(g.type)]}>{g.name}</span>
{/each} {/snippet}
</select> </Pick>
</form> </form>
<svelte:boundary> <svelte:boundary>
<div <div
@@ -75,22 +70,22 @@
curClass, curClass,
]} ]}
> >
<span class="block text-xl">{cur?.name}</span> <span class="block text-xl">{group?.name}</span>
{#if cur != null} {#if group != null}
<span class="block"> <span class="block">
{spark.TYPE_NAMES[cur.type]} Spark {spark.TYPE_NAMES[group.type]} Spark
</span> </span>
{/if} {/if}
<span class="block">{cur?.description}</span> <span class="block">{group?.description}</span>
</div> </div>
<table class="mx-auto mt-8 w-full max-w-xl table-fixed"> <table class="mx-auto mt-8 w-full max-w-xl table-fixed border-separate border-spacing-2">
<caption class="text-xl">Possible Effects</caption> <caption class="text-xl">Possible Effects</caption>
<tbody> <tbody>
{#each curDescriptions as s (s)} {#each curDescriptions as s (s)}
<tr class="text-center even:bg-mist-300 dark:even:bg-mist-900"> <tr>
<td> <td class="flex gap-2 p-1 text-center border border-mist-400 dark:border-mist-950">
{#each s as n (n)} {#each s as n (n)}
<span class="block">{n}</span> <span class="flex-1 my-auto">{n}</span>
{/each} {/each}
</td> </td>
</tr> </tr>