SPB Git forge

spb/qc26

Public
10commits 1branches 0releases
2.8 MBsize
maindefault branch
17 days agolast push
Python 51.6% TypeScript 46.7% CSS 1.7%
4.2 KB · 72 lines typescript
Raw Blame History
1/** Registre des partis côté web — miroir du registre du moteur (engine/qc26/parties.py).2 * Toute couleur ou logo de parti passe par ici : aucun code hex dans les composants. */3import type { PartyId, PartyKey } from "./api";45export interface PartyDef {6  id: PartyId;7  abbreviation: string;8  officialName: string;9  shortName: string;10  color: string;11  secondaryColor: string;12  website: string;13  logo: string;14  logoWhite?: string;15  /** Le logo officiel est blanc : afficher sur une pastille de cette couleur. */16  logoBackdrop?: string;17  logoRatio: number; // largeur / hauteur18  order: number;19}2021export const PARTIES: PartyDef[] = [22  { id: "caq", abbreviation: "CAQ", officialName: "Coalition avenir Québec", shortName: "CAQ", color: "#20A8E0", secondaryColor: "#0B6FA6", website: "https://coalitionavenirquebec.org", logo: "/parties/caq/logo.png", logoWhite: "/parties/caq/logo-white.png", logoRatio: 2560 / 1134, order: 1 },23  { id: "plq", abbreviation: "PLQ", officialName: "Parti libéral du Québec", shortName: "PLQ", color: "#ED1B2D", secondaryColor: "#007AC2", website: "https://plq.org", logo: "/parties/plq/logo.svg", logoWhite: "/parties/plq/logo-white.svg", logoRatio: 516.1 / 278.3, order: 2 },24  { id: "pq", abbreviation: "PQ", officialName: "Parti québécois", shortName: "PQ", color: "#1E295C", secondaryColor: "#4C5B9E", website: "https://pq.org", logo: "/parties/pq/logo.svg", logoWhite: "/parties/pq/wordmark-white.png", logoRatio: 180 / 45, order: 3 },25  { id: "qs", abbreviation: "QS", officialName: "Québec solidaire", shortName: "QS", color: "#FF5505", secondaryColor: "#FFF0A8", website: "https://quebecsolidaire.net", logo: "/parties/qs/logo.svg", logoRatio: 720 / 300, order: 4 },26  { id: "pcq", abbreviation: "PCQ", officialName: "Parti conservateur du Québec", shortName: "PCQ", color: "#6E4C9F", secondaryColor: "#102850", website: "https://conservateur.quebec", logo: "/parties/pcq/logo.svg", logoBackdrop: "#102850", logoRatio: 324 / 79, order: 5 },27];2829export const OTHERS = { id: "aut" as const, abbreviation: "Autres", officialName: "Autres candidatures", color: "#9AA0A6" };30export const PARTY_IDS: PartyId[] = PARTIES.map((p) => p.id);31export const PARTY_BY_ID: Record<string, PartyDef> = Object.fromEntries(PARTIES.map((p) => [p.id, p]));3233export function party(id: string | null | undefined): PartyDef | null {34  return id ? PARTY_BY_ID[id] ?? null : null;35}36export function partyColor(id: string | null | undefined): string {37  if (!id) return "#C4C8CE";38  return PARTY_BY_ID[id]?.color ?? OTHERS.color;39}40export function partyLabel(id: string | null | undefined): string {41  if (!id) return "—";42  return PARTY_BY_ID[id]?.abbreviation ?? OTHERS.abbreviation;43}44export function partyName(id: string | null | undefined): string {45  if (!id) return "—";46  return PARTY_BY_ID[id]?.officialName ?? OTHERS.officialName;47}48/** Ordonne des identifiants de partis par une valeur décroissante. */49export function sortParties<T>(rec: Record<string, T>, key: (v: T) => number, includeOthers = false): [PartyKey, T][] {50  return (Object.entries(rec) as [PartyKey, T][])51    .filter(([id]) => includeOthers || id !== "aut")52    .sort((a, b) => key(b[1]) - key(a[1]));53}54/** Couleur de parti via variable CSS (adaptée au thème clair/sombre dans globals.css). À utiliser dans l'UI ;55 * `partyColor` (hex) reste pour les images OG (satori) et les exports. */56export function partyVar(id: string | null | undefined): string {57  if (!id) return "var(--p-none)";58  return PARTY_BY_ID[id] ? `var(--p-${id})` : "var(--p-aut)";59}60/** Couleur de parti mélangée à la surface : alpha 0…1 → color-mix (thème-safe). */61export function partyAlpha(id: string | null | undefined, alpha: number): string {62  const a = Math.max(0, Math.min(1, alpha));63  return `color-mix(in srgb, ${partyVar(id)} ${Math.round(a * 100)}%, transparent)`;64}65/** Couleur atténuée par une probabilité (incertitude → moins d'opacité). */66export function withAlpha(hex: string, alpha: number): string {67  const h = hex.replace("#", "");68  const n = parseInt(h.length === 3 ? h.split("").map((c) => c + c).join("") : h, 16);69  const r = (n >> 16) & 255, g = (n >> 8) & 255, b = n & 255;70  return `rgba(${r}, ${g}, ${b}, ${Math.max(0, Math.min(1, alpha)).toFixed(3)})`;71}72