forked from Creditra/Creditra-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcolorFromId.ts
More file actions
76 lines (71 loc) · 2.24 KB
/
Copy pathcolorFromId.ts
File metadata and controls
76 lines (71 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* Deterministic color identity for account / entity scanning.
*
* Maps a stable string id to a palette color so list rows and cards keep a
* consistent left-edge stripe across renders and sessions. Used by linked
* accounts (and reusable anywhere a per-entity color stripe is needed).
*
* Accessibility:
* - Palette colors are drawn from design tokens with ≥ 3:1 contrast against
* `--surface` (#161b22) for non-text UI components (WCAG 1.4.11).
* - Callers must not rely on color alone — pair the stripe with a text label
* (WCAG 1.4.1 Use of Color).
*/
import type { CSSProperties } from 'react';
import { COLOR } from './tokens';
/**
* Fixed accent palette for per-account color stripes.
* Order is stable — never re-order without migrating persisted UI expectations.
*/
export const ACCOUNT_STRIPE_PALETTE: readonly string[] = [
COLOR.accent, // blue
COLOR.success, // green
COLOR.warning, // amber
'#a371f7', // purple — AA ≥ 3:1 on #161b22
'#39d0d8', // teal
COLOR.danger, // red
] as const;
/**
* djb2 XOR hash — identical algorithm to `lineAccentColor` in tokens.ts so
* credit-line and account identities stay consistent if they share an id.
*/
function hashId(id: string): number {
let hash = 5381;
for (let i = 0; i < id.length; i++) {
hash = ((hash << 5) + hash) ^ id.charCodeAt(i);
hash = hash | 0;
}
return hash;
}
/**
* Map any stable string id to a palette color.
*
* @param id Account / entity identifier (e.g. linked-account UUID).
* @returns One of `ACCOUNT_STRIPE_PALETTE` — same id → same color always.
*
* @example
* colorFromId('acct-google-1') // => '#58a6ff' (stable)
*/
export function colorFromId(id: string): string {
if (!id) {
return ACCOUNT_STRIPE_PALETTE[0];
}
const hash = hashId(id);
return ACCOUNT_STRIPE_PALETTE[Math.abs(hash) % ACCOUNT_STRIPE_PALETTE.length];
}
/**
* Zero-width CSS style for a 3 px left-edge identity stripe.
* Absolute positioning keeps layout width unchanged (no CLS).
*/
export function accountStripeStyle(id: string): CSSProperties {
return {
position: 'absolute',
top: 0,
left: 0,
width: 3,
height: '100%',
background: colorFromId(id),
borderRadius: '4px 0 0 4px',
pointerEvents: 'none',
};
}