mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix(webchat): align demo and widget theme tokens
This commit is contained in:
parent
1b198e3d08
commit
924d056b79
119
mateclaw-webchat/index.html
Normal file
119
mateclaw-webchat/index.html
Normal file
@ -0,0 +1,119 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>MateClaw WebChat Demo</title>
|
||||
<style>
|
||||
:root {
|
||||
--mc-font-body: 'Inter', 'Avenir Next', 'SF Pro Display', 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
--mc-text-sm: 13px;
|
||||
--mc-text-base: 15px;
|
||||
--mc-radius-md: 12px;
|
||||
--mc-radius-full: 9999px;
|
||||
--mc-primary: #d96d46;
|
||||
--mc-primary-hover: #bb4f27;
|
||||
--mc-bg: #f6f1ea;
|
||||
--mc-bg-elevated: #ffffff;
|
||||
--mc-bg-muted: #f1e8df;
|
||||
--mc-border-light: #ebe3db;
|
||||
--mc-text-primary: #1d1612;
|
||||
--mc-text-secondary: #665245;
|
||||
--mc-text-inverse: #ffffff;
|
||||
--mc-shadow-medium: 0 18px 48px rgba(58, 32, 19, 0.12);
|
||||
--mc-shadow-strong: 0 24px 70px rgba(58, 32, 19, 0.16);
|
||||
--mc-chat-bg: #fafaf8;
|
||||
--mc-chat-header-bg: #ffffff;
|
||||
--mc-assistant-bubble-bg: #ffffff;
|
||||
--mc-assistant-bubble-border: #ddd5cc;
|
||||
--mc-assistant-bubble-color: #1c1410;
|
||||
--mc-user-bubble-bg: #d97757;
|
||||
--mc-user-bubble-color: #ffffff;
|
||||
--mc-input-bg: #fafaf8;
|
||||
--mc-input-border: #ddd5cc;
|
||||
--mc-input-text: #1c1410;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--mc-bg);
|
||||
color: var(--mc-text-primary);
|
||||
font-family: var(--mc-font-body);
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 760px;
|
||||
padding: 48px 32px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 12px;
|
||||
font-size: 28px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: var(--mc-text-secondary);
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>MateClaw WebChat Demo</h1>
|
||||
<p>点击右下角按钮打开 WebChat。本页面会模拟流式接口,方便本地预览组件交互。</p>
|
||||
</main>
|
||||
|
||||
<script type="module">
|
||||
import { init } from './src/index.ts'
|
||||
|
||||
const originalFetch = window.fetch.bind(window)
|
||||
|
||||
window.fetch = async (input, initOptions) => {
|
||||
const url = typeof input === 'string' ? input : input.url
|
||||
if (url.includes('/api/v1/channels/webchat/stream')) {
|
||||
const body = JSON.parse(String(initOptions?.body || '{}'))
|
||||
const encoder = new TextEncoder()
|
||||
|
||||
return new Response(
|
||||
new ReadableStream({
|
||||
start(controller) {
|
||||
const chunks = [
|
||||
`data: ${JSON.stringify({ text: `收到:${body.message || ''}` })}\n\n`,
|
||||
`data: ${JSON.stringify({ text: '\\n这是本地 demo 的模拟流式回复。' })}\n\n`,
|
||||
'event: done\n\n',
|
||||
]
|
||||
|
||||
chunks.forEach((chunk, index) => {
|
||||
setTimeout(() => {
|
||||
controller.enqueue(encoder.encode(chunk))
|
||||
if (index === chunks.length - 1) controller.close()
|
||||
}, index * 220)
|
||||
})
|
||||
},
|
||||
}),
|
||||
{
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'text/event-stream' },
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return originalFetch(input, initOptions)
|
||||
}
|
||||
|
||||
init({
|
||||
apiKey: 'dev-key',
|
||||
server: location.origin,
|
||||
title: 'MateClaw WebChat',
|
||||
primaryColor: 'var(--mc-primary, #D97757)',
|
||||
subtitle: '本地预览',
|
||||
welcomeMessage: '我是 MateClaw WebChat,本页面用于本地开发预览。',
|
||||
quickPrompts: ['分析这个问题', '给我执行建议', '你能做哪些事情?'],
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -15,7 +15,7 @@ export interface WebChatConfig {
|
||||
server: string
|
||||
/** Widget position */
|
||||
position?: 'bottom-right' | 'bottom-left'
|
||||
/** Primary color (hex) */
|
||||
/** Primary color (CSS color). Defaults to MateClaw UI token. */
|
||||
primaryColor?: string
|
||||
/** Widget title */
|
||||
title?: string
|
||||
@ -30,7 +30,7 @@ interface Message {
|
||||
|
||||
const DEFAULT_CONFIG: Partial<WebChatConfig> = {
|
||||
position: 'bottom-right',
|
||||
primaryColor: '#409eff',
|
||||
primaryColor: 'var(--mc-primary, #D97757)',
|
||||
title: 'MateClaw',
|
||||
placeholder: 'Type a message...',
|
||||
}
|
||||
@ -58,6 +58,13 @@ function generateId(): string {
|
||||
function injectStyles() {
|
||||
const style = document.createElement('style')
|
||||
style.textContent = `
|
||||
.mc-webchat-bubble,
|
||||
.mc-webchat-panel,
|
||||
.mc-webchat-panel * {
|
||||
box-sizing: border-box;
|
||||
font-family: var(--mc-font-body, 'Inter', 'Avenir Next', 'SF Pro Display', 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.mc-webchat-bubble {
|
||||
position: fixed;
|
||||
${config.position === 'bottom-left' ? 'left: 20px' : 'right: 20px'};
|
||||
@ -66,10 +73,10 @@ function injectStyles() {
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
background: ${config.primaryColor};
|
||||
color: white;
|
||||
color: var(--mc-text-inverse, #ffffff);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
box-shadow: var(--mc-shadow-medium, 0 18px 48px rgba(58, 32, 19, 0.12));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@ -83,29 +90,31 @@ function injectStyles() {
|
||||
bottom: 88px;
|
||||
width: 380px;
|
||||
height: 520px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.12);
|
||||
background: var(--mc-bg-elevated, #ffffff);
|
||||
color: var(--mc-text-primary, #1d1612);
|
||||
border: 1px solid var(--mc-border-light, #ebe3db);
|
||||
border-radius: var(--mc-radius-md, 12px);
|
||||
box-shadow: var(--mc-shadow-strong, 0 24px 70px rgba(58, 32, 19, 0.16));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 99999;
|
||||
overflow: hidden;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
.mc-webchat-header {
|
||||
padding: 14px 16px;
|
||||
background: ${config.primaryColor};
|
||||
color: white;
|
||||
background: var(--mc-chat-header-bg, #ffffff);
|
||||
color: var(--mc-text-primary, #1d1612);
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid var(--mc-border-light, #ebe3db);
|
||||
}
|
||||
.mc-webchat-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: white;
|
||||
color: var(--mc-text-secondary, #665245);
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
padding: 0 4px;
|
||||
@ -119,40 +128,45 @@ function injectStyles() {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
background: var(--mc-chat-bg, #FAFAF8);
|
||||
}
|
||||
.mc-webchat-msg {
|
||||
max-width: 85%;
|
||||
padding: 8px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
border-radius: var(--mc-radius-md, 12px);
|
||||
font-size: var(--mc-text-sm, 13px);
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.mc-webchat-msg--user {
|
||||
align-self: flex-end;
|
||||
background: ${config.primaryColor};
|
||||
color: white;
|
||||
background: var(--mc-user-bubble-bg, ${config.primaryColor});
|
||||
color: var(--mc-user-bubble-color, #ffffff);
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.mc-webchat-msg--assistant {
|
||||
align-self: flex-start;
|
||||
background: #f0f2f5;
|
||||
color: #333;
|
||||
background: var(--mc-assistant-bubble-bg, #ffffff);
|
||||
color: var(--mc-assistant-bubble-color, #1C1410);
|
||||
border: 1px solid var(--mc-assistant-bubble-border, #DDD5CC);
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.mc-webchat-input-area {
|
||||
padding: 10px 12px;
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid var(--mc-border-light, #ebe3db);
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
background: var(--mc-bg-elevated, #ffffff);
|
||||
}
|
||||
.mc-webchat-input {
|
||||
flex: 1;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
border: 1px solid var(--mc-input-border, #DDD5CC);
|
||||
border-radius: var(--mc-radius-full, 9999px);
|
||||
background: var(--mc-input-bg, #FAFAF8);
|
||||
color: var(--mc-input-text, #1C1410);
|
||||
font-size: var(--mc-text-sm, 13px);
|
||||
outline: none;
|
||||
}
|
||||
.mc-webchat-input:focus { border-color: ${config.primaryColor}; }
|
||||
@ -161,7 +175,7 @@ function injectStyles() {
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background: ${config.primaryColor};
|
||||
color: white;
|
||||
color: var(--mc-text-inverse, #ffffff);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user