UNPKG

flowbite-svelte

Version:

Flowbite components for Svelte

74 lines (73 loc) 3.13 kB
import {} from ".."; import { getContext } from "svelte"; // import { dev } from "$app/environment"; // for svelte users not using sveltekit substitute the above line with the following line const dev = import.meta.env.MODE === "development"; export function getTheme(componentKey) { const theme = getContext("theme"); return theme?.[componentKey]; } /** * Warns about deprecated theme-related props and suggests modern alternatives. * * Shows the component name, deprecated props, migration hints, and usage location (in dev mode). * * @param component - Name of the component using deprecated props. * @param names - Record of deprecated prop names and their values. * @param replacements - Optional map of deprecated keys to their replacements (e.g., "divClass" → "div"). */ export function warnThemeDeprecation(component, names, replacements) { if (!dev) return; const nonEmptyNames = Object.keys(names).filter((name) => names[name]); if (nonEmptyNames.length === 0) return; let migrationHint = ""; const usesClass = nonEmptyNames.some((name) => replacements?.[name] === "class"); const propText = usesClass ? `"classes" or "class"` : `"classes"`; if (replacements) { const classProps = []; const classesObjectEntries = []; for (const name of nonEmptyNames) { const newKey = replacements[name]; const value = names[name]; if (!newKey || !value) continue; if (newKey === "class") { classProps.push(`class="${value}"`); } else { classesObjectEntries.push(`${newKey}: "${value}"`); } } const hintLines = []; if (classProps.length > 0) hintLines.push(...classProps); if (classesObjectEntries.length > 0) { hintLines.push(`classes={{ ${classesObjectEntries.join(", ")} }}`); } if (hintLines.length > 0) { migrationHint = `\nMigration example: ${hintLines.join(" ")}`; } } // Stack trace parsing to find external caller const stack = new Error().stack; const externalCaller = getExternalCaller(stack); console.warn(`⚠️ The following "${component}" props are deprecated: ${nonEmptyNames.map((n) => `"${n}"`).join(", ")}.\n` + `💡 Please use the ${propText} prop instead.${migrationHint}\n` + (externalCaller ? `🔍 Used at: ${externalCaller}` : "")); } // Extracts the first file in the stack trace that is NOT the current component file function getExternalCaller(stack) { if (!stack) return null; const lines = stack.split("\n").slice(2); // skip "Error" and self-call const currentFileMatch = lines[0]?.match(/(?:\()?(.*?\.svelte):\d+:\d+\)?$/); const currentFile = currentFileMatch?.[1]; for (const line of lines) { const match = line.match(/(?:\()?(.*?\.svelte):\d+:\d+\)?$/); const file = match?.[1]; if (file && file !== currentFile) { return line.trim().replace(/^at /, ""); // Clean format } } return null; }