From a2b904811af0e7fd1bfaf30846fded10b7cb2383 Mon Sep 17 00:00:00 2001 From: lew Date: Tue, 7 Apr 2026 18:17:41 +0100 Subject: [PATCH] feat: dynamic field labels, optionally overriding field names per species --- data/schema/species.xsd | 16 ++- data/species/diona.xml | 2 +- data/species/human.xml | 5 +- data/species/ipc.xml | 5 +- data/species/skrell.xml | 2 +- data/species/tajara.xml | 5 +- data/species/unathi.xml | 2 +- data/species/vaurca.xml | 5 +- src/lib/components/RecordCard.svelte | 4 +- src/lib/components/SchemaForm.svelte | 2 +- src/lib/components/fields/DynamicField.svelte | 97 ++++++++++++------- .../components/fields/SubspeciesField.svelte | 3 +- src/lib/data/parse.test.ts | 32 ++++++ src/lib/data/parse.ts | 13 ++- src/lib/data/types.ts | 2 +- src/lib/output.test.ts | 51 +++++++++- src/lib/output.ts | 47 +++++---- src/lib/utils/blank.ts | 4 +- src/lib/utils/field-flags.ts | 44 +++++++++ src/lib/utils/resolve-label.test.ts | 37 +++++++ src/lib/utils/resolve-label.ts | 17 ++++ 21 files changed, 322 insertions(+), 73 deletions(-) create mode 100644 src/lib/data/parse.test.ts create mode 100644 src/lib/utils/field-flags.ts create mode 100644 src/lib/utils/resolve-label.test.ts create mode 100644 src/lib/utils/resolve-label.ts diff --git a/data/schema/species.xsd b/data/schema/species.xsd index 18afdfc..a8ad8f5 100644 --- a/data/schema/species.xsd +++ b/data/schema/species.xsd @@ -3,8 +3,19 @@ - + + + + + + + + + + + + @@ -22,10 +33,9 @@ - + - diff --git a/data/species/diona.xml b/data/species/diona.xml index fb86329..c592985 100644 --- a/data/species/diona.xml +++ b/data/species/diona.xml @@ -1,5 +1,5 @@ - + A mysterious plant-like species hailing from the depths of space. Dionae are comprised of cat-sized caterpillar-like creatures called nymphs, which form gestalt consciousnesses when two or more combine. Almost every aspect of the species is a mystery: their origins, behaviour, and functions. They are capable of great intellectual and biological feats, surviving primarily off the electromagnetic spectrum and biological matter. diff --git a/data/species/human.xml b/data/species/human.xml index ef18590..482cc3b 100644 --- a/data/species/human.xml +++ b/data/species/human.xml @@ -1,5 +1,8 @@ - + + + + Humans originated on Earth. diff --git a/data/species/ipc.xml b/data/species/ipc.xml index e5f254d..77afd8b 100644 --- a/data/species/ipc.xml +++ b/data/species/ipc.xml @@ -1,5 +1,8 @@ - + + + + IPCs are synthetic chassis housing a positronic processing core. From skeletal baselines to humanlike shells, they serve in a variety of roles across the Orion Spur. Their legal status varies wildly between nations, ranging from full citizenship to being classified as property. diff --git a/data/species/skrell.xml b/data/species/skrell.xml index 8726104..bf63dbf 100644 --- a/data/species/skrell.xml +++ b/data/species/skrell.xml @@ -1,5 +1,5 @@ - + Skrell are a species of amphibious bipeds, originating from the planet of Qerrbalak. With longer lifespans than most sophonts, combined with their earlier development of organized societies, skrell are the oldest spacefaring species in the Orion Spur. diff --git a/data/species/tajara.xml b/data/species/tajara.xml index 39905fa..304109b 100644 --- a/data/species/tajara.xml +++ b/data/species/tajara.xml @@ -1,5 +1,8 @@ - + + + + The Tajara are a race of humanoids that possess markedly felinoid traits. Tajaran history and society is deeply entrenched in the conflict between its caste system and ruling governments. diff --git a/data/species/unathi.xml b/data/species/unathi.xml index cdf998c..3f52554 100644 --- a/data/species/unathi.xml +++ b/data/species/unathi.xml @@ -1,5 +1,5 @@ - + A heavily reptilian species, Unathi hail from the Uuosa-Eso system. A relatively recent addition to the galactic stage, they suffered immense turmoil after the cultural and economic disruption following first contact with humanity. With their homeworld of Moghes suffering catastrophic climate change from a nuclear war in the recent past, the Izweski Hegemony that rules the majority of the species struggles to find its place in the galaxy. They hold ideals of honesty, virtue, martial combat, and spirituality above all else. diff --git a/data/species/vaurca.xml b/data/species/vaurca.xml index 8b526b8..da2776f 100644 --- a/data/species/vaurca.xml +++ b/data/species/vaurca.xml @@ -1,5 +1,8 @@ - + + + + The Vaurca are an insectoid species with a complex caste-based society organised into Hives, each led by a Queen. They communicate primarily through a localised expression of their hivemind. Having arrived in the Orion Spur from deep space, they are one of the newest species to join the galactic stage, and their integration into existing societies remains an ongoing process. diff --git a/src/lib/components/RecordCard.svelte b/src/lib/components/RecordCard.svelte index 9c52302..767287b 100644 --- a/src/lib/components/RecordCard.svelte +++ b/src/lib/components/RecordCard.svelte @@ -5,10 +5,11 @@ import DynamicField from './fields/DynamicField.svelte'; import { slugify } from '$lib/utils/slugify'; - let { record, data, onFieldChange }: { + let { record, data, onFieldChange, onSave }: { record: RecordDef; data: Record; onFieldChange: (key: string, value: any) => void; + onSave: () => void; } = $props(); let expanded = $state(false); @@ -76,6 +77,7 @@ {field} value={data[key]} {data} + {onSave} onChange={(v) => onFieldChange(key, v)} /> {#if hasError} diff --git a/src/lib/components/SchemaForm.svelte b/src/lib/components/SchemaForm.svelte index 9654bd9..30f06c0 100644 --- a/src/lib/components/SchemaForm.svelte +++ b/src/lib/components/SchemaForm.svelte @@ -13,7 +13,6 @@ let dismissed = $state(null); let showTemplateSwitcher = $state(false); let showMigrationModal = $state(false); - let speciesKeys = $derived(new Set( character.template.records.flatMap((r) => r.fields) .filter((f) => f.type === 'species') @@ -160,6 +159,7 @@ } roster.scheduleSave(character); }} + onSave={() => roster.scheduleSave(character)} /> {/each} diff --git a/src/lib/components/fields/DynamicField.svelte b/src/lib/components/fields/DynamicField.svelte index 3893c85..9a29074 100644 --- a/src/lib/components/fields/DynamicField.svelte +++ b/src/lib/components/fields/DynamicField.svelte @@ -1,5 +1,9 @@ -{#if field.type === 'name'} - -{:else if field.type === 'text'} - -{:else if field.type === 'textarea'} - -{:else if field.type === 'list'} - -{:else if field.type === 'number'} - -{:else if field.type === 'select'} - -{:else if field.type === 'multi-select'} - -{:else if field.type === 'checkbox'} - -{:else if field.type === 'date'} - -{:else if field.type === 'height'} - -{:else if field.type === 'weight'} - -{:else if field.type === 'species'} - -{:else if field.type === 'subspecies'} - -{:else if field.type === 'citizenship'} - -{:else if field.type === 'languages'} - -{:else if field.type === 'separator'} - -{/if} +
+ {#if override !== null} + + {/if} + + {#if field.type === 'name'} + + {:else if field.type === 'text'} + + {:else if field.type === 'textarea'} + + {:else if field.type === 'list'} + + {:else if field.type === 'number'} + + {:else if field.type === 'select'} + + {:else if field.type === 'multi-select'} + + {:else if field.type === 'checkbox'} + + {:else if field.type === 'date'} + + {:else if field.type === 'height'} + + {:else if field.type === 'weight'} + + {:else if field.type === 'species'} + + {:else if field.type === 'subspecies'} + + {:else if field.type === 'citizenship'} + + {:else if field.type === 'languages'} + + {:else if field.type === 'separator'} + + {/if} +
diff --git a/src/lib/components/fields/SubspeciesField.svelte b/src/lib/components/fields/SubspeciesField.svelte index d0a36d0..6a432ec 100644 --- a/src/lib/components/fields/SubspeciesField.svelte +++ b/src/lib/components/fields/SubspeciesField.svelte @@ -12,7 +12,6 @@ let currentSpecies = $derived(species.find((s) => s.id === data[slugify('Species')])); let subs = $derived(currentSpecies?.subspecies ?? []); - let label = $derived(currentSpecies?.subspeciesLabel ?? field.label); let selected = $derived(subs.find((s) => s.id === value)); let custom = $state(false); @@ -33,7 +32,7 @@ {#if subs.length > 0 || isCustom}