@konce-pt/color
v0.11.1
Published
Colour maths for Koncept UI — sRGB, OKLab and OKLCH conversions, hue-aware mixing, gamut mapping, WCAG and APCA contrast. Framework-free TypeScript, zero runtime dependencies.
Maintainers
Readme
@konce-pt/color
Rachunek barw Koncept UI: konwersje sRGB ↔ OKLab ↔ OKLCH, mieszanie po kole odcieni, sprowadzanie barwy do gamutu sRGB oraz kontrast w dwóch miarach — WCAG 2.1 i APCA. Czysty TypeScript, zero zależności runtime, bez wiązania z frameworkiem.
Paleta biblioteki jest zapisana w OKLCH i przechodzi przez build verbatim, bez transformacji kolorów. Żeby cokolwiek z tymi wartościami policzyć — wymieszać dwie barwy, wyprowadzić rampę z jednego ziarna, sprawdzić czy napis na tle da się przeczytać — potrzebny jest model, w którym jasność znaczy jasność. Tym modelem jest OKLab i to jest ta paczka.
Zwykle nie instalujesz jej samodzielnie: używa jej KptBackdrop z @konce-pt/angular
i z @konce-pt/react. Sięgnij po nią wprost, gdy liczysz barwy po swojej stronie.
npm i @konce-pt/colorimport { clampToGamut, formatOklch, parseOklch, apcaLc, parseHexColor } from '@konce-pt/color';
// Odcień marki przeniesiony na tę samą jasność co token biblioteki.
const token = parseOklch('oklch(0.546 0.190 255)');
const brand = { ...token, h: 152 };
formatOklch(clampToGamut(brand)); // 'oklch(0.546 0.161 152)' — nasycenie zbite do gamutu sRGB
// Czy biały napis na tym tle da się przeczytać? |Lc| 75 to próg tekstu podstawowego.
apcaLc(parseHexColor('#ffffff'), parseHexColor('#3b82f6')); // -66.4 → za małoDlaczego po kole, a nie po prostej
Interpolacja w sRGB miesza wartości po gammie i prowadzi przejście przez błoto. Prostokątny OKLab
naprawia jasność, ale dla odcieni leżących naprzeciwko siebie przecina oś achromatyczną: w połowie
przejścia z niebieskiego w żółty zostaje szarość dokładnie tam, gdzie mieszanka ma świecić
najmocniej. mixOklch idzie krótszym łukiem koła z zachowanym nasyceniem, a przystanek bez
nasycenia przejmuje odcień sąsiada — inaczej atan2 na zerowej chromie zwraca kąt przypadkowy
i barwa szarpie.
Z tego samego powodu clampToGamut obniża samo nasycenie, zamiast przycinać składowe RGB:
przycięta po kanałach barwa marki potrafi zmienić odcień o kilkanaście stopni, czyli przestać być
tą barwą.
Dwie miary kontrastu
contrastRatio to WCAG 2.1 — symetryczna liczba 1–21, progi 4.5 (tekst) i 3 (tekst duży,
elementy interfejsu). apcaLc to APCA: wartość ze znakiem, gdzie znak niesie biegunowość
(dodatni — treść ciemna na jasnym tle), a kolejność argumentów ma znaczenie, bo ta sama para
barw czyta się inaczej w każdą stronę. Progi |Lc|: 75 tekst podstawowy, 60 tekst większy,
45 elementy interfejsu.
Pełny opis: llms.txt (EN)
i llms-pl.txt (PL).
Testy
pnpm --filter @konce-pt/color exec node --test "src/**/*.test.ts"Licencja
MIT © konce.pt
