Temas de Iframe
Chastify envía información del tema a las extensiones de iframe para que su interfaz de usuario pueda coincidir con la página de bloqueo donde está incrustada.
No asuma que el usuario está utilizando un tema oscuro. Su extensión puede abrirse con temas claros, oscuros, personalizados, translúcidos y de alto contraste.
La opción predeterminada más segura es tratar la carga útil del iframe ui como la fuente de información principal para el fondo de la página, el color del texto y el color del borde, y luego derivar sus propios paneles e insignias legibles de ui.isDark.
Carga útil del tema
Cuando Chastify abre su iframe, agrega una carga útil JSON codificada en URI a location.hash.
La carga útil incluye ui:
{
"bridge": {
"v": 1,
"nonce": "request-nonce",
"parentOrigin": "https://chastify.net"
},
"sessionId": "extension-session-id",
"lockId": "lock-id",
"ui": {
"isDark": true,
"bg": "rgb(10, 10, 10)",
"text": "#e5e7eb",
"border": "#27272a"
}
}
Significados de los campos:
ui.isDark: indica si la página principal está utilizando actualmente un tema oscuro.ui.bg: fondo de página/superficie del host. Puede ser un color o un fondo CSS complejo.ui.text: color principal del texto legible.ui.border: color del borde que coincide con el tema del host.
ui.bg puede ser una cadena de fondo CSS completa, no solo un color hexadecimal. Úselo como un valor CSS background, no como un valor que deba analizar manualmente.
Analizar el hash
type ChastifyThemePayload = {
ui?: {
isDark?: boolean;
bg?: string;
text?: string;
border?: string;
};
};
export function parseHashPayload(): ChastifyThemePayload | null {
const raw = window.location.hash.startsWith("#")
? window.location.hash.slice(1)
: window.location.hash;
if (!raw) return null;
try {
return JSON.parse(decodeURIComponent(raw));
} catch {
return null;
}
}
Variables CSS mínimas
Convierte la carga útil en variables CSS una sola vez al iniciar el sistema:
const payload = parseHashPayload();
const ui = payload?.ui ?? {};
const isDark = ui.isDark !== false;
document.documentElement.style.setProperty("--chastify-bg", ui.bg || (isDark ? "#040711" : "#f8fafc"));
document.documentElement.style.setProperty("--chastify-text", ui.text || (isDark ? "#e5e7eb" : "#0f172a"));
document.documentElement.style.setProperty("--chastify-border", ui.border || (isDark ? "#27272a" : "#e2e8f0"));
document.documentElement.dataset.themeMode = isDark ? "dark" : "light";
Utilice esas variables en el shell de su aplicación:
html,
body,
#root {
min-height: 100%;
margin: 0;
}
body {
background: var(--chastify-bg);
color: var(--chastify-text);
}
.panel {
border: 1px solid var(--chastify-border);
}
Ejemplo de React
import { useMemo } from "react";
function getTheme(payload: any) {
const ui = payload?.ui ?? {};
const isDark = ui.isDark !== false;
return {
isDark,
pageStyle: {
background: ui.bg || (isDark ? "#040711" : "#f8fafc"),
color: ui.text || (isDark ? "#e5e7eb" : "#0f172a"),
} satisfies React.CSSProperties,
panelClass: isDark
? "border-white/10 bg-black/35 text-slate-100"
: "border-slate-200 bg-white/85 text-slate-950 shadow-sm",
mutedClass: isDark ? "text-slate-400" : "text-slate-600",
badgeClass: isDark
? "bg-sky-400/15 text-sky-200"
: "bg-sky-50 text-sky-900 ring-1 ring-sky-200",
};
}
export function ExtensionApp({ payload }: { payload: any }) {
const theme = useMemo(() => getTheme(payload), [payload]);
return (
<main style={theme.pageStyle} className="min-h-screen p-4">
<section className={`rounded-2xl border p-4 ${theme.panelClass}`}>
<h1 className="text-xl font-bold">My Extension</h1>
<p className={`mt-2 text-sm ${theme.mutedClass}`}>
This text stays readable on light and dark Chastify themes.
</p>
<span className={`mt-3 inline-flex rounded-full px-3 py-1 text-xs font-semibold ${theme.badgeClass}`}>
Connected
</span>
</section>
</main>
);
}
Patrón de viento de cola
Si utiliza Tailwind, cree una bifurcación desde ui.isDark para cada superficie que contenga texto.
const isDarkTheme = payload?.ui?.isDark !== false;
const panelClass = isDarkTheme
? "border-white/10 bg-black/30 text-slate-100"
: "border-slate-200 bg-white/85 text-slate-950 shadow-sm";
const successClass = isDarkTheme
? "border-emerald-300/20 bg-emerald-400/10 text-emerald-100"
: "border-emerald-500/25 bg-emerald-50 text-emerald-950";
const errorClass = isDarkTheme
? "border-rose-300/20 bg-rose-400/10 text-rose-100"
: "border-rose-500/25 bg-rose-50 text-rose-950";
Utilice las clases elegidas donde se renderiza el texto:
<div className={`rounded-xl border px-3 py-2 text-sm ${result.ok ? successClass : errorClass}`}>
<div className="font-semibold">{result.title}</div>
<div className="mt-1 opacity-85">{result.message}</div>
</div>
Actualizaciones de temas en vivo
El padre puede enviar actualizaciones de tema en tiempo real mientras su iframe esté abierto:
type UiUpdateMessage = {
type: "chastify:ext:ui";
v: 1;
nonce: string;
ui: {
isDark?: boolean;
bg?: string;
text?: string;
border?: string;
};
};
Escucha ese mensaje y verifica el nonce:
const nonce = payload.bridge.nonce;
const parentOrigin = payload.bridge.parentOrigin;
window.addEventListener("message", (event) => {
if (event.origin !== parentOrigin) return;
const msg = event.data as Partial<UiUpdateMessage>;
if (msg.type !== "chastify:ext:ui" || msg.v !== 1) return;
if (msg.nonce !== nonce) return;
applyTheme(msg.ui);
});
Errores comunes
- Codificar de forma fija
text-whiteotext-*-100pálido dentro de las tarjetas sin una alternativa de tema claro. - Se está dando estilo al fondo de la página, pero se han olvidado las tarjetas anidadas, las insignias, los anillos de progreso y los feeds de resultados.
- Tratar
ui.bgcomo un simple color hexadecimal. Podría ser un degradado o una cadena de fondo CSS normalizada por el navegador. - Al usar controles de formulario nativos sin configurar el color de fondo ni el color del texto, las opciones de selección pueden volverse ilegibles en temas oscuros.
- Se asume que es necesario recargar el iframe para los cambios de tema. Esté atento a
chastify:ext:uisi desea recibir actualizaciones en tiempo real.
Los datos del tema son solo datos de presentación. No los utilice para autorización, decisiones de confianza, lógica de desbloqueo, recompensas, castigos ni identidad de sesión del backend.
Lista de verificación
Antes de publicar su extensión iframe:
- Tema de luz de prueba.
- Prueba el tema oscuro.
- Pruebe un tema personalizado si está disponible.
- Verifique que todas las tarjetas, botones, insignias, controles de formulario, anillos de progreso y mensajes de resultados tengan un contraste legible.
- Comprueba que el texto siga cabiendo en el móvil.
- Verifica que el iframe cambie de tamaño automáticamente después de cambios de tema o contenido.
Siguiente: Inicio rápido de Iframe o Ejemplos de API.