export { Verdana110 as calcWidth } from './calc-text-width' import { Verdana110 as calcWidth } from './calc-text-width' import colorPresets from './color-presets' export type StyleOption = 'flat' | 'classic' export type ColorPreset = keyof typeof colorPresets export interface BadgenOptions { status: string; subject?: string; color?: ColorPreset; label?: string; labelColor?: string style?: StyleOption; icon?: string; iconWidth?: number; scale?: number } export function badgen ({ label, subject, status, color = 'blue', style, icon, iconWidth = 13, labelColor = '555', scale = 1 }: BadgenOptions) { typeAssert(typeof status === 'string', ' must be string') label = label === undefined ? subject : label // subject is deprecated if (!label && !icon) { return bare({ status, color, style, scale }) } color = colorPresets[color] || color labelColor = colorPresets[labelColor] || labelColor iconWidth = iconWidth * 10 const iconSpanWidth = icon ? (label?.length ? iconWidth + 30 : iconWidth - 18) : 0 const sbTextStart = icon ? (iconSpanWidth + 50) : 50 const sbTextWidth = label ? calcWidth(label) : 0 const stTextWidth = calcWidth(status) const sbRectWidth = sbTextWidth + 100 + iconSpanWidth const stRectWidth = stTextWidth + 100 const width = sbRectWidth + stRectWidth const xlink = icon ? ' xmlns:xlink="http://www.w3.org/1999/xlink"' : '' const gradientId = generateRandomID(5) const maskId = generateRandomID(5) label = label ? sanitize(label) : '' status = sanitize(status) color = sanitize(color) labelColor = sanitize(labelColor) icon = icon ? sanitize(icon) : icon const accessibleText = createAccessibleText({label, status}) if (style === 'flat') { return ` ${accessibleText} ${icon ? `` : ''} ` } return ` ${accessibleText} ${icon ? `` : ''} ` } function bare ({ status, color = 'blue', style, scale = 1 }: BadgenOptions) { typeAssert(typeof status === 'string', ' must be string') color = colorPresets[color] || color || colorPresets.blue const stTextWidth = calcWidth(status) const stRectWidth = stTextWidth + 115 const gradientId = generateRandomID(5) const maskId = generateRandomID(5) status = sanitize(status) color = sanitize(color) if (style === 'flat') { return ` ${status} ` } return ` ${status} ` } function sanitize (str: string): string { return str .replace(/\u0026/g, '&') .replace(/\u003C/g, '<') .replace(/\u003E/g, '>') .replace(/\u0022/g, '"') .replace(/\u0027/g, ''') } interface AccessibleTextProps { status: string; label?: string; } function generateRandomID(length: number): string { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; let result = ''; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } return result; } function createAccessibleText({label, status}: AccessibleTextProps): string { const labelPrefix = label ? `${label}: ` : ''; return labelPrefix + status; } function typeAssert (assertion: boolean, message: string): void { if (!assertion) throw new TypeError(message) } declare global { interface Window { badgen: typeof badgen; } } if (typeof window === 'object') { window.badgen = badgen }