feat(settings): Akzentfarbe zusätzlich als Hex-Code eingebbar
- normalizeHexColor() (apps/web/src/lib/color.ts) normalisiert Hex-Eingaben (fuehrendes # optional, 3-stellige Kurzform, Gross-/Kleinschreibung, Leerraum) - Kontoformular: Hex-Textfeld neben dem Farbwaehler, beide bidirektional synchron, ersetzt den reinen Anzeige-Span - Ungueltiger Text: aria-invalid + roter Rand + Fehlertext, "Farbe speichern" gesperrt; Zuruecksetzen setzt beides auf #ffed00 - i18n: settings.account.accentColorHex/accentColorHexInvalid in de.json und en.json - Unit-Tests: color.test.ts (9 Faelle), account-settings-form.test.tsx (7 Faelle) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { normalizeHexColor } from './color';
|
||||
|
||||
/**
|
||||
* color.test — Normalisierung der Hex-Eingabe der Akzentfarbe
|
||||
* (quick-260917-gsh).
|
||||
*/
|
||||
describe('normalizeHexColor', () => {
|
||||
it('accepts a canonical six-digit hex value with leading #', () => {
|
||||
expect(normalizeHexColor('#ffed00')).toBe('#ffed00');
|
||||
});
|
||||
|
||||
it('accepts a six-digit value without # and uppercase letters', () => {
|
||||
expect(normalizeHexColor('FFED00')).toBe('#ffed00');
|
||||
});
|
||||
|
||||
it('expands a three-digit shorthand', () => {
|
||||
expect(normalizeHexColor('#fe0')).toBe('#ffee00');
|
||||
});
|
||||
|
||||
it('trims surrounding whitespace and lowercases mixed case', () => {
|
||||
expect(normalizeHexColor(' #FfEd00 ')).toBe('#ffed00');
|
||||
});
|
||||
|
||||
it('rejects non-hex characters', () => {
|
||||
expect(normalizeHexColor('#ggg')).toBeNull();
|
||||
});
|
||||
|
||||
it('rejects the wrong digit count (5)', () => {
|
||||
expect(normalizeHexColor('#12345')).toBeNull();
|
||||
});
|
||||
|
||||
it('rejects an empty string', () => {
|
||||
expect(normalizeHexColor('')).toBeNull();
|
||||
});
|
||||
|
||||
it('rejects a lone hash', () => {
|
||||
expect(normalizeHexColor('#')).toBeNull();
|
||||
});
|
||||
|
||||
it('rejects the wrong digit count (7)', () => {
|
||||
expect(normalizeHexColor('#1234567')).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Normalisierung der Hex-Eingabe der persoenlichen Akzentfarbe
|
||||
* (Einstellungen → Konto, quick-260917-gsh).
|
||||
*
|
||||
* `PATCH /users/me/accent-color` verlangt serverseitig `/^#[0-9a-fA-F]{6}$/` —
|
||||
* diese Funktion bringt Roheingaben (mit/ohne `#`, Kurzform, Gross-/
|
||||
* Kleinschreibung, umgebender Leerraum) in genau diese kanonische Form
|
||||
* oder liefert `null`, wenn das nicht moeglich ist.
|
||||
*/
|
||||
|
||||
const HEX_PATTERN = /^[0-9a-f]{3}$|^[0-9a-f]{6}$/i;
|
||||
|
||||
export function normalizeHexColor(input: string): string | null {
|
||||
const trimmed = input.trim();
|
||||
const withoutHash = trimmed.startsWith('#') ? trimmed.slice(1) : trimmed;
|
||||
|
||||
if (!HEX_PATTERN.test(withoutHash)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const expanded =
|
||||
withoutHash.length === 3
|
||||
? withoutHash
|
||||
.split('')
|
||||
.map((ch) => ch + ch)
|
||||
.join('')
|
||||
: withoutHash;
|
||||
|
||||
return `#${expanded.toLowerCase()}`;
|
||||
}
|
||||
Reference in New Issue
Block a user