Make player character color and icon optional

Clicking an already-selected color or icon in the create/edit form now
deselects it. PCs without a color use the default combatant styling;
PCs without an icon show no icon. Domain, application, persistence,
and display layers all updated to handle the optional fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-13 18:01:20 +01:00
parent 07cdd4867a
commit b7406c4b54
15 changed files with 121 additions and 45 deletions

View File

@@ -18,8 +18,8 @@ interface EditFields {
readonly name?: string;
readonly ac?: number;
readonly maxHp?: number;
readonly color?: string;
readonly icon?: string;
readonly color?: string | null;
readonly icon?: string | null;
}
function validateFields(fields: EditFields): DomainError | null {
@@ -50,14 +50,22 @@ function validateFields(fields: EditFields): DomainError | null {
message: "Max HP must be a positive integer",
};
}
if (fields.color !== undefined && !VALID_PLAYER_COLORS.has(fields.color)) {
if (
fields.color !== undefined &&
fields.color !== null &&
!VALID_PLAYER_COLORS.has(fields.color)
) {
return {
kind: "domain-error",
code: "invalid-color",
message: `Invalid color: ${fields.color}`,
};
}
if (fields.icon !== undefined && !VALID_PLAYER_ICONS.has(fields.icon)) {
if (
fields.icon !== undefined &&
fields.icon !== null &&
!VALID_PLAYER_ICONS.has(fields.icon)
) {
return {
kind: "domain-error",
code: "invalid-icon",
@@ -78,11 +86,11 @@ function applyFields(
maxHp: fields.maxHp !== undefined ? fields.maxHp : existing.maxHp,
color:
fields.color !== undefined
? (fields.color as PlayerCharacter["color"])
? ((fields.color as PlayerCharacter["color"]) ?? undefined)
: existing.color,
icon:
fields.icon !== undefined
? (fields.icon as PlayerCharacter["icon"])
? ((fields.icon as PlayerCharacter["icon"]) ?? undefined)
: existing.icon,
};
}