Skip to content

Commit 91b91e3

Browse files
authored
Merge pull request #101 from eric861129/dev
feat: enhance UI with new color variables and improve component styles
2 parents c01d381 + 3d83469 commit 91b91e3

11 files changed

Lines changed: 184 additions & 71 deletions

File tree

components/Footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const Footer: React.FC = () => {
1515
<div className="container mx-auto px-8 flex justify-between items-center">
1616
<div className="flex items-center gap-3 text-[10px] font-bold tracking-tight">
1717
<span className="text-slate-500 dark:text-slate-400">
18-
© 2025 EricHuang
18+
© 2025 <span style={{ color: 'var(--brand-primary)' }}>EricHuang</span>
1919
</span>
2020
<div className="w-px h-2 bg-slate-300 dark:bg-slate-700" />
2121
<span className="text-slate-400 dark:text-slate-500 uppercase tracking-widest">
@@ -27,7 +27,7 @@ const Footer: React.FC = () => {
2727
href={GITHUB_URL}
2828
target="_blank"
2929
rel="noopener noreferrer"
30-
className="flex items-center gap-1.5 text-slate-500 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors text-[10px] font-bold"
30+
className="flex items-center gap-1.5 text-slate-500 dark:text-slate-400 hover-brand transition-colors text-[10px] font-bold"
3131
>
3232
<Github className="w-3 h-3" />
3333
<span>GitHub</span>

components/MarkdownEditor.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,13 @@ const MarkdownEditor: React.FC = () => {
8787
/>
8888
</div>
8989

90-
{/* Resizable Divider */}
91-
<div
92-
onMouseDown={startResizing}
93-
className="w-1.5 h-full cursor-col-resize hover:bg-indigo-500/30 active:bg-indigo-500/50 transition-colors z-10 flex items-center justify-center group"
94-
>
95-
<div className="w-0.5 h-8 bg-slate-300 dark:bg-slate-700 group-hover:bg-indigo-500 rounded-full transition-colors" />
96-
</div>
97-
90+
{/* Resizable Divider */}
91+
<div
92+
onMouseDown={startResizing}
93+
className="w-1.5 h-full cursor-col-resize resizer-product transition-colors z-10 flex items-center justify-center group"
94+
>
95+
<div className="w-0.5 h-8 bg-slate-300 dark:bg-slate-700 group-hover:bg-product rounded-full transition-colors" />
96+
</div>
9897
<div style={{ width: `${100 - splitPercent}%` }} className="flex flex-col h-full">
9998
<PreviewPane
10099
parsedBlocks={parsedBlocks}

components/editor/EditorHeader.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,17 @@ export const EditorHeader: React.FC = () => {
3737
return (
3838
<header className="bg-white dark:bg-slate-900 border-b border-slate-200 dark:border-slate-800 px-8 py-4 flex justify-between items-center z-20 shadow-sm transition-colors">
3939
<div className="flex items-center gap-4">
40-
<div className="bg-slate-900 dark:bg-indigo-600 p-1 rounded-xl">
40+
<div
41+
className="p-1 rounded-xl"
42+
style={{ backgroundColor: 'var(--product-primary)' }}
43+
>
4144
<img src={logoPath} alt="Logo" className="w-9 h-9" />
4245
</div>
4346
<div>
44-
<h1 className="text-xl font-black text-slate-900 dark:text-white tracking-tight">
47+
<h1
48+
className="text-xl font-black tracking-tight"
49+
style={{ color: 'var(--product-primary)' }}
50+
>
4551
{t('title')}
4652
</h1>
4753
<p className="text-[10px] text-slate-400 dark:text-slate-500 font-bold uppercase tracking-widest">{t('subtitle')}</p>
@@ -55,7 +61,8 @@ export const EditorHeader: React.FC = () => {
5561
<IconButton
5662
onClick={() => setIsAIModalOpen(true)}
5763
title={t('aiPrompt')}
58-
className="bg-transparent border-none hover:bg-white dark:hover:bg-slate-700 shadow-none text-indigo-600 dark:text-indigo-400"
64+
className="bg-transparent border-none hover:bg-white dark:hover:bg-slate-700 shadow-none"
65+
style={{ color: 'var(--product-primary)' }}
5966
>
6067
<Bot className="w-4 h-4" />
6168
</IconButton>

components/editor/EditorPane.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ export const EditorPane: React.FC<EditorPaneProps> = ({
135135
<textarea
136136
ref={textareaRef}
137137
onScroll={onScroll}
138-
className="flex-1 w-full p-10 resize-none focus:outline-none text-base leading-[1.8] text-slate-700 dark:text-slate-300 bg-transparent selection:bg-indigo-100 dark:selection:bg-indigo-900"
138+
className="flex-1 w-full p-10 resize-none focus:outline-none text-base leading-[1.8] text-slate-700 dark:text-slate-300 bg-transparent selection-product"
139+
139140
style={{ fontFamily: UI_THEME.FONTS.PREVIEW }}
140141
value={content}
141142
onChange={handleChange}

components/editor/PreviewRenderers.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ export const PreviewBlock: React.FC<{ block: ParsedBlock; showLineNumbers?: bool
102102
case BlockType.HEADING_1:
103103
return <h1 className="text-4xl font-black mb-12 mt-16 pb-4 border-b-4 border-slate-900 tracking-tight leading-tight"><RenderRichText text={block.content} /></h1>;
104104
case BlockType.HEADING_2:
105-
return <h2 className="text-2xl font-black mb-8 mt-12 tracking-tight flex items-center gap-3 before:w-2 before:h-8 before:bg-indigo-600"><RenderRichText text={block.content} /></h2>;
105+
return <h2 className="text-2xl font-black mb-8 mt-12 tracking-tight flex items-center gap-3 before:w-2 before:h-8 before-bg-product"><RenderRichText text={block.content} /></h2>;
106106
case BlockType.HEADING_3:
107-
return <h3 className="text-xl font-bold mb-6 mt-10 text-slate-800 underline decoration-indigo-200 underline-offset-8 decoration-4"><RenderRichText text={block.content} /></h3>;
107+
return <h3 className="text-xl font-bold mb-6 mt-10 text-slate-800 dark:text-slate-200 underline decoration-product underline-offset-8 decoration-4"><RenderRichText text={block.content} /></h3>;
108108
case BlockType.CODE_BLOCK:
109109
const codeLines = block.content.split('\n');
110110
return (
@@ -138,14 +138,17 @@ export const PreviewBlock: React.FC<{ block: ParsedBlock; showLineNumbers?: bool
138138
<div className={`
139139
${isCenter ? 'max-w-[90%]' : 'max-w-[85%]'}
140140
border-2 p-6 relative
141-
${isRight ? 'border-dashed border-slate-900 bg-white text-right' :
142-
isCenter ? 'border-double border-indigo-400 bg-indigo-50/30 text-center' :
143-
'border-dotted border-slate-900 bg-slate-100 text-left'}
141+
${isRight ? 'border-dashed border-slate-900 dark:border-slate-400 bg-white dark:bg-slate-900 text-right' :
142+
isCenter ? 'border-double border-product bg-product-glow text-center' :
143+
'border-dotted border-slate-900 dark:border-slate-400 bg-slate-100 dark:bg-slate-800 text-left'}
144144
`}>
145-
<div class={`absolute -top-3 ${isRight ? 'left-4' : isCenter ? 'left-1/2 -translate-x-1/2' : 'right-4'} bg-inherit px-2 text-[10px] font-black tracking-widest text-indigo-600 border border-slate-200 uppercase`}>
145+
<div
146+
class={`absolute -top-3 ${isRight ? 'left-4' : isCenter ? 'left-1/2 -translate-x-1/2' : 'right-4'} bg-inherit px-2 text-[10px] font-black tracking-widest border border-slate-200 dark:border-slate-700 uppercase`}
147+
style={{ color: 'var(--product-primary)' }}
148+
>
146149
{block.role}
147150
</div>
148-
<div className="whitespace-pre-wrap leading-[1.8] text-slate-900"><RenderRichText text={block.content} /></div>
151+
<div className="whitespace-pre-wrap leading-[1.8] text-slate-900 dark:text-slate-100"><RenderRichText text={block.content} /></div>
149152
</div>
150153
</div>
151154
);

components/editor/slash-command/SlashCommandMenu.tsx

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,25 +106,33 @@ export const SlashCommandMenu: React.FC<SlashCommandMenuProps> = ({
106106
const Icon = item.icon;
107107

108108
return (
109-
<button
110-
key={item.id}
111-
ref={isSelected ? selectedItemRef : null}
112-
className={`w-full flex items-center gap-3 px-3 py-2 text-left text-sm rounded-md transition-colors
113-
${isSelected
114-
? 'bg-indigo-50 dark:bg-indigo-900/30 text-indigo-700 dark:text-indigo-300'
115-
: 'text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50'
116-
}
109+
<button
110+
key={command.id}
111+
onClick={() => {
112+
onSelect(command.id);
113+
}}
114+
className={`
115+
w-full flex items-center gap-3 px-3 py-2 text-sm text-left transition-all
116+
${idx === selectedIndex
117+
? 'bg-product-glow'
118+
: 'hover:bg-slate-50 dark:hover:bg-slate-800 text-slate-700 dark:text-slate-300'}
119+
`}
120+
style={idx === selectedIndex ? { color: 'var(--product-primary)' } : {}}
121+
>
122+
<div
123+
className={`
124+
p-1.5 rounded-lg border transition-colors
125+
${idx === selectedIndex
126+
? 'bg-white dark:bg-slate-900'
127+
: 'bg-slate-100 dark:bg-slate-800 border-slate-200 dark:border-slate-700'}
117128
`}
118-
onClick={() => onSelect(item)}
129+
style={idx === selectedIndex ? { borderColor: 'var(--product-primary)' } : {}}
119130
>
120-
<div className={`flex items-center justify-center w-8 h-8 rounded border
121-
${isSelected
122-
? 'bg-white dark:bg-indigo-900/50 border-indigo-200 dark:border-indigo-800 text-indigo-600 dark:text-indigo-400'
123-
: 'bg-slate-50 dark:bg-slate-800 border-slate-200 dark:border-slate-700 text-slate-500 dark:text-slate-400'
124-
}`}
125-
>
126-
<Icon size={16} />
127-
</div>
131+
{React.cloneElement(command.icon as React.ReactElement, {
132+
className: "w-4 h-4",
133+
style: idx === selectedIndex ? { color: 'var(--product-primary)' } : {}
134+
})}
135+
</div>
128136
<div className="flex flex-col flex-1 min-w-0">
129137
<span className="font-medium truncate">{item.label}</span>
130138
{item.description && (

components/ui/Button.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,29 @@ export const Button: React.FC<ButtonProps> = ({
1111
variant = 'primary',
1212
isLoading,
1313
disabled,
14+
style,
1415
...props
1516
}) => {
1617
const baseStyles = "flex items-center justify-center gap-2 px-6 py-2.5 font-bold rounded-xl transition-all shadow-md active:scale-95 disabled:active:scale-100 disabled:cursor-not-allowed";
1718

1819
const variants = {
19-
primary: "bg-slate-900 dark:bg-indigo-600 hover:bg-slate-800 dark:hover:bg-indigo-500 text-white disabled:bg-slate-300 dark:disabled:bg-slate-700",
20+
primary: "text-white disabled:bg-slate-300 dark:disabled:bg-slate-700",
2021
secondary: "bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-200 dark:hover:bg-slate-700",
2122
danger: "bg-red-500 text-white hover:bg-red-600"
2223
};
2324

25+
const primaryStyles = variant === 'primary' ? {
26+
backgroundColor: 'var(--product-primary)',
27+
boxShadow: '0 4px 12px var(--product-glow)',
28+
} : {};
29+
30+
// Handle hover for primary via CSS or just keep it simple if we can't easily do hover in inline styles without a library
31+
// Better yet, I can add a small CSS block in index.html for .btn-primary-product
32+
2433
return (
2534
<button
26-
className={`${baseStyles} ${variants[variant]} ${className}`}
35+
className={`${baseStyles} ${variants[variant]} ${variant === 'primary' ? 'btn-product-primary' : ''} ${className}`}
36+
style={{ ...primaryStyles, ...style }}
2737
disabled={disabled || isLoading}
2838
{...props}
2939
>

components/ui/IconButton.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,22 @@ export const IconButton: React.FC<IconButtonProps> = ({
88
children,
99
className = '',
1010
active,
11+
style,
1112
...props
1213
}) => {
1314
const baseStyles = "p-2 rounded-lg border transition-all flex items-center justify-center";
1415
const defaultStyles = "bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 border-slate-200 dark:border-slate-700 hover:bg-slate-200 dark:hover:bg-slate-700";
15-
const activeStyles = "bg-indigo-100 dark:bg-indigo-900/50 text-indigo-600 dark:text-indigo-400 border-indigo-200 dark:border-indigo-800";
16+
17+
const activeStyles = {
18+
backgroundColor: 'var(--product-glow)',
19+
color: 'var(--product-primary)',
20+
borderColor: 'var(--product-primary)',
21+
};
1622

1723
return (
1824
<button
19-
className={`${baseStyles} ${active ? activeStyles : defaultStyles} ${className}`}
25+
className={`${baseStyles} ${active ? '' : defaultStyles} ${className}`}
26+
style={active ? { ...activeStyles, ...style } : style}
2027
{...props}
2128
>
2229
{children}

globals.css

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/* --- 設計系統核心變數 (Amber Anthracite v2.0 + Scholarly Blue) --- */
2+
:root {
3+
--font-main: "Consolas", "Microsoft JhengHei", "微軟正黑體", sans-serif;
4+
5+
/* Master Brand: Amber Anthracite v2.0 */
6+
--bg-base: #FCF9F5;
7+
--text-high: #2D2926;
8+
--brand-primary: #A86434; /* Amber */
9+
10+
/* MD2DOC Product Layer: Scholarly Blue */
11+
--product-primary: #3E5C76;
12+
--product-hover: #527491;
13+
--product-glow: rgba(62, 92, 118, 0.12);
14+
}
15+
16+
[data-theme='dark'] {
17+
--bg-base: #1A1816;
18+
--text-high: #E0E0E0;
19+
--brand-primary: #EFC69B; /* Soft Amber */
20+
21+
--product-primary: #6D9DC5;
22+
--product-hover: #8AB3D6;
23+
--product-glow: rgba(109, 157, 197, 0.2);
24+
}
25+
26+
/* --- 基礎頁面樣式 --- */
27+
body {
28+
font-family: var(--font-main);
29+
background-color: var(--bg-base);
30+
color: var(--text-high);
31+
margin: 0;
32+
transition: background-color 0.3s ease, color 0.3s ease;
33+
}
34+
35+
.manuscript-font {
36+
font-family: var(--font-main);
37+
}
38+
39+
code, pre, .font-mono {
40+
font-family: "Consolas", monospace !important;
41+
}
42+
43+
/* --- 自定義捲軸樣式 --- */
44+
::-webkit-scrollbar { width: 8px; height: 8px; }
45+
::-webkit-scrollbar-track { background: var(--bg-base); }
46+
::-webkit-scrollbar-thumb {
47+
background: #cbd5e1;
48+
border-radius: 4px;
49+
}
50+
[data-theme='dark'] ::-webkit-scrollbar-thumb {
51+
background: #334155;
52+
}
53+
::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
54+
55+
/* --- 產品功能性 Helper Classes --- */
56+
57+
/* 按鈕主色調 */
58+
.btn-product-primary {
59+
background-color: var(--product-primary);
60+
transition: all 0.2s ease;
61+
}
62+
63+
.btn-product-primary:hover:not(:disabled) {
64+
background-color: var(--product-hover);
65+
transform: translateY(-1px);
66+
box-shadow: 0 6px 16px var(--product-glow);
67+
}
68+
69+
/* 文字選取顏色 */
70+
.selection-product::selection {
71+
background-color: var(--product-glow);
72+
}
73+
74+
/* 預覽區 H2 裝飾線 */
75+
.before-bg-product::before {
76+
content: "";
77+
display: block;
78+
background-color: var(--product-primary) !important;
79+
}
80+
81+
/* 分隔線調整工具 */
82+
.resizer-product:hover {
83+
background-color: var(--product-glow);
84+
}
85+
86+
.resizer-product:active {
87+
background-color: rgba(109, 157, 197, 0.4);
88+
}
89+
90+
/* 品牌簽名 Hover */
91+
.hover-brand:hover {
92+
color: var(--brand-primary) !important;
93+
}

index.html

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -64,37 +64,21 @@
6464
<script src="https://cdn.tailwindcss.com"></script>
6565
<script>
6666
tailwind.config = {
67-
darkMode: 'class'
67+
darkMode: 'class',
68+
theme: {
69+
extend: {
70+
colors: {
71+
'brand-primary': 'var(--brand-primary)',
72+
'product-primary': 'var(--product-primary)',
73+
'product-hover': 'var(--product-hover)',
74+
'product-glow': 'var(--product-glow)',
75+
'bg-base': 'var(--bg-base)',
76+
'text-high': 'var(--text-high)',
77+
}
78+
}
79+
}
6880
}
6981
</script>
70-
<style>
71-
/* 核心排版策略:英數強制 Consolas,中文微軟正黑體 */
72-
:root {
73-
--font-main: "Consolas", "Microsoft JhengHei", "微軟正黑體", sans-serif;
74-
}
75-
76-
body {
77-
font-family: var(--font-main);
78-
background-color: #f1f5f9;
79-
margin: 0;
80-
color: #1e293b;
81-
}
82-
83-
.manuscript-font {
84-
font-family: var(--font-main);
85-
}
86-
87-
/* 程式碼塊強制等寬 */
88-
code, pre, .font-mono {
89-
font-family: "Consolas", monospace !important;
90-
}
91-
92-
/* 自定義捲軸 */
93-
::-webkit-scrollbar { width: 8px; height: 8px; }
94-
::-webkit-scrollbar-track { background: #f8fafc; }
95-
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
96-
::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
97-
</style>
9882
<script src="https://cdnjs.cloudflare.com/ajax/libs/buffer/6.0.3/buffer.min.js"></script>
9983
<script>
10084
// 關鍵:將 Buffer 掛載到全局,docx 庫才能運作

0 commit comments

Comments
 (0)