fix(frontend): let a tag be created/edited without a colour
A native <input type="color"> always holds a value, so the form always sent the input's default colour and a tag could never be colourless. Add a "Color" checkbox gating the swatch: off by default on the new-tag form (so tags are colourless unless opted in) and initialised from the tag on the edit form, which can now clear a colour. Sends color: null when off. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
|
||||
let name = $state('');
|
||||
let notes = $state('');
|
||||
// A native <input type="color"> always holds a value, so a separate flag tracks
|
||||
// whether the tag has a colour at all — letting it be cleared back to none.
|
||||
let hasColor = $state(false);
|
||||
let color = $state('#444455');
|
||||
let categoryId = $state('');
|
||||
let isPublic = $state(false);
|
||||
@@ -43,6 +46,7 @@
|
||||
|
||||
name = t.name ?? '';
|
||||
notes = t.notes ?? '';
|
||||
hasColor = !!t.color;
|
||||
color = t.color ? `#${t.color}` : '#444455';
|
||||
categoryId = t.category_id ?? '';
|
||||
isPublic = t.is_public ?? false;
|
||||
@@ -61,7 +65,7 @@
|
||||
await api.patch(`/tags/${tagId}`, {
|
||||
name: name.trim(),
|
||||
notes: notes.trim() || null,
|
||||
color: color.slice(1),
|
||||
color: hasColor ? color.slice(1) : null,
|
||||
category_id: categoryId || null,
|
||||
is_public: isPublic
|
||||
});
|
||||
@@ -139,8 +143,18 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="field color-field">
|
||||
<label class="label" for="color">Color</label>
|
||||
<input id="color" class="color-input" type="color" bind:value={color} />
|
||||
<label class="label color-label">
|
||||
<input type="checkbox" class="color-check" bind:checked={hasColor} />
|
||||
Color
|
||||
</label>
|
||||
<input
|
||||
id="color"
|
||||
class="color-input"
|
||||
type="color"
|
||||
bind:value={color}
|
||||
disabled={!hasColor}
|
||||
aria-label="Tag color"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -339,6 +353,18 @@
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.color-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.color-check {
|
||||
cursor: pointer;
|
||||
accent-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.color-input {
|
||||
width: 50px;
|
||||
height: 36px;
|
||||
@@ -349,6 +375,11 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.color-input:disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
let name = $state('');
|
||||
let notes = $state('');
|
||||
// A native <input type="color"> always holds a value, so a separate flag tracks
|
||||
// whether the tag should have a color at all. Off by default → no colour unless
|
||||
// the user opts in (otherwise the tag falls back to its category / the default).
|
||||
let hasColor = $state(false);
|
||||
let color = $state('#444455');
|
||||
let categoryId = $state('');
|
||||
let isPublic = $state(false);
|
||||
@@ -27,7 +31,7 @@
|
||||
await api.post('/tags', {
|
||||
name: name.trim(),
|
||||
notes: notes.trim() || null,
|
||||
color: color.slice(1), // strip #
|
||||
color: hasColor ? color.slice(1) : null, // strip #; null = no colour
|
||||
category_id: categoryId || null,
|
||||
is_public: isPublic
|
||||
});
|
||||
@@ -86,8 +90,18 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="field color-field">
|
||||
<label class="label" for="color">Color</label>
|
||||
<input id="color" class="color-input" type="color" bind:value={color} />
|
||||
<label class="label color-label">
|
||||
<input type="checkbox" class="color-check" bind:checked={hasColor} />
|
||||
Color
|
||||
</label>
|
||||
<input
|
||||
id="color"
|
||||
class="color-input"
|
||||
type="color"
|
||||
bind:value={color}
|
||||
disabled={!hasColor}
|
||||
aria-label="Tag color"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -235,6 +249,18 @@
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.color-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.color-check {
|
||||
cursor: pointer;
|
||||
accent-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.color-input {
|
||||
width: 50px;
|
||||
height: 36px;
|
||||
@@ -245,6 +271,11 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.color-input:disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
Reference in New Issue
Block a user