Attribute: Farbfeld zeigt nur noch ein Quadrat statt zwei

ColorHexField stellte Swatch UND natives <input type="color"> sichtbar
nebeneinander dar (zusätzlich zum separaten Hex-Textfeld) — wirkte wie zwei
Farbfelder pro Zeile. Hex-Textfeld entfernt, natives Color-Input liegt jetzt
unsichtbar über dem Swatch (öffnet die native Palette beim Klick auf das
einzige sichtbare Quadrat). Betrifft alle Attribute-Farbfelder in der App,
nicht nur die neuen Fenster-Linien-Felder.
This commit is contained in:
2026-07-12 18:48:25 +02:00
parent bd8612ee74
commit a51fd212d3
2 changed files with 20 additions and 76 deletions
+17 -37
View File
@@ -4494,13 +4494,15 @@ body {
align-items: center; align-items: center;
gap: 6px; gap: 6px;
} }
/* Swatch + natives Farb-Input — EIGENER Klick-Bereich (öffnet die Palette). /* Swatch = EINZIGES sichtbares Quadrat; das native Farb-Input liegt unsichtbar
Der Hex-Text daneben ist jetzt ein separates <input> (ColorHexField), (opacity 0) exakt darüber und öffnet beim Klick die native Palette — vorher
damit er unabhängig editierbar ist statt nur die Palette zu öffnen. */ standen Swatch UND natives Input sichtbar nebeneinander ("zwei Farbfelder",
Nutzer-Report). Kein separates Hex-Textfeld mehr daneben. */
.attr-color-swatch-wrap { .attr-color-swatch-wrap {
position: relative;
display: inline-flex; display: inline-flex;
align-items: center; width: 16px;
gap: 4px; height: 16px;
cursor: pointer; cursor: pointer;
} }
.attr-color-swatch { .attr-color-swatch {
@@ -4511,44 +4513,22 @@ body {
flex: 0 0 auto; flex: 0 0 auto;
} }
.attr-color input[type="color"] { .attr-color input[type="color"] {
width: 22px; position: absolute;
height: 18px; inset: 0;
width: 100%;
height: 100%;
padding: 0; padding: 0;
border: 1px solid var(--line); border: none;
border-radius: 3px; opacity: 0;
background: transparent;
cursor: pointer; cursor: pointer;
} }
.attr-color-hex {
font-variant-numeric: tabular-nums;
color: var(--ink-2);
font-size: 11px;
}
/* Editierbarer Hex-Code: sieht wie reiner Text aus, bis man klickt/fokussiert
— dann Rahmen + helle Schrift als Editier-Signal. */
.attr-color-hex-input {
width: 8.5ch;
color: var(--ink-2);
border: 1px solid transparent;
background: transparent;
border-radius: 3px;
padding: 1px 3px;
font-family: var(--font-mono);
cursor: text;
}
.attr-color-hex-input:hover:not(:disabled) {
border-color: var(--border);
}
.attr-color-hex-input:focus {
outline: none;
border-color: var(--accent);
background: var(--input);
color: var(--ink);
}
.attr-color input[type="color"]:disabled { .attr-color input[type="color"]:disabled {
opacity: 0.4;
cursor: not-allowed; cursor: not-allowed;
} }
.attr-color-swatch-wrap:has(input:disabled) {
cursor: not-allowed;
opacity: 0.4;
}
.attr-color-clear { .attr-color-clear {
border: 1px solid var(--line); border: 1px solid var(--line);
background: transparent; background: transparent;
+3 -39
View File
@@ -1,8 +1,7 @@
// Farbfeld: Swatch (öffnet die native Farbpalette) + separat editierbarer // Farbfeld: nur der quadratische Swatch (öffnet die native Farbpalette per
// Hex-Code (Tippen/Enter übernimmt, Esc verwirft). Ersetzt die frühere reine // Klick) — bewusst OHNE separates Hex-Textfeld daneben (Nutzer-Wunsch: in den
// Text-Anzeige des Hex-Werts, die nicht anklickbar/editierbar war. // Attributen soll generell nur das Quadrat sichtbar sein, keine zwei Felder).
import { useEffect, useState } from "react";
import { t } from "../i18n"; import { t } from "../i18n";
export function ColorHexField({ export function ColorHexField({
@@ -14,23 +13,6 @@ export function ColorHexField({
onChange: (hex: string) => void; onChange: (hex: string) => void;
disabled?: boolean; disabled?: boolean;
}) { }) {
const [text, setText] = useState(value.toUpperCase());
// Extern geänderter Wert (z. B. Preset-Klick) synchron halten, solange das
// Feld nicht gerade selbst bearbeitet wird (kein Cursor-Sprung beim Tippen).
useEffect(() => setText(value.toUpperCase()), [value]);
const commit = (raw: string) => {
const trimmed = raw.trim();
const withHash = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
if (/^#[0-9a-fA-F]{6}$/.test(withHash)) {
onChange(withHash.toLowerCase());
setText(withHash.toUpperCase());
} else {
setText(value.toUpperCase()); // ungültig → letzten gültigen Wert zeigen
}
};
return ( return (
<span className="attr-color"> <span className="attr-color">
<label className="attr-color-swatch-wrap" title={t("attr.pickColor")}> <label className="attr-color-swatch-wrap" title={t("attr.pickColor")}>
@@ -42,24 +24,6 @@ export function ColorHexField({
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
/> />
</label> </label>
<input
type="text"
className="attr-color-hex attr-color-hex-input"
value={text}
disabled={disabled}
spellCheck={false}
onChange={(e) => setText(e.target.value)}
onBlur={(e) => commit(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
commit(e.currentTarget.value);
e.currentTarget.blur();
} else if (e.key === "Escape") {
setText(value.toUpperCase());
e.currentTarget.blur();
}
}}
/>
</span> </span>
); );
} }