diff --git a/src/app.css b/src/app.css index 1909965..ae171d5 100644 --- a/src/app.css +++ b/src/app.css @@ -17,6 +17,7 @@ --text-muted: #737373; --accent: #0066cc; --accent-hover: #0052a3; + --error: #dc2626; } .dark { @@ -28,6 +29,7 @@ --text-muted: #a3a3a3; --accent: #4da6ff; --accent-hover: #80bfff; + --error: #f87171; } body { @@ -35,3 +37,9 @@ body { color: var(--text); font-family: system-ui, -apple-system, sans-serif; } + +.field-error input, +.field-error select, +.field-error textarea { + border-color: var(--error) !important; +} diff --git a/src/app.html b/src/app.html index a047305..2a6e487 100644 --- a/src/app.html +++ b/src/app.html @@ -3,7 +3,7 @@ - Aurora Records + Character Records %sveltekit.head% diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index a922ccb..e756c02 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -62,7 +62,7 @@
-

Aurora Records

+

Character Records

{#if roster.characters.length > 0} diff --git a/src/lib/components/RecordCard.svelte b/src/lib/components/RecordCard.svelte index cfb1a9f..9c52302 100644 --- a/src/lib/components/RecordCard.svelte +++ b/src/lib/components/RecordCard.svelte @@ -1,7 +1,7 @@ @@ -55,12 +62,26 @@ {#if expanded}
{#each record.fields as field} - onFieldChange(slugify(field.label), v)} - /> + {@const key = slugify(field.label)} + {@const hasError = isRequired(field) && touched[key] && isFieldEmpty(data[key])} +
{ + if (isRequired(field) && !(e.currentTarget as HTMLElement).contains(e.relatedTarget as Node)) { + touched[key] = true; + } + }} + > + onFieldChange(key, v)} + /> + {#if hasError} +

This field is required

+ {/if} +
{/each}
{/if} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 7aa356e..9093e24 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,5 +1,6 @@
+ {#if importError} +
+ {importError} + +
+ {/if} + {#if fileImportData}
@@ -109,19 +129,56 @@ {/if} {:else} -
-

No characters yet.

- +
+
+
+

+ Pick a template and fill in the form. Each section covers a different record. Blank fields are omitted from the output automatically, so no rush to finish everything. +

+

+ Characters save to your browser. You can also export to a file or generate a share link: the link itself encodes the full set of records, so functionally it's a save file. +

+

+ Share links let the recipient see a preview of your records, with the option to import the character into their own roster. +

+

+ This tool is entirely data-driven in XML, and it's already set up for template sharing. A visual template editor is coming soon, so anybody can create their own templates and share them between one another. +

+

+ Cheers. +

+
+ +
+ + +
+
+ + + {#if showPicker} { showPicker = false; }} /> {/if}