feat: add primary color input in theme editor, closes #963 (#970)

This commit is contained in:
Huang Xin
2025-04-26 15:58:20 +08:00
committed by GitHub
parent 98faed320a
commit 9303ec8c5f
19 changed files with 96 additions and 32 deletions
@@ -296,5 +296,7 @@
"Description:": "الوصف:",
"No description available": "لا يوجد وصف متاح",
"List": "قائمة",
"Grid": "شبكة"
"Grid": "شبكة",
"(from 'As You Like It', Act II)": "(من 'كما تحب'، الفصل الثاني)",
"Link Color": "لون الرابط"
}
@@ -296,5 +296,7 @@
"Description:": "Beschreibung:",
"No description available": "Keine Beschreibung verfügbar",
"List": "Liste",
"Grid": "Raster"
"Grid": "Raster",
"(from 'As You Like It', Act II)": "(aus 'Wie es euch gefällt', Akt II)",
"Link Color": "Linkfarbe"
}
@@ -296,5 +296,7 @@
"Description:": "Περιγραφή:",
"No description available": "Δεν είναι διαθέσιμη καμία περιγραφή",
"List": "Λίστα",
"Grid": "Πλέγμα"
"Grid": "Πλέγμα",
"(from 'As You Like It', Act II)": "('Όπως σας αρέσει', Πράξη II)",
"Link Color": "Χρώμα συνδέσμου"
}
@@ -296,5 +296,7 @@
"Description:": "Descripción:",
"No description available": "No hay descripción disponible",
"List": "Lista",
"Grid": "Cuadrícula"
"Grid": "Cuadrícula",
"(from 'As You Like It', Act II)": "(de 'Como gustéis', Acto II)",
"Link Color": "Color del enlace"
}
@@ -296,5 +296,7 @@
"Description:": "Description :",
"No description available": "Aucune description disponible",
"List": "Liste",
"Grid": "Grille"
"Grid": "Grille",
"(from 'As You Like It', Act II)": "(de 'Comme il vous plaira', Acte II)",
"Link Color": "Couleur du lien"
}
@@ -296,5 +296,7 @@
"Description:": "विवरण:",
"No description available": "कोई विवरण उपलब्ध नहीं है",
"List": "सूची",
"Grid": "ग्रिड"
"Grid": "ग्रिड",
"(from 'As You Like It', Act II)": "('जैसा आप इसे पसंद करते हैं', अधिनियम II)",
"Link Color": "लिंक रंग"
}
@@ -296,5 +296,7 @@
"Description:": "Deskripsi:",
"No description available": "Tidak ada deskripsi yang tersedia",
"List": "Daftar",
"Grid": "Jala"
"Grid": "Jala",
"(from 'As You Like It', Act II)": "(dari 'Seperti yang Anda Inginkan', Bab II)",
"Link Color": "Warna Tautan"
}
@@ -296,5 +296,7 @@
"Description:": "Descrizione:",
"No description available": "Nessuna descrizione disponibile",
"List": "Elenco",
"Grid": "Griglia"
"Grid": "Griglia",
"(from 'As You Like It', Act II)": "(da 'Come vi piace', Atto II)",
"Link Color": "Colore link"
}
@@ -296,5 +296,7 @@
"Description:": "説明:",
"No description available": "説明はありません",
"List": "リスト",
"Grid": "グリッド"
"Grid": "グリッド",
"(from 'As You Like It', Act II)": "(「お気に召すまま」第2幕)",
"Link Color": "リンクカラー"
}
@@ -296,5 +296,7 @@
"Description:": "설명:",
"No description available": "설명 없음",
"List": "목록",
"Grid": "격자"
"Grid": "격자",
"(from 'As You Like It', Act II)": "(당신이 좋아하는 대로, 2막)",
"Link Color": "링크 색상"
}
@@ -296,5 +296,7 @@
"Description:": "Opis:",
"No description available": "Brak opisu",
"List": "Lista",
"Grid": "Siatka"
"Grid": "Siatka",
"(from 'As You Like It', Act II)": "(z „Jak wam się podoba”, Akt II)",
"Link Color": "Kolor linku"
}
@@ -296,5 +296,7 @@
"Description:": "Descrição:",
"No description available": "Nenhuma descrição disponível",
"List": "Lista",
"Grid": "Grade"
"Grid": "Grade",
"(from 'As You Like It', Act II)": "(de 'Como Gostais', Ato II)",
"Link Color": "Cor do Link"
}
@@ -296,5 +296,7 @@
"Description:": "Описание:",
"No description available": "Нет доступного описания",
"List": "Список",
"Grid": "Сетка"
"Grid": "Сетка",
"(from 'As You Like It', Act II)": "(из 'Как вам это понравится', Акт II)",
"Link Color": "Цвет ссылки"
}
@@ -296,5 +296,7 @@
"Description:": "Tanım:",
"No description available": "Tanım mevcut değil",
"List": "Liste",
"Grid": "Izgara"
"Grid": "Izgara",
"(from 'As You Like It', Act II)": "(As You Like It, 2. Perde)",
"Link Color": "Bağlantı Rengi"
}
@@ -296,5 +296,7 @@
"Description:": "Опис:",
"No description available": "Опис недоступний",
"List": "Список",
"Grid": "Сітка"
"Grid": "Сітка",
"(from 'As You Like It', Act II)": "(з 'Як вам це подобається', Акт II)",
"Link Color": "Колір посилання"
}
@@ -296,5 +296,7 @@
"Description:": "Miêu tả:",
"No description available": "Không có mô tả nào",
"List": "Danh sách",
"Grid": "Lưới"
"Grid": "Lưới",
"(from 'As You Like It', Act II)": "(từ 'Như bạn thích', Hành động II)",
"Link Color": "Màu liên kết"
}
@@ -296,5 +296,7 @@
"Description:": "简介",
"No description available": "暂无简介",
"List": "列表",
"Grid": "网格"
"Grid": "网格",
"(from 'As You Like It', Act II)": "出自《皆大欢喜》,第二幕",
"Link Color": "链接颜色"
}
@@ -296,5 +296,7 @@
"Description:": "簡介",
"No description available": "暫無簡介",
"List": "列表",
"Grid": "網格"
"Grid": "網格",
"(from 'As You Like It', Act II)": "(出自《皆大歡喜》,第二幕)",
"Link Color": "連結顏色"
}
@@ -25,20 +25,27 @@ const ThemeEditor: React.FC<ThemeEditorProps> = ({ customTheme, onSave, onDelete
const [lightBackgroundColor, setLightBackgroundColor] = useState(
customTheme?.colors.light.bg || template.light.bg,
);
const [lightPrimaryColor, setLightPrimaryColor] = useState(
customTheme?.colors.light.primary || template.light.primary,
);
const [darkTextColor, setDarkTextColor] = useState(
customTheme?.colors.dark.fg || template.dark.fg,
);
const [darkBackgroundColor, setDarkBackgroundColor] = useState(
customTheme?.colors.dark.bg || template.dark.bg,
);
const [darkPrimaryColor, setDarkPrimaryColor] = useState(
customTheme?.colors.dark.primary || template.dark.primary,
);
const [themeName, setThemeName] = useState(customTheme?.label || _('Custom'));
const ThemePreview: React.FC<{
textColor: string;
backgroundColor: string;
primaryColor: string;
label: string;
}> = ({ textColor, backgroundColor, label }) => (
}> = ({ textColor, backgroundColor, primaryColor, label }) => (
<div className='mb-2 mt-4'>
<label className='mb-1 block text-sm font-medium'>{label}</label>
<div
@@ -52,6 +59,14 @@ const ThemeEditor: React.FC<ThemeEditorProps> = ({ customTheme, onSave, onDelete
{_(
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare",
)}
<p
className='mt-4 cursor-pointer italic'
style={{
color: primaryColor,
}}
>
{_("(from 'As You Like It', Act II)")}
</p>
</p>
</div>
</div>
@@ -65,12 +80,12 @@ const ThemeEditor: React.FC<ThemeEditorProps> = ({ customTheme, onSave, onDelete
light: {
fg: lightTextColor,
bg: lightBackgroundColor,
primary: '#3b82f6',
primary: lightPrimaryColor,
},
dark: {
fg: darkTextColor,
bg: darkBackgroundColor,
primary: '#60a5fa',
primary: darkPrimaryColor,
},
},
};
@@ -89,17 +104,16 @@ const ThemeEditor: React.FC<ThemeEditorProps> = ({ customTheme, onSave, onDelete
{_('Save')}
</button>
<button
className={clsx(
'btn btn-ghost btn-sm px-2',
!settings.globalReadSettings.customThemes.find(
(theme) => theme.name === md5Fingerprint(themeName),
) && 'btn-disabled',
)}
onClick={() => onDelete(getCustomTheme())}
>
{_('Delete')}
</button>
{settings.globalReadSettings.customThemes.find(
(theme) => theme.name === md5Fingerprint(themeName),
) && (
<button
className={clsx('btn btn-ghost btn-sm px-2')}
onClick={() => onDelete(getCustomTheme())}
>
{_('Delete')}
</button>
)}
<button className='btn btn-ghost btn-sm px-2' onClick={onCancel}>
{_('Cancel')}
@@ -129,9 +143,16 @@ const ThemeEditor: React.FC<ThemeEditorProps> = ({ customTheme, onSave, onDelete
onChange={setLightBackgroundColor}
/>
<ColorInput
label={_('Link Color')}
value={lightPrimaryColor}
onChange={setLightPrimaryColor}
/>
<ThemePreview
textColor={lightTextColor}
backgroundColor={lightBackgroundColor}
primaryColor={lightPrimaryColor}
label={_('Preview')}
/>
</div>
@@ -147,9 +168,16 @@ const ThemeEditor: React.FC<ThemeEditorProps> = ({ customTheme, onSave, onDelete
onChange={setDarkBackgroundColor}
/>
<ColorInput
label={_('Link Color')}
value={darkPrimaryColor}
onChange={setDarkPrimaryColor}
/>
<ThemePreview
textColor={darkTextColor}
backgroundColor={darkBackgroundColor}
primaryColor={darkPrimaryColor}
label={_('Preview')}
/>
</div>