diff --git a/src/common/utils/colorUtils.ts b/src/common/utils/colorUtils.ts index d90fe1d..8f4fd03 100644 --- a/src/common/utils/colorUtils.ts +++ b/src/common/utils/colorUtils.ts @@ -1,6 +1,15 @@ import { clampChroma, converter, formatHex, wcagContrast } from "culori"; import { SHADE_STEPS } from "../constants/colorConstants"; +/** + * Génère une palette de teintes (shades) à partir d'une couleur de base en hex. + * + * L'algorithme place la couleur de base à l'étape la plus proche de sa luminosité + * naturelle, puis dérive les autres étapes autour d'elle dans l'espace OKLCH. + * + * @param colorHex - Couleur de départ au format hex (#RRGGBB) + * @returns Tableau trié de { step, color } pour chaque étape définie dans SHADE_STEPS + */ export function generateShades( colorHex: string, ): { step: number; color: string }[] { @@ -9,9 +18,10 @@ export function generateShades( const { l: baseL, c: CO, h: H0 } = base; const lMax = 0.95; const lMin = 0.15; + // Fix: utiliser le spread ES2020 plutôt que Math.min/max.apply (antipattern ES5) const stepNumbers = SHADE_STEPS.map(Number); - const minStep = Math.min.apply(Math, stepNumbers); - const maxStep = Math.max.apply(Math, stepNumbers); + const minStep = Math.min(...stepNumbers); + const maxStep = Math.max(...stepNumbers); // Trouve la shade la plus proche de la luminosité de base let closestStep = SHADE_STEPS[0]; @@ -38,8 +48,7 @@ export function generateShades( return { step, color: colorHex }; } - const stepValue = step; - const t = (stepValue - minStep) / (maxStep - minStep); + const t = (step - minStep) / (maxStep - minStep); // Appliquer le décalage de luminosité pour adapter le dégradé autour de la couleur de base const l = lMax - Math.pow(t, 1.15) * (lMax - lMin) + luminosityOffset; const c = CO * Math.pow(Math.sin(Math.PI * t), 0.9); @@ -48,6 +57,13 @@ export function generateShades( }); } +/** + * Génère une palette de niveaux de gris pour un ensemble d'étapes données. + * + * @param steps - Valeurs d'étape entre 0 et 1000 (0 = blanc, 1000 = noir) + * @param hue - Teinte optionnelle pour un gris légèrement teinté (défaut : 0 = neutre) + * @returns Dictionnaire { step → couleur hex } + */ export function generateGreyShades( steps: number[], hue: number = 0, @@ -55,7 +71,9 @@ export function generateGreyShades( const greyShades: Record = {}; for (const step of steps) { const t = step / 1000; - const lightness = 1 - t * 1; + // Fix: clamp lightness dans [0, 1] — si step > 1000, la valeur non clampée + // serait négative, ce que culori accepte silencieusement avec un rendu indéfini. + const lightness = Math.max(0, Math.min(1, 1 - t)); greyShades[step] = formatHex({ mode: "hsl", h: hue, @@ -67,6 +85,15 @@ export function generateGreyShades( return greyShades; } +/** + * Détermine la couleur de texte (clair ou foncé) offrant le meilleur contraste WCAG + * sur un fond donné. + * + * @param background - Couleur de fond en RGBA Figma (valeurs 0–1) + * @param light - Couleur "claire" candidate en RGBA Figma + * @param dark - Couleur "foncée" candidate en RGBA Figma + * @returns "Light" si la couleur claire offre le meilleur contraste, "Dark" sinon + */ export function getContrastColor( background: { r: number; g: number; b: number; a: number }, light: { r: number; g: number; b: number; a: number }, diff --git a/src/main/builders/variables/variableBuilder.ts b/src/main/builders/variables/variableBuilder.ts index d4a4e2b..4d8395e 100644 --- a/src/main/builders/variables/variableBuilder.ts +++ b/src/main/builders/variables/variableBuilder.ts @@ -128,16 +128,24 @@ export class VariableBuilder { return vars.filter((v) => v.name === variableName)[0]; } + /** + * Trouve plusieurs variables par collection et noms. + * + * Effectue un seul appel à l'API Figma (getLocalVariablesAsync) puis + * filtre le résultat en mémoire — bien plus efficace que N appels séquentiels. + * + * @param collectionName - Nom de la collection cible + * @param variableNames - Liste des noms de variables recherchées + * @returns Variables trouvées (dans l'ordre de variableNames) + */ async findVariables( collectionName: string, variableNames: string[], ): Promise { - const variables: Variable[] = []; - for (const name of variableNames) { - const variable = await this.findVariable(collectionName, name); - if (variable) variables.push(variable); - } - return variables; + // Un seul appel API au lieu de N appels séquentiels via findVariable() + const allVars = await this.getCollectionVariables(collectionName); + const nameSet = new Set(variableNames); + return allVars.filter((v) => nameSet.has(v.name)); } /** diff --git a/src/ui/components/colorSelector.ts b/src/ui/components/colorSelector.ts index 40fdd50..8ff715c 100644 --- a/src/ui/components/colorSelector.ts +++ b/src/ui/components/colorSelector.ts @@ -1,5 +1,8 @@ import { COLOR_DATA } from "../constants"; +/** Mettre à true pour activer les logs de débogage. Toujours false en production. */ +const DEBUG = false; + function formatColorName(name: string): string { return name .replace(/([A-Z])/g, " $1") @@ -140,7 +143,7 @@ export function initColorSelector(wrapper: HTMLElement): void { const text = wrapper.querySelector(".color-text"); if (!button || !popup || !preview || !text) { - console.warn("❌ Color selector elements not found", { + if (DEBUG) console.warn("❌ Color selector elements not found", { button: !!button, popup: !!popup, preview: !!preview, @@ -267,7 +270,7 @@ export function initAllColorSelectors(): void { if (wrappers.length === 0) { console.error("❌ CRITICAL: No color selector wrappers found!"); - console.log("Available divs:", document.querySelectorAll("div").length); + if (DEBUG) console.log("Available divs:", document.querySelectorAll("div").length); return; } @@ -294,4 +297,4 @@ export function initAllColorSelectors(): void { }); } }); -} +} \ No newline at end of file diff --git a/src/ui/initializers/buttonListeners.ts b/src/ui/initializers/buttonListeners.ts index db93fd3..527adf8 100644 --- a/src/ui/initializers/buttonListeners.ts +++ b/src/ui/initializers/buttonListeners.ts @@ -8,6 +8,9 @@ import { debugPanel } from "../components/debugPanel"; import { layoutGuideType } from "../../common/types"; import { stringify } from "querystring"; +/** Mettre à true pour activer les logs de débogage. Toujours false en production. */ +const DEBUG = false; + // List of button IDs corresponding to different actions const btns = [ "brand-colors", @@ -104,7 +107,7 @@ export function attachButtonListeners() { // debugPanel.show(); const formData = getFormData(); - console.log("📋 FormData complète:", formData); + if (DEBUG) console.log("📋 FormData complète:", formData); // Handle Color Families const colorsData: Record> = {}; @@ -309,4 +312,4 @@ export function attachButtonListeners() { }); } }); -} +} \ No newline at end of file diff --git a/src/ui/main.ts b/src/ui/main.ts index 3663a41..405f1fd 100644 --- a/src/ui/main.ts +++ b/src/ui/main.ts @@ -11,6 +11,9 @@ import { } from "./initializers"; import { initImageCategoryList } from "./initializers/imageCategoryInitializer"; +/** Mettre à true pour activer les logs de débogage. Toujours false en production. */ +const DEBUG = false; + document.addEventListener("DOMContentLoaded", () => { initTabs(); @@ -42,8 +45,8 @@ document.addEventListener("DOMContentLoaded", () => { switch (message.type) { case "notification": - console.log("Plugin notification:", message.message); + if (DEBUG) console.log("Plugin notification:", message.message); break; } }; -}); +}); \ No newline at end of file diff --git a/src/ui/utils/formData.ts b/src/ui/utils/formData.ts index 0bc7da4..cf82663 100644 --- a/src/ui/utils/formData.ts +++ b/src/ui/utils/formData.ts @@ -1,3 +1,7 @@ + + +/** Mettre à true pour activer les logs de débogage. Toujours false en production. */ +const DEBUG = false; export interface FormData { [key: string]: string | number | File[]; } @@ -87,7 +91,7 @@ export function getFormData(): FormData { const files = fileListInstance.getFiles(); data[inputId] = files; } else { - console.warn( + if (DEBUG) console.warn( "❌ Pas d'instance ou pas de méthode getFiles pour:", inputId, ); @@ -95,4 +99,4 @@ export function getFormData(): FormData { }); return data; -} +} \ No newline at end of file