Compare commits
No commits in common. "470e34e7a888db0582bce4648f8236402b37acac" and "1ef4a31d5d107ff242321448f470ab05fe60caf7" have entirely different histories.
470e34e7a8
...
1ef4a31d5d
@ -62,21 +62,6 @@
|
|||||||
|
|
||||||
/* 字体大小 */
|
/* 字体大小 */
|
||||||
--font-size-base: 15px;
|
--font-size-base: 15px;
|
||||||
|
|
||||||
/* ========================================
|
|
||||||
代码块颜色 - Claude 风格亮色主题
|
|
||||||
======================================== */
|
|
||||||
--color-code-bg: #F5F3F0;
|
|
||||||
--color-code-toolbar-bg: #EDEAE6;
|
|
||||||
--color-code-border: #E0DDD8;
|
|
||||||
--color-code-line-number: #A8A29E;
|
|
||||||
--color-code-line-border: #E0DDD8;
|
|
||||||
--color-code-text: #374151;
|
|
||||||
--color-code-toolbar-text: #78716C;
|
|
||||||
--color-code-toolbar-text-hover: #57534E;
|
|
||||||
--color-code-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
|
|
||||||
/* Mac 红黄绿按钮 - 亮色主题隐藏 */
|
|
||||||
--color-code-traffic-light-display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================
|
/* ========================================
|
||||||
@ -119,22 +104,6 @@
|
|||||||
--shadow-dropdown: 0 4px 12px rgba(0, 0, 0, 0.4);
|
--shadow-dropdown: 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||||
--shadow-input: 0 2px 8px rgba(0, 0, 0, 0.2);
|
--shadow-input: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
--shadow-input-focus: 0 4px 16px rgba(224, 107, 62, 0.2);
|
--shadow-input-focus: 0 4px 16px rgba(224, 107, 62, 0.2);
|
||||||
|
|
||||||
/* ========================================
|
|
||||||
代码块颜色 - Mac Style 紫灰主题
|
|
||||||
与页面背景 #29252B 协调
|
|
||||||
======================================== */
|
|
||||||
--color-code-bg: #322D38;
|
|
||||||
--color-code-toolbar-bg: #29252B;
|
|
||||||
--color-code-border: #3A353E;
|
|
||||||
--color-code-line-number: #5A5560;
|
|
||||||
--color-code-line-border: #3A353E;
|
|
||||||
--color-code-text: #D4D4D8;
|
|
||||||
--color-code-toolbar-text: #8B8592;
|
|
||||||
--color-code-toolbar-text-hover: #D4D4D8;
|
|
||||||
--color-code-shadow: 0 8px 24px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
||||||
/* Mac 红黄绿按钮 - 暗色主题显示 */
|
|
||||||
--color-code-traffic-light-display: flex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
@ -438,12 +407,11 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================
|
/* ========================================
|
||||||
Prism.js 代码高亮样式
|
Prism.js 代码高亮样式 (VS Code Dark+)
|
||||||
======================================== */
|
======================================== */
|
||||||
|
|
||||||
/* 基础样式 */
|
|
||||||
code[class*="language-"],
|
code[class*="language-"],
|
||||||
pre[class*="language-"] {
|
pre[class*="language-"] {
|
||||||
|
color: #d4d4d4;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
font-family: 'SF Mono', Monaco, 'Courier New', monospace;
|
font-family: 'SF Mono', Monaco, 'Courier New', monospace;
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
@ -456,150 +424,66 @@ pre[class*="language-"] {
|
|||||||
hyphens: none;
|
hyphens: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================
|
.token.comment,
|
||||||
亮色主题语法高亮 (Claude Style)
|
.token.prolog,
|
||||||
======================================== */
|
.token.doctype,
|
||||||
:root code[class*="language-"],
|
.token.cdata {
|
||||||
:root pre[class*="language-"] {
|
color: #6a9955;
|
||||||
color: #374151;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.comment,
|
.token.punctuation {
|
||||||
:root .token.prolog,
|
color: #d4d4d4;
|
||||||
:root .token.doctype,
|
|
||||||
:root .token.cdata {
|
|
||||||
color: #9CA3AF;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.punctuation {
|
.token.property,
|
||||||
color: #6B7280;
|
.token.tag,
|
||||||
|
.token.boolean,
|
||||||
|
.token.number,
|
||||||
|
.token.constant,
|
||||||
|
.token.symbol,
|
||||||
|
.token.deleted {
|
||||||
|
color: #b5cea8;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.property,
|
.token.selector,
|
||||||
:root .token.tag,
|
.token.attr-name,
|
||||||
:root .token.boolean,
|
.token.string,
|
||||||
:root .token.number,
|
.token.char,
|
||||||
:root .token.constant,
|
.token.builtin,
|
||||||
:root .token.symbol,
|
.token.inserted {
|
||||||
:root .token.deleted {
|
color: #ce9178;
|
||||||
color: #2563EB;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.selector,
|
.token.operator,
|
||||||
:root .token.attr-name,
|
.token.entity,
|
||||||
:root .token.string,
|
.token.url,
|
||||||
:root .token.char,
|
.language-css .token.string,
|
||||||
:root .token.builtin,
|
.style .token.string {
|
||||||
:root .token.inserted {
|
color: #d4d4d4;
|
||||||
color: #059669;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.operator,
|
.token.atrule,
|
||||||
:root .token.entity,
|
.token.attr-value,
|
||||||
:root .token.url,
|
.token.keyword {
|
||||||
:root .language-css .token.string,
|
color: #569cd6;
|
||||||
:root .style .token.string {
|
|
||||||
color: #374151;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.atrule,
|
.token.function,
|
||||||
:root .token.attr-value,
|
.token.class-name {
|
||||||
:root .token.keyword {
|
color: #dcdcaa;
|
||||||
color: #D97706;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.function,
|
.token.regex,
|
||||||
:root .token.class-name {
|
.token.important,
|
||||||
color: #7C3AED;
|
.token.variable {
|
||||||
|
color: #d16969;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.regex,
|
.token.important,
|
||||||
:root .token.important,
|
.token.bold {
|
||||||
:root .token.variable {
|
|
||||||
color: #DC2626;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root .token.important,
|
|
||||||
:root .token.bold {
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .token.italic {
|
.token.italic {
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================
|
|
||||||
暗色主题语法高亮 (Mac Style - 紫灰主题)
|
|
||||||
======================================== */
|
|
||||||
[data-theme="dark"] code[class*="language-"],
|
|
||||||
[data-theme="dark"] pre[class*="language-"] {
|
|
||||||
color: #D4D4D8;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.comment,
|
|
||||||
[data-theme="dark"] .token.prolog,
|
|
||||||
[data-theme="dark"] .token.doctype,
|
|
||||||
[data-theme="dark"] .token.cdata {
|
|
||||||
color: #6B6672;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.punctuation {
|
|
||||||
color: #A8A3AE;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.property,
|
|
||||||
[data-theme="dark"] .token.tag,
|
|
||||||
[data-theme="dark"] .token.boolean,
|
|
||||||
[data-theme="dark"] .token.number,
|
|
||||||
[data-theme="dark"] .token.constant,
|
|
||||||
[data-theme="dark"] .token.symbol,
|
|
||||||
[data-theme="dark"] .token.deleted {
|
|
||||||
color: #E8A87C;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.selector,
|
|
||||||
[data-theme="dark"] .token.attr-name,
|
|
||||||
[data-theme="dark"] .token.string,
|
|
||||||
[data-theme="dark"] .token.char,
|
|
||||||
[data-theme="dark"] .token.builtin,
|
|
||||||
[data-theme="dark"] .token.inserted {
|
|
||||||
color: #9DD68D;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.operator,
|
|
||||||
[data-theme="dark"] .token.entity,
|
|
||||||
[data-theme="dark"] .token.url,
|
|
||||||
[data-theme="dark"] .language-css .token.string,
|
|
||||||
[data-theme="dark"] .style .token.string {
|
|
||||||
color: #7DD3C0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.atrule,
|
|
||||||
[data-theme="dark"] .token.attr-value,
|
|
||||||
[data-theme="dark"] .token.keyword {
|
|
||||||
color: #D4A5E8;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.function,
|
|
||||||
[data-theme="dark"] .token.class-name {
|
|
||||||
color: #7EB8E8;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.regex,
|
|
||||||
[data-theme="dark"] .token.important,
|
|
||||||
[data-theme="dark"] .token.variable {
|
|
||||||
color: #E88A95;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.important,
|
|
||||||
[data-theme="dark"] .token.bold {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .token.italic {
|
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,38 +84,16 @@ export function CodeBlock({
|
|||||||
const lines = code.split('\n');
|
const lines = code.split('\n');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('relative group rounded overflow-hidden my-4', className)}
|
<div className={cn('relative group rounded overflow-hidden my-4', className)}>
|
||||||
style={{ boxShadow: 'var(--color-code-shadow)' }}>
|
|
||||||
{/* 顶部工具栏 */}
|
{/* 顶部工具栏 */}
|
||||||
<div className="flex items-center justify-between px-4 py-2.5 text-sm"
|
<div className="flex items-center justify-between px-4 py-2 bg-[#2d2d2d] text-gray-400 text-sm">
|
||||||
style={{
|
<span className="font-mono">{language || 'code'}</span>
|
||||||
backgroundColor: 'var(--color-code-toolbar-bg)',
|
|
||||||
color: 'var(--color-code-toolbar-text)',
|
|
||||||
borderBottom: '1px solid var(--color-code-border)'
|
|
||||||
}}>
|
|
||||||
{/* 左侧:Mac 红黄绿按钮 + 语言 */}
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
{/* Mac Traffic Lights - 通过 CSS 变量控制显示 */}
|
|
||||||
<div className="items-center gap-2"
|
|
||||||
style={{ display: 'var(--color-code-traffic-light-display)' }}>
|
|
||||||
<span className="w-3 h-3 rounded-full"
|
|
||||||
style={{ backgroundColor: '#ff5f56', boxShadow: '0 0 0 1px rgba(0, 0, 0, 0.1) inset' }} />
|
|
||||||
<span className="w-3 h-3 rounded-full"
|
|
||||||
style={{ backgroundColor: '#ffbd2e', boxShadow: '0 0 0 1px rgba(0, 0, 0, 0.1) inset' }} />
|
|
||||||
<span className="w-3 h-3 rounded-full"
|
|
||||||
style={{ backgroundColor: '#27c93f', boxShadow: '0 0 0 1px rgba(0, 0, 0, 0.1) inset' }} />
|
|
||||||
</div>
|
|
||||||
<span className="font-mono text-[13px]">{language || 'code'}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 右侧:操作按钮 */}
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{/* HTML 预览按钮 */}
|
{/* HTML 预览按钮 */}
|
||||||
{isHtmlPreviewable && (
|
{isHtmlPreviewable && (
|
||||||
<button
|
<button
|
||||||
onClick={() => setPreviewOpen(true)}
|
onClick={() => setPreviewOpen(true)}
|
||||||
className="inline-flex items-center gap-1.5 px-2 py-1 rounded transition-colors hover:bg-white/10"
|
className="inline-flex items-center gap-1.5 px-2 py-1 rounded hover:bg-white/10 transition-colors text-blue-400 hover:text-blue-300"
|
||||||
style={{ color: 'var(--color-primary)' }}
|
|
||||||
title="预览 HTML"
|
title="预览 HTML"
|
||||||
>
|
>
|
||||||
<Eye size={14} />
|
<Eye size={14} />
|
||||||
@ -125,8 +103,7 @@ export function CodeBlock({
|
|||||||
{/* 复制按钮 */}
|
{/* 复制按钮 */}
|
||||||
<button
|
<button
|
||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
className="inline-flex items-center gap-1.5 px-2 py-1 rounded transition-colors hover:bg-white/10"
|
className="inline-flex items-center gap-1.5 px-2 py-1 rounded hover:bg-white/10 transition-colors"
|
||||||
style={{ color: 'var(--color-code-toolbar-text)' }}
|
|
||||||
title="Copy code"
|
title="Copy code"
|
||||||
>
|
>
|
||||||
{copied ? (
|
{copied ? (
|
||||||
@ -145,20 +122,14 @@ export function CodeBlock({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 代码区域 */}
|
{/* 代码区域 */}
|
||||||
<div className="relative overflow-x-auto"
|
<div className="relative overflow-x-auto bg-[#1e1e1e]">
|
||||||
style={{ backgroundColor: 'var(--color-code-bg)' }}>
|
|
||||||
{showLineNumbers && (
|
{showLineNumbers && (
|
||||||
<div className="absolute left-0 top-0 bottom-0 w-12 select-none"
|
<div className="absolute left-0 top-0 bottom-0 w-12 bg-[#1e1e1e] border-r border-gray-700 select-none">
|
||||||
style={{
|
|
||||||
backgroundColor: 'var(--color-code-bg)',
|
|
||||||
borderRight: '1px solid var(--color-code-line-border)'
|
|
||||||
}}>
|
|
||||||
<div className="py-4 px-2 text-right">
|
<div className="py-4 px-2 text-right">
|
||||||
{lines.map((_, index) => (
|
{lines.map((_, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className="text-sm font-mono leading-6"
|
className="text-gray-500 text-sm font-mono leading-6"
|
||||||
style={{ color: 'var(--color-code-line-number)' }}
|
|
||||||
>
|
>
|
||||||
{index + 1}
|
{index + 1}
|
||||||
</div>
|
</div>
|
||||||
@ -175,7 +146,6 @@ export function CodeBlock({
|
|||||||
>
|
>
|
||||||
<code
|
<code
|
||||||
className={`language-${normalizedLanguage} text-sm leading-6`}
|
className={`language-${normalizedLanguage} text-sm leading-6`}
|
||||||
style={{ color: 'var(--color-code-text)' }}
|
|
||||||
dangerouslySetInnerHTML={{ __html: highlightedCode }}
|
dangerouslySetInnerHTML={{ __html: highlightedCode }}
|
||||||
/>
|
/>
|
||||||
</pre>
|
</pre>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user