Files
openchamber/packages/ui/src/contexts/theme-embedded-bootstrap.ts
T
Kai Yang 023ec2362e fix(ui): compact embedded chat URLs (#2431)
* fix(ui): keep embedded session chat URLs compact

* test(ui): guard embedded session chat URL length

* fix(ui): sync embedded custom themes

Bootstrap custom themes from parent window so iframe URLs stay compact.

Refs #2423

* docs(ui): clarify theme sync precedence
2026-07-26 15:33:04 +03:00

57 lines
1.5 KiB
TypeScript

import { isEmbeddedSessionChat } from '@/components/layout/contextPanelEmbeddedChat';
import type { Theme } from '@/types/theme';
import { isValidTheme } from './theme-validation';
type ThemeBootstrapWindow = Window & {
__openchamberEmbeddedThemeBootstrap?: unknown;
};
export const readEmbeddedThemeSearchParams = (): URLSearchParams | null => {
if (!isEmbeddedSessionChat()) {
return null;
}
return new URLSearchParams(window.location.search);
};
export const publishEmbeddedThemeBootstrap = (theme: Theme): void => {
if (typeof window === 'undefined') {
return;
}
(window as ThemeBootstrapWindow).__openchamberEmbeddedThemeBootstrap = theme;
};
export const readEmbeddedThemeBootstrap = (): Theme | null => {
if (!isEmbeddedSessionChat()) {
return null;
}
try {
const parent = window.parent as ThemeBootstrapWindow;
if (parent === window) {
return null;
}
return isValidTheme(parent.__openchamberEmbeddedThemeBootstrap)
? parent.__openchamberEmbeddedThemeBootstrap
: null;
} catch {
return null;
}
};
const getSystemPreference = (): boolean => {
if (typeof window === 'undefined') {
return true;
}
return window.matchMedia('(prefers-color-scheme: dark)').matches;
};
export const getInitialSystemPreference = (): boolean => {
const embeddedParams = readEmbeddedThemeSearchParams();
const embeddedVariant = embeddedParams?.get('themeVariant');
if (embeddedVariant === 'dark' || embeddedVariant === 'light') {
return embeddedVariant === 'dark';
}
return getSystemPreference();
};