@rnzeus/harmonia
v0.1.3
Published
Typed colour registry + utilities for React Native / TypeScript
Readme
@rnzeus/harmonia
Typed colour registry + utilities for React Native / TypeScript.
Why
Design tokens tend to drift over time. You start with a clean UI kit, then designers gradually introduce random colours (different HEX / alpha variants), and your codebase ends up with a giant misc bucket.
This package helps you:
- keep a typed palette (
list) and typed aliases (aliases) usingas const - use
pick()with autocomplete (token names + palette hexes) - get consistent output in RN (
#RRGGBBAAvia.rn()) - choose readable text colour via
autoText() - safely handle “designer went wild” colours without leaking them into tokens
Install
yarn add @rnzeus/harmonia
# or
npm i @rnzeus/harmoniaUsage
Create a single instance in your app init (not inside JSX):
import { createColour } from '@rnzeus/harmonia';
export const MY_LIST = [
'#6C00F6',
'#865BFF',
'#191919',
'#FFFFFF',
'#000000',
] as const;
export const MY_ALIASES = {
primary: '#6C00F6',
border: '#FFFFFF',
text: '#191919',
} as const;
export const Colour = createColour({
list: MY_LIST,
aliases: MY_ALIASES,
strict: __DEV__,
debug: __DEV__,
fallback: '#FF00FF',
});Then anywhere:
Colour.pick('primary').rn();
Colour.pick('#865BFF').darken(0.1).rn();
Colour.mix('primary', '#FFFFFF', 0.2).rn();
Colour.contrast('text', 'primary');Configuration
createColour() accepts a configuration object that defines how the colour system behaves.
export const Colour = createColour({
list: MY_LIST,
aliases: MY_ALIASES,
// errors
strict: __DEV__,
fallback: '#FF00FF',
onError: (error, context) => {
console.warn('[Colour]', error.message, context);
},
// debug (one-time init log)
debug: __DEV__,
// autoText defaults
textCandidates: ['#FFFFFF', '#000000'],
textMinContrast: 4.5,
textPrefer: 'first-pass',
});autoText defaults
Most apps can keep the defaults, but you can customise them if needed:
export const Colour = createColour({
list: MY_LIST,
aliases: MY_ALIASES,
strict: __DEV__,
debug: __DEV__,
// Example: prefer max contrast and allow a brand colour as candidate
textCandidates: ['#FFFFFF', '#000000', 'primary'],
textMinContrast: 4.5,
textPrefer: 'max-contrast',
});autoText usage
autoText() helps you pick a readable text colour for a given background.
By default, it chooses between #FFFFFF and #000000 using WCAG contrast (≥ 4.5).
// background can be a token or any valid hex
const text = Colour.autoText('primary').rn();Custom candidates
You can provide your own candidates (tokens or hex values):
const text = Colour.autoText('#101010', ['text', '#FFFFFF', '#B3FF00']).rn();Strategy & contrast threshold
const text = Colour.autoText('bg.primary', ['#FFFFFF', '#000000'], {
prefer: 'max-contrast',
minContrast: 4.5,
}).rn();This is useful when:
- designers introduce unexpected background colours
- you want predictable readable text without adding more tokens
Debug
If debug: true, it logs one compact summary on init:
- strict / fallback
- tokens list
- palette size + canonical palette (
#RRGGBBAA)
License
MIT
