-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinlineTextStyles.ts
More file actions
118 lines (102 loc) · 2.99 KB
/
inlineTextStyles.ts
File metadata and controls
118 lines (102 loc) · 2.99 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import {
DEFAULT_COLOR_PRESETS,
type ColorPickerPreset,
} from '@univers42/ui-collection';
export interface InlineColorOption extends ColorPickerPreset {
id: string;
textColor: string;
backgroundColor: string;
swatch: string;
}
const LEGACY_INLINE_COLOR_ALIASES: Record<string, string> = {
gray: '#334155',
brown: '#F59E0B',
orange: '#F59E0B',
yellow: '#F59E0B',
green: '#10B981',
blue: '#0EA5E9',
purple: '#4F46E5',
pink: '#F43F5E',
red: '#F43F5E',
slate: '#334155',
indigo: '#4F46E5',
sky: '#0EA5E9',
emerald: '#10B981',
amber: '#F59E0B',
rose: '#F43F5E',
white: '#FFFFFF',
black: '#0F172A',
};
function normalizeHexColor(value: string | undefined | null): string | null {
if (!value) {
return null;
}
const normalized = value.trim().toUpperCase();
if (/^#[0-9A-F]{6}$/.test(normalized) || /^#[0-9A-F]{8}$/.test(normalized)) {
return normalized;
}
const shortMatch = normalized.match(/^#([0-9A-F]{3,4})$/);
if (!shortMatch) {
const rgbMatch = normalized.match(
/^RGBA?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(?:\d+|\d*\.\d+))?\s*\)$/,
);
if (!rgbMatch) {
return null;
}
const rgb = rgbMatch.slice(1, 4).map((channel) =>
Number.parseInt(channel, 10).toString(16).padStart(2, '0').toUpperCase(),
);
return `#${rgb.join('')}`;
}
const [r, g, b, a] = shortMatch[1].split('');
return a
? `#${r}${r}${g}${g}${b}${b}${a}${a}`
: `#${r}${r}${g}${g}${b}${b}`;
}
function hexToRgba(hex: string, alpha: number) {
const normalized = normalizeHexColor(hex);
if (!normalized) {
return `rgba(15, 23, 42, ${alpha})`;
}
const r = Number.parseInt(normalized.slice(1, 3), 16);
const g = Number.parseInt(normalized.slice(3, 5), 16);
const b = Number.parseInt(normalized.slice(5, 7), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
function createInlineColorOption(label: string, hex: string): InlineColorOption {
return {
id: hex,
label,
value: hex,
textColor: hex,
backgroundColor: hexToRgba(hex, 0.18),
swatch: hex,
};
}
export const INLINE_COLOR_OPTIONS: InlineColorOption[] = DEFAULT_COLOR_PRESETS
.map((preset) => {
const hex = normalizeHexColor(preset.value);
return hex ? createInlineColorOption(preset.label, hex) : null;
})
.filter((option): option is InlineColorOption => option !== null);
const INLINE_COLOR_MAP = new Map(
INLINE_COLOR_OPTIONS.map((option) => [option.id, option] as const),
);
export function normalizeInlineColorToken(token: string) {
const normalizedHex = normalizeHexColor(token);
if (normalizedHex) {
return normalizedHex;
}
const alias = token.trim().toLowerCase();
return LEGACY_INLINE_COLOR_ALIASES[alias] ?? null;
}
export function getInlineColorOption(colorId: string) {
const normalizedColor = normalizeInlineColorToken(colorId);
if (!normalizedColor) {
return undefined;
}
return (
INLINE_COLOR_MAP.get(normalizedColor) ??
createInlineColorOption(normalizedColor, normalizedColor)
);
}