feat(say-server): add light/dark theme support (#338)
- Add importmap entry for main SDK exports (applyDocumentTheme, etc.) - Import and apply host theme and styles on context changes - Apply initial host context theme/styles when app connects - Update CSS to use [data-theme="dark"] selector for host-provided themes - Keep @media prefers-color-scheme as fallback for standalone mode - Add color-scheme meta tag for native element theming
This commit is contained in:
parent
89f58bf555
commit
8c4168a092
1 changed files with 30 additions and 1 deletions
|
|
@ -672,6 +672,7 @@ EMBEDDED_VIEW_HTML = """<!DOCTYPE html>
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<title>Say View</title>
|
||||
<script src="https://unpkg.com/@babel/standalone@7.26.10/babel.min.js"></script>
|
||||
<script type="importmap">
|
||||
|
|
@ -679,6 +680,7 @@ EMBEDDED_VIEW_HTML = """<!DOCTYPE html>
|
|||
"imports": {
|
||||
"react": "https://esm.sh/react@19.2.0",
|
||||
"react-dom/client": "https://esm.sh/react-dom@19.2.0/client",
|
||||
"@modelcontextprotocol/ext-apps": "https://esm.sh/@modelcontextprotocol/ext-apps@0.4.1?deps=zod@3.25.1&external=react,react-dom",
|
||||
"@modelcontextprotocol/ext-apps/react": "https://esm.sh/@modelcontextprotocol/ext-apps@0.4.1/react?deps=zod@3.25.1&external=react,react-dom"
|
||||
}
|
||||
}
|
||||
|
|
@ -769,8 +771,14 @@ EMBEDDED_VIEW_HTML = """<!DOCTYPE html>
|
|||
.infoPopup a:hover { text-decoration: underline; }
|
||||
.infoPopup ul { margin: 0; padding-left: 16px; }
|
||||
.infoPopup li { margin: 4px 0; }
|
||||
/* Dark mode: host-provided theme via data-theme attribute */
|
||||
[data-theme="dark"] {
|
||||
--color-text-primary: #eee;
|
||||
--color-text-secondary: #666;
|
||||
}
|
||||
/* Fallback: system preference when running standalone without host */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
:root:not([data-theme]) {
|
||||
--color-text-primary: #eee;
|
||||
--color-text-secondary: #666;
|
||||
}
|
||||
|
|
@ -783,6 +791,7 @@ EMBEDDED_VIEW_HTML = """<!DOCTYPE html>
|
|||
import React, { useState, useCallback, useEffect, useRef, StrictMode } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { useApp } from '@modelcontextprotocol/ext-apps/react';
|
||||
import { applyDocumentTheme, applyHostStyleVariables, applyHostFonts } from '@modelcontextprotocol/ext-apps';
|
||||
|
||||
function SayView() {
|
||||
const [hostContext, setHostContext] = useState(undefined);
|
||||
|
|
@ -1251,6 +1260,16 @@ EMBEDDED_VIEW_HTML = """<!DOCTYPE html>
|
|||
if (params.displayMode) {
|
||||
setDisplayMode(params.displayMode);
|
||||
}
|
||||
// Apply host theme and styles
|
||||
if (params.theme) {
|
||||
applyDocumentTheme(params.theme);
|
||||
}
|
||||
if (params.styles?.variables) {
|
||||
applyHostStyleVariables(params.styles.variables);
|
||||
}
|
||||
if (params.styles?.css?.fonts) {
|
||||
applyHostFonts(params.styles.css.fonts);
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
@ -1265,6 +1284,16 @@ EMBEDDED_VIEW_HTML = """<!DOCTYPE html>
|
|||
if (ctx?.displayMode) {
|
||||
setDisplayMode(ctx.displayMode);
|
||||
}
|
||||
// Apply initial host theme and styles
|
||||
if (ctx?.theme) {
|
||||
applyDocumentTheme(ctx.theme);
|
||||
}
|
||||
if (ctx?.styles?.variables) {
|
||||
applyHostStyleVariables(ctx.styles.variables);
|
||||
}
|
||||
if (ctx?.styles?.css?.fonts) {
|
||||
applyHostFonts(ctx.styles.css.fonts);
|
||||
}
|
||||
}, [app]);
|
||||
|
||||
// Speak lock: coordinate with other TTS Views
|
||||
|
|
|
|||
Loading…
Reference in a new issue