better gui

This commit is contained in:
Lukas Forsberg 2025-12-10 22:54:41 +01:00
parent 0339054f73
commit 1ee16327e9
2 changed files with 92 additions and 30 deletions

View File

@ -0,0 +1,18 @@
import { tick } from "svelte";
export function autoGrow(node) {
function resize() {
node.style.height = "auto";
node.style.height = node.scrollHeight + "px";
}
// wait until DOM updates to apply initial value
tick().then(resize);
node.addEventListener("input", resize);
return {
destroy() {
node.removeEventListener("input", resize);
}
};
}

View File

@ -3,7 +3,8 @@
import { API_BASE } from '$lib/config';
import { Defaults } from './defaults.svelte';
import type { Skill, Connection} from './types.svelte';
import { autoGrow } from '$lib/common/autogrow';
export let currentCharacter: any;
export let currentCharacterData: any;
@ -85,17 +86,46 @@
<h2>Attributes</h2>
<div class="info-container">
{#each Object.entries(characterData.Attributes) as [key, value], i}
<div class="input-row">
<label for={"field-" + i}>{key}</label>
<input
id={"field-" + i}
type="number"
bind:value={characterData["Attributes"][key]}
min=0
max=100 />
</div>
{/each}
<table>
<tbody>
<tr>
<td>
<label for={"field-Agility"}>Agility</label>
<input id={"field-Agility"} type="number" bind:value={characterData.Attributes.Agility} min=0 max=100/>
</td>
<td>
<label for={"field-Body"}>Body</label>
<input id={"field-Body"} type="number" bind:value={characterData.Attributes.Body} min=0 max=100/>
</td>
<td>
<label for={"field-Charisma"}>Charisma</label>
<input id={"field-Charisma"} type="number" bind:value={characterData.Attributes.Charisma} min=0 max=100/>
</td>
<td>
<label for={"field-Edge"}>Edge</label>
<input id={"field-Edge"} type="number" bind:value={characterData.Attributes.Edge} min=0 max=100/>
</td>
</tr>
<tr>
<td>
<label for={"field-Essence"}>Essence</label>
<input id={"field-Essence"} type="number" bind:value={characterData.Attributes.Essence} min=0 max=100/>
</td>
<td>
<label for={"field-Initiative"}>Initiative</label>
<input id={"field-Initiative"} type="number" bind:value={characterData.Attributes.Initiative} min=0 max=100/>
</td>
<td>
<label for={"field-Charisma"}>Charisma</label>
<input id={"field-Charisma"} type="number" bind:value={characterData.Attributes.Charisma} min=0 max=100/>
</td>
<td>
<label for={"field-Edge"}>Edge</label>
<input id={"field-Edge"} type="number" bind:value={characterData.Attributes.Edge} min=0 max=100/>
</td>
</tr>
</tbody>
</table>
</div>
<h2>Skills</h2>
@ -105,7 +135,7 @@
<th>Name</th>
<th>Rating</th>
<th>Attribute</th>
<th>Dice Pool</th>
<th>Dice</th>
<th>Page</th>
<th></th>
<th></th>
@ -115,7 +145,7 @@
<tbody>
{#each characterData.Skills as skill, i}
<tr>
<td><input placeholder="Name" bind:value={characterData.Skills[i].Name} /></td>
<td><textarea use:autoGrow class="input-height" rows="1" bind:value={characterData.Skills[i].Name}></textarea></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Skills[i].Rating} /></td>
<td><select bind:value={characterData.Skills[i].Attribute}>
{#each Object.keys(Defaults.Attributes) as attr}
@ -125,7 +155,7 @@
<td><span>{skill.Rating + characterData.Attributes[skill.Attribute]}</span></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Skills[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Skills[i].Page)}>View</button></td>
<td><button on:click={() => remove("Skills", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("Skills", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -145,10 +175,10 @@
<tbody>
{#each characterData.Connections as connection, i}
<tr>
<td><input placeholder="Name" bind:value={characterData.Connections[i].Name}/></td>
<td><textarea use:autoGrow class="input-height" rows="1" bind:value={characterData.Connections[i].Name}></textarea></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Connections[i].Loyalty} /></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Connections[i].Connection} /></td>
<td><button on:click={() => remove("Connections", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("Connections", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -175,17 +205,17 @@
<tbody>
{#each characterData.RangedWeapons as weapon, i}
<tr>
<td><input placeholder="Name" bind:value={characterData.RangedWeapons[i].Weapon} /></td>
<td><textarea use:autoGrow class="input-height" rows="1" bind:value={characterData.RangedWeapons[i].Weapon}></textarea></td>
<td><input type="number" min=0 max=100 bind:value={characterData.RangedWeapons[i].Damage} /></td>
<td><input bind:value={characterData.RangedWeapons[i].Type} /></td>
<td><textarea use:autoGrow class="input-height" style="width: 5em;" rows="1" bind:value={characterData.RangedWeapons[i].Type}></textarea></td>
<td><input type="number" min=0 max=100 bind:value={characterData.RangedWeapons[i].AP} /></td>
<td><input bind:value={characterData.RangedWeapons[i].Mode} /></td>
<td><textarea use:autoGrow class="input-height" style="width: 3em;" rows="1" bind:value={characterData.RangedWeapons[i].Mode}></textarea></td>
<td><input type="number" min=0 max=100 bind:value={characterData.RangedWeapons[i].RC} /></td>
<td><input type="number" min=0 max=9999 bind:value={characterData.RangedWeapons[i].Ammo} /></td>
<td><input bind:value={characterData.RangedWeapons[i].Availabiliy} /></td>
<td><textarea use:autoGrow class="input-height" style="width: 3em;" rows="1" bind:value={characterData.RangedWeapons[i].Availabiliy}></textarea></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td>
<td><button on:click={() => remove("RangedWeapons", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("RangedWeapons", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -200,8 +230,8 @@
<th>Reach</th>
<th>Damage</th>
<th>Type</th>
<th>Strength Multiplier</th>
<th>Calculated Damage</th>
<th>Multiplier</th>
<th>Cal.Dmg</th>
<th>AP</th>
<th>Page</th>
<th></th>
@ -220,7 +250,7 @@
<td><input type="number" min=0 max=100 bind:value={characterData.MeleeWeapons[i].AP} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td>
<td><button on:click={() => remove("MeleeWeapons", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("MeleeWeapons", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -247,7 +277,7 @@
<td><input type="number" min=0 max=100 bind:value={characterData.Armor[i].Impact} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Armor[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Armor[i].Page)}>View</button></td>
<td><button on:click={() => remove("Armor", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("Armor", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -276,7 +306,7 @@
<td><input placeholder="Notes" bind:value={characterData.Cyberware[i].Notes} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td>
<td><button on:click={() => remove("Cyberware", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("Cyberware", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -305,7 +335,7 @@
<td><input placeholder="Notes" bind:value={characterData.Bioware[i].Notes} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td>
<td><button on:click={() => remove("Bioware", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("Bioware", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -330,7 +360,7 @@
<td><input placeholder="Qualitiy" bind:value={characterData.PositiveQualities[i].Qualitiy} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.PositiveQualities[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.PositiveQualities[i].Page)}>View</button></td>
<td><button on:click={() => remove("PositiveQualities", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("PositiveQualities", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -353,7 +383,7 @@
<td><input placeholder="Qualitiy" bind:value={characterData.NegativeQualities[i].Qualitiy} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.NegativeQualities[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.NegativeQualities[i].Page)}>View</button></td>
<td><button on:click={() => remove("NegativeQualities", i)}>X</button></td>
<td><button class="red-button" on:click={() => remove("NegativeQualities", i)}>X</button></td>
</tr>
{/each}
</tbody>
@ -416,6 +446,20 @@
gap: 0.5em; /* space between each input-row */
}
.red-button {
border: none; /* optional: remove default border */
cursor: pointer; /* optional: pointer cursor */
}
.input-height {
border: none; /* optional: remove default border */
font: inherit; /* copies all font-related properties from the parent/input styling */
height: auto; /* allows autoGrow action to work */
min-height: 0;
/* resize: none; */
overflow: hidden; /* Allow autoGrow to work clean */
width: 10em; /* 15 × current font size */
}
.input-row {
display: flex;
align-items: center;