feat: integrate HeroUI and Tailwind CSS for enhanced styling (#9973)
This commit is contained in:
4
.github/workflows/auto-i18n.yml
vendored
4
.github/workflows/auto-i18n.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Auto I18N
|
||||
|
||||
env:
|
||||
API_KEY: ${{ secrets.TRANSLATE_API_KEY}}
|
||||
API_KEY: ${{ secrets.TRANSLATE_API_KEY }}
|
||||
MODEL: ${{ vars.MODEL || 'deepseek/deepseek-v3.1'}}
|
||||
BASE_URL: ${{ vars.BASE_URL || 'https://api.ppinfra.com/openai'}}
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
# 在临时目录安装依赖
|
||||
mkdir -p /tmp/translation-deps
|
||||
cd /tmp/translation-deps
|
||||
echo '{"dependencies": {"openai": "^5.12.2", "cli-progress": "^3.12.0", "tsx": "^4.20.3", "prettier": "^3.5.3", "prettier-plugin-sort-json": "^4.1.1"}}' > package.json
|
||||
echo '{"dependencies": {"openai": "^5.12.2", "cli-progress": "^3.12.0", "tsx": "^4.20.3", "prettier": "^3.5.3", "prettier-plugin-sort-json": "^4.1.1", "prettier-plugin-tailwindcss": "^0.6.14"}}' > package.json
|
||||
npm install --no-package-lock
|
||||
|
||||
# 设置 NODE_PATH 让项目能找到这些依赖
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
"endOfLine": "lf",
|
||||
"jsonRecursiveSort": true,
|
||||
"jsonSortOrder": "{\"*\": \"lexical\"}",
|
||||
"plugins": ["prettier-plugin-sort-json"],
|
||||
"plugins": ["prettier-plugin-sort-json", "prettier-plugin-tailwindcss"],
|
||||
"printWidth": 120,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"tailwindFunctions": ["clsx"],
|
||||
"tailwindStylesheet": "./src/renderer/src/assets/styles/tailwind.css",
|
||||
"trailingComma": "none"
|
||||
}
|
||||
|
||||
21
components.json
Normal file
21
components.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"aliases": {
|
||||
"components": "@renderer/ui/third-party",
|
||||
"hooks": "@renderer/hooks",
|
||||
"lib": "@renderer/lib",
|
||||
"ui": "@renderer/ui",
|
||||
"utils": "@renderer/utils"
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"rsc": false,
|
||||
"style": "new-york",
|
||||
"tailwind": {
|
||||
"baseColor": "zinc",
|
||||
"config": "",
|
||||
"css": "src/renderer/src/assets/styles/tailwind.css",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"tsx": true
|
||||
}
|
||||
@@ -60,6 +60,7 @@ export default defineConfig({
|
||||
},
|
||||
renderer: {
|
||||
plugins: [
|
||||
(async () => (await import('@tailwindcss/vite')).default())(),
|
||||
react({
|
||||
tsDecorators: true,
|
||||
plugins: [
|
||||
|
||||
@@ -123,7 +123,9 @@ export default defineConfig([
|
||||
'.gitignore',
|
||||
'scripts/cloudflare-worker.js',
|
||||
'src/main/integration/nutstore/sso/lib/**',
|
||||
'src/main/integration/cherryin/index.js'
|
||||
'src/main/integration/cherryin/index.js',
|
||||
'src/main/integration/nutstore/sso/lib/**',
|
||||
'src/renderer/src/ui/**'
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
10
package.json
10
package.json
@@ -128,6 +128,7 @@
|
||||
"@eslint/js": "^9.22.0",
|
||||
"@google/genai": "patch:@google/genai@npm%3A1.0.1#~/.yarn/patches/@google-genai-npm-1.0.1-e26f0f9af7.patch",
|
||||
"@hello-pangea/dnd": "^18.0.1",
|
||||
"@heroui/react": "^2.8.3",
|
||||
"@kangfenmao/keyv-storage": "^0.1.0",
|
||||
"@langchain/community": "^0.3.50",
|
||||
"@langchain/core": "^0.3.68",
|
||||
@@ -148,6 +149,7 @@
|
||||
"@reduxjs/toolkit": "^2.2.5",
|
||||
"@shikijs/markdown-it": "^3.12.0",
|
||||
"@swc/plugin-styled-components": "^8.0.4",
|
||||
"@tailwindcss/vite": "^4.1.13",
|
||||
"@tanstack/react-query": "^5.85.5",
|
||||
"@tanstack/react-virtual": "^3.13.12",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
@@ -210,6 +212,7 @@
|
||||
"cheerio": "^1.1.2",
|
||||
"chokidar": "^4.0.3",
|
||||
"cli-progress": "^3.12.0",
|
||||
"clsx": "^2.1.1",
|
||||
"code-inspector-plugin": "^0.20.14",
|
||||
"color": "^5.0.0",
|
||||
"concurrently": "^9.2.1",
|
||||
@@ -238,6 +241,7 @@
|
||||
"fast-diff": "^1.3.0",
|
||||
"fast-xml-parser": "^5.2.0",
|
||||
"fetch-socks": "1.3.2",
|
||||
"framer-motion": "^12.23.12",
|
||||
"franc-min": "^6.2.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"google-auth-library": "^9.15.1",
|
||||
@@ -272,6 +276,7 @@
|
||||
"playwright": "^1.52.0",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-sort-json": "^4.1.1",
|
||||
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||
"proxy-agent": "^6.5.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
@@ -301,17 +306,18 @@
|
||||
"remark-math": "^6.0.0",
|
||||
"remove-markdown": "^0.6.2",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"sass": "^1.88.0",
|
||||
"shiki": "^3.12.0",
|
||||
"strict-url-sanitise": "^0.0.1",
|
||||
"string-width": "^7.2.0",
|
||||
"striptags": "^3.2.0",
|
||||
"styled-components": "^6.1.11",
|
||||
"tailwindcss": "^4.1.13",
|
||||
"tar": "^7.4.3",
|
||||
"tiny-pinyin": "^1.3.2",
|
||||
"tokenx": "^1.1.0",
|
||||
"tsx": "^4.20.3",
|
||||
"turndown-plugin-gfm": "^1.0.2",
|
||||
"tw-animate-css": "^1.3.8",
|
||||
"typescript": "^5.6.2",
|
||||
"undici": "6.21.2",
|
||||
"unified": "^11.0.5",
|
||||
@@ -356,7 +362,7 @@
|
||||
"prettier --write",
|
||||
"eslint --fix"
|
||||
],
|
||||
"*.{json,yml,yaml,css,scss,html}": [
|
||||
"*.{json,yml,yaml,css,html}": [
|
||||
"prettier --write"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cherrystudio/ai-core",
|
||||
"version": "1.0.0-alpha.11",
|
||||
"version": "1.0.0-alpha.12",
|
||||
"description": "Cherry Studio AI Core - Unified AI Provider Interface Based on Vercel AI SDK",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
|
||||
@@ -8,18 +8,18 @@
|
||||
</head>
|
||||
|
||||
<body class="bg-gray-50">
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<div class="mx-auto max-w-4xl px-4 py-8">
|
||||
<!-- 中文版本 -->
|
||||
<div class="mb-12">
|
||||
<h1 class="text-3xl font-bold mb-8 text-gray-900">许可协议</h1>
|
||||
<h1 class="mb-8 text-3xl font-bold text-gray-900">许可协议</h1>
|
||||
|
||||
<p class="mb-6 text-gray-700">
|
||||
本项目采用<strong>区分用户的双重许可 (User-Segmented Dual Licensing)</strong> 模式。
|
||||
</p>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">核心原则</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">核心原则</h2>
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
<strong>个人用户 和 10人及以下企业/组织:</strong> 默认适用
|
||||
<strong>GNU Affero 通用公共许可证 v3.0 (AGPLv3)</strong>。
|
||||
@@ -32,7 +32,7 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">定义:"10人及以下"</h2>
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">定义:"10人及以下"</h2>
|
||||
<p class="text-gray-700">
|
||||
指在您的组织(包括公司、非营利组织、政府机构、教育机构等任何实体)中,能够访问、使用或以任何方式直接或间接受益于本软件(Cherry
|
||||
Studio)功能的个人总数不超过10人。这包括但不限于开发者、测试人员、运营人员、最终用户、通过集成系统间接使用者等。
|
||||
@@ -40,10 +40,10 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">
|
||||
1. 开源许可证 (Open Source License): AGPLv3 - 适用于个人及10人及以下组织
|
||||
</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
如果您是个人用户,或者您的组织满足上述"10人及以下"的定义,您可以在
|
||||
<strong>AGPLv3</strong> 的条款下自由使用、修改和分发 Cherry Studio。AGPLv3 的完整文本可以访问
|
||||
@@ -62,10 +62,10 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">
|
||||
2. 商业许可证 (Commercial License) - 适用于超过10人的组织,或希望规避 AGPLv3 义务的用户
|
||||
</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
<strong>强制要求:</strong>
|
||||
如果您的组织<strong>不</strong>满足上述"10人及以下"的定义(即有11人或更多人可以访问、使用或受益于本软件),您<strong>必须</strong>联系我们获取并签署一份商业许可证才能使用
|
||||
@@ -80,7 +80,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<strong>需要商业许可证的常见情况包括(但不限于):</strong>
|
||||
<ul class="list-disc pl-6 mt-2 space-y-1">
|
||||
<ul class="mt-2 list-disc space-y-1 pl-6">
|
||||
<li>您的组织规模超过10人。</li>
|
||||
<li>
|
||||
(无论组织规模)您希望分发修改过的 Cherry Studio 版本,但<strong>不希望</strong>根据 AGPLv3
|
||||
@@ -104,8 +104,8 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">3. 贡献 (Contributions)</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">3. 贡献 (Contributions)</h2>
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
我们欢迎社区对 Cherry Studio 的贡献。所有向本项目提交的贡献都将被视为在
|
||||
<strong>AGPLv3</strong> 许可证下提供。
|
||||
@@ -119,8 +119,8 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">4. 其他条款 (Other Terms)</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">4. 其他条款 (Other Terms)</h2>
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>关于商业许可证的具体条款和条件,以双方签署的正式商业许可协议为准。</li>
|
||||
<li>
|
||||
项目维护者保留根据需要更新本许可政策(包括用户规模定义和阈值)的权利。相关更新将通过项目官方渠道(如代码仓库、官方网站)进行通知。
|
||||
@@ -133,13 +133,13 @@
|
||||
|
||||
<!-- English Version -->
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold mb-8 text-gray-900">Licensing</h1>
|
||||
<h1 class="mb-8 text-3xl font-bold text-gray-900">Licensing</h1>
|
||||
|
||||
<p class="mb-6 text-gray-700">This project employs a <strong>User-Segmented Dual Licensing</strong> model.</p>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">Core Principle</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">Core Principle</h2>
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
<strong>Individual Users and Organizations with 10 or Fewer Individuals:</strong> Governed by default
|
||||
under the <strong>GNU Affero General Public License v3.0 (AGPLv3)</strong>.
|
||||
@@ -152,7 +152,7 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">Definition: "10 or Fewer Individuals"</h2>
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">Definition: "10 or Fewer Individuals"</h2>
|
||||
<p class="text-gray-700">
|
||||
Refers to any organization (including companies, non-profits, government agencies, educational institutions,
|
||||
etc.) where the total number of individuals who can access, use, or in any way directly or indirectly
|
||||
@@ -162,10 +162,10 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">
|
||||
1. Open Source License: AGPLv3 - For Individuals and Organizations of 10 or Fewer
|
||||
</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
If you are an individual user, or if your organization meets the "10 or Fewer Individuals" definition
|
||||
above, you are free to use, modify, and distribute Cherry Studio under the terms of the
|
||||
@@ -186,11 +186,11 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">
|
||||
2. Commercial License - For Organizations with More Than 10 Individuals, or Users Needing to Avoid AGPLv3
|
||||
Obligations
|
||||
</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
<strong>Mandatory Requirement:</strong> If your organization does <strong>not</strong> meet the "10 or
|
||||
Fewer Individuals" definition above (i.e., 11 or more individuals can access, use, or benefit from the
|
||||
@@ -207,7 +207,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<strong>Common scenarios requiring a Commercial License include (but are not limited to):</strong>
|
||||
<ul class="list-disc pl-6 mt-2 space-y-1">
|
||||
<ul class="mt-2 list-disc space-y-1 pl-6">
|
||||
<li>
|
||||
Your organization has more than 10 individuals who can access, use, or benefit from the software.
|
||||
</li>
|
||||
@@ -236,8 +236,8 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">3. Contributions</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">3. Contributions</h2>
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
We welcome community contributions to Cherry Studio. All contributions submitted to this project are
|
||||
considered to be offered under the <strong>AGPLv3</strong> license.
|
||||
@@ -255,8 +255,8 @@
|
||||
</section>
|
||||
|
||||
<section class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900">4. Other Terms</h2>
|
||||
<ul class="list-disc pl-6 space-y-2 text-gray-700">
|
||||
<h2 class="mb-4 text-xl font-semibold text-gray-900">4. Other Terms</h2>
|
||||
<ul class="list-disc space-y-2 pl-6 text-gray-700">
|
||||
<li>
|
||||
The specific terms and conditions of the Commercial License are governed by the formal commercial license
|
||||
agreement signed by both parties.
|
||||
|
||||
@@ -12,18 +12,18 @@
|
||||
|
||||
<body id="app">
|
||||
<div :class="isDark ? 'dark-bg' : 'bg'" class="min-h-screen">
|
||||
<div class="max-w-3xl mx-auto py-12 px-4">
|
||||
<h1 class="text-3xl font-bold mb-8" :class="isDark ? 'text-white' : 'text-gray-900'">Release Timeline</h1>
|
||||
<div class="mx-auto max-w-3xl px-4 py-12">
|
||||
<h1 class="mb-8 text-3xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900'">Release Timeline</h1>
|
||||
|
||||
<!-- Loading状态 -->
|
||||
<div v-if="loading" class="text-center py-8">
|
||||
<div v-if="loading" class="py-8 text-center">
|
||||
<div
|
||||
class="inline-block animate-spin rounded-full h-8 w-8 border-4"
|
||||
class="inline-block h-8 w-8 animate-spin rounded-full border-4"
|
||||
:class="isDark ? 'border-gray-700 border-t-blue-500' : 'border-gray-300 border-t-blue-500'"></div>
|
||||
</div>
|
||||
|
||||
<!-- Error 状态 -->
|
||||
<div v-else-if="error" class="text-red-500 text-center py-8">{{ error }}</div>
|
||||
<div v-else-if="error" class="py-8 text-center text-red-500">{{ error }}</div>
|
||||
|
||||
<!-- Release 列表 -->
|
||||
<div v-else class="space-y-8">
|
||||
@@ -32,21 +32,21 @@
|
||||
:key="release.id"
|
||||
class="relative pl-8"
|
||||
:class="isDark ? 'border-l-2 border-gray-700' : 'border-l-2 border-gray-200'">
|
||||
<div class="absolute -left-2 top-0 w-4 h-4 rounded-full bg-green-500"></div>
|
||||
<div class="absolute top-0 -left-2 h-4 w-4 rounded-full bg-green-500"></div>
|
||||
<div
|
||||
class="rounded-lg shadow-sm p-6 transition-shadow"
|
||||
class="rounded-lg p-6 shadow-sm transition-shadow"
|
||||
:class="isDark ? 'bg-black hover:shadow-md hover:shadow-black' : 'bg-white hover:shadow-md'">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div class="mb-4 flex items-start justify-between">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold" :class="isDark ? 'text-white' : 'text-gray-900'">
|
||||
{{ release.name || release.tag_name }}
|
||||
</h2>
|
||||
<p class="text-sm mt-1" :class="isDark ? 'text-gray-400' : 'text-gray-500'">
|
||||
<p class="mt-1 text-sm" :class="isDark ? 'text-gray-400' : 'text-gray-500'">
|
||||
{{ formatDate(release.published_at) }}
|
||||
</p>
|
||||
</div>
|
||||
<span
|
||||
class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium"
|
||||
class="inline-flex items-center rounded-full px-3 py-1 text-sm font-medium"
|
||||
:class="isDark ? 'bg-green-900 text-green-200' : 'bg-green-100 text-green-800'">
|
||||
{{ release.tag_name }}
|
||||
</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { exec } from 'child_process'
|
||||
import * as fs from 'fs/promises'
|
||||
import linguistLanguages from 'linguist-languages'
|
||||
import * as linguistLanguages from 'linguist-languages'
|
||||
import * as path from 'path'
|
||||
import { promisify } from 'util'
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import '@renderer/databases'
|
||||
|
||||
import { HeroUIProvider } from '@heroui/react'
|
||||
import { loggerService } from '@logger'
|
||||
import store, { persistor } from '@renderer/store'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { Provider } from 'react-redux'
|
||||
import { PersistGate } from 'redux-persist/integration/react'
|
||||
|
||||
import { ToastPortal } from './components/ToastPortal'
|
||||
import TopViewContainer from './components/TopView'
|
||||
import AntdProvider from './context/AntdProvider'
|
||||
import { CodeStyleProvider } from './context/CodeStyleProvider'
|
||||
@@ -32,21 +34,24 @@ function App(): React.ReactElement {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<StyleSheetManager>
|
||||
<ThemeProvider>
|
||||
<AntdProvider>
|
||||
<NotificationProvider>
|
||||
<CodeStyleProvider>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<TopViewContainer>
|
||||
<Router />
|
||||
</TopViewContainer>
|
||||
</PersistGate>
|
||||
</CodeStyleProvider>
|
||||
</NotificationProvider>
|
||||
</AntdProvider>
|
||||
</ThemeProvider>
|
||||
</StyleSheetManager>
|
||||
<HeroUIProvider className="flex flex-1">
|
||||
<StyleSheetManager>
|
||||
<ThemeProvider>
|
||||
<AntdProvider>
|
||||
<NotificationProvider>
|
||||
<CodeStyleProvider>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<TopViewContainer>
|
||||
<Router />
|
||||
</TopViewContainer>
|
||||
</PersistGate>
|
||||
</CodeStyleProvider>
|
||||
</NotificationProvider>
|
||||
</AntdProvider>
|
||||
</ThemeProvider>
|
||||
</StyleSheetManager>
|
||||
<ToastPortal />
|
||||
</HeroUIProvider>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
)
|
||||
|
||||
60
src/renderer/src/assets/styles/CommandListPopover.css
Normal file
60
src/renderer/src/assets/styles/CommandListPopover.css
Normal file
@@ -0,0 +1,60 @@
|
||||
.command-list-popover {
|
||||
/* Base styles are handled inline for theme support */
|
||||
|
||||
/* Arrow styles based on placement */
|
||||
}
|
||||
|
||||
.command-list-popover[data-placement^='bottom'] {
|
||||
transform-origin: top center;
|
||||
animation: slideDownAndFadeIn 0.15s ease-out;
|
||||
}
|
||||
|
||||
.command-list-popover[data-placement^='top'] {
|
||||
transform-origin: bottom center;
|
||||
animation: slideUpAndFadeIn 0.15s ease-out;
|
||||
}
|
||||
|
||||
.command-list-popover[data-placement*='start'] {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.command-list-popover[data-placement*='end'] {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
@keyframes slideDownAndFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px) scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUpAndFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(8px) scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure smooth scrolling in virtual list */
|
||||
.command-list-popover .dynamic-virtual-list {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Better focus indicators */
|
||||
.command-list-popover [data-index] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.command-list-popover [data-index]:focus-visible {
|
||||
outline: 2px solid var(--color-primary, #1677ff);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
.command-list-popover {
|
||||
// Base styles are handled inline for theme support
|
||||
|
||||
// Arrow styles based on placement
|
||||
&[data-placement^='bottom'] {
|
||||
transform-origin: top center;
|
||||
animation: slideDownAndFadeIn 0.15s ease-out;
|
||||
}
|
||||
|
||||
&[data-placement^='top'] {
|
||||
transform-origin: bottom center;
|
||||
animation: slideUpAndFadeIn 0.15s ease-out;
|
||||
}
|
||||
|
||||
&[data-placement*='start'] {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
&[data-placement*='end'] {
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideDownAndFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px) scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUpAndFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(8px) scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure smooth scrolling in virtual list
|
||||
.command-list-popover .dynamic-virtual-list {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
// Better focus indicators
|
||||
.command-list-popover [data-index] {
|
||||
position: relative;
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--color-primary, #1677ff);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
}
|
||||
@@ -10,14 +10,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 电磁波扩散效果
|
||||
/* 电磁波扩散效果 */
|
||||
.animation-pulse {
|
||||
--pulse-color: 59, 130, 246;
|
||||
--pulse-size: 8px;
|
||||
animation: animation-pulse 1.5s infinite;
|
||||
}
|
||||
|
||||
// Modal动画
|
||||
/* Modal动画 */
|
||||
@keyframes animation-move-down-in {
|
||||
0% {
|
||||
transform: translate3d(0, 100%, 0);
|
||||
@@ -54,7 +54,7 @@
|
||||
animation-duration: 0.25s;
|
||||
}
|
||||
|
||||
// 旋转动画
|
||||
/* 旋转动画 */
|
||||
@keyframes animation-rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
@@ -69,7 +69,7 @@
|
||||
animation: animation-rotate 0.75s linear infinite;
|
||||
}
|
||||
|
||||
// 定位高亮动画
|
||||
/* 定位高亮动画 */
|
||||
@keyframes animation-locate-highlight {
|
||||
0% {
|
||||
background-color: transparent;
|
||||
238
src/renderer/src/assets/styles/ant.css
Normal file
238
src/renderer/src/assets/styles/ant.css
Normal file
@@ -0,0 +1,238 @@
|
||||
@import './container.css';
|
||||
|
||||
/* Modal 关闭按钮不应该可拖拽,以确保点击正常 */
|
||||
.ant-modal-close {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
/* 普通 Drawer 内容不应该可拖拽 */
|
||||
.ant-drawer-content {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
/* minapp-drawer 有自己的拖拽规则 */
|
||||
|
||||
/* 下拉菜单和弹出框内容不应该可拖拽 */
|
||||
.ant-dropdown,
|
||||
.ant-dropdown-menu,
|
||||
.ant-popover-content,
|
||||
.ant-tooltip-content,
|
||||
.ant-popconfirm {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
#inputbar {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.ant-image-preview-switch-left {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.ant-btn:not(:disabled):focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Align lucide icon in Button */
|
||||
.ant-btn .ant-btn-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ant-tabs-tabpane:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ant-tabs-tab-btn {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.ant-segmented-group {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.minapp-drawer .ant-drawer-content-wrapper {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.minapp-drawer .ant-drawer-header {
|
||||
position: absolute;
|
||||
-webkit-app-region: drag;
|
||||
min-height: calc(var(--navbar-height) + 0.5px);
|
||||
margin-top: -0.5px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.minapp-drawer .ant-drawer-body {
|
||||
padding: 0;
|
||||
margin-top: var(--navbar-height);
|
||||
overflow: hidden;
|
||||
/* 手动展开 @extend #content-container 的内容 */
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
.minapp-drawer .minapp-mask {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
[navbar-position='left'] .minapp-drawer {
|
||||
max-width: calc(100vw - var(--sidebar-width));
|
||||
}
|
||||
|
||||
[navbar-position='left'] .minapp-drawer .ant-drawer-header {
|
||||
width: calc(100vw - var(--sidebar-width));
|
||||
}
|
||||
|
||||
[navbar-position='top'] .minapp-drawer {
|
||||
max-width: 100vw;
|
||||
}
|
||||
|
||||
[navbar-position='top'] .minapp-drawer .ant-drawer-header {
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.ant-drawer-header {
|
||||
/* 普通 drawer header 不应该可拖拽,除非被 minapp-drawer 覆盖 */
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.message-attachments .ant-upload-list-item:hover {
|
||||
background-color: initial !important;
|
||||
}
|
||||
|
||||
.ant-dropdown-menu .ant-dropdown-menu-sub {
|
||||
max-height: 80vh;
|
||||
width: max-content;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
border: 0.5px solid var(--color-border);
|
||||
}
|
||||
|
||||
.ant-dropdown {
|
||||
background-color: var(--ant-color-bg-elevated);
|
||||
overflow: hidden;
|
||||
border-radius: var(--ant-border-radius-lg);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.ant-dropdown .ant-dropdown-menu {
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
border: 0.5px solid var(--color-border);
|
||||
}
|
||||
|
||||
/* Align lucide icon in dropdown menu item extra */
|
||||
.ant-dropdown .ant-dropdown-menu .ant-dropdown-menu-submenu-expand-icon,
|
||||
.ant-dropdown .ant-dropdown-menu .ant-dropdown-menu-item-extra {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ant-dropdown .ant-dropdown-arrow + .ant-dropdown-menu {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ant-select-dropdown {
|
||||
border: 0.5px solid var(--color-border);
|
||||
}
|
||||
|
||||
.ant-dropdown-menu-submenu {
|
||||
background-color: var(--ant-color-bg-elevated);
|
||||
overflow: hidden;
|
||||
border-radius: var(--ant-border-radius-lg);
|
||||
}
|
||||
|
||||
.ant-dropdown-menu-submenu .ant-dropdown-menu-submenu-title {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ant-popover .ant-popover-inner {
|
||||
border: 0.5px solid var(--color-border);
|
||||
}
|
||||
|
||||
.ant-popover .ant-popover-inner .ant-popover-inner-content {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.ant-popover .ant-popover-arrow + .ant-popover-content .ant-popover-inner {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) .ant-modal-confirm-body-has-title {
|
||||
padding: 16px 0 0 0;
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) .ant-modal-content {
|
||||
border-radius: 10px;
|
||||
border: 0.5px solid var(--color-border);
|
||||
padding: 0 0 8px 0;
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) .ant-modal-content .ant-modal-close {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) .ant-modal-content .ant-modal-header {
|
||||
padding: 16px 16px 0 16px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) .ant-modal-content .ant-modal-body {
|
||||
/* 保持 body 在视口内,使用标准的最大高度 */
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
padding: 0 16px 0 16px;
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) .ant-modal-content .ant-modal-footer {
|
||||
padding: 0 16px 8px 16px;
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) .ant-modal-content .ant-modal-confirm-btns {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ant-modal.ant-modal-confirm.ant-modal-confirm-confirm .ant-modal-content {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.ant-collapse:not(.ant-collapse-ghost) {
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.ant-color-picker .ant-collapse:not(.ant-collapse-ghost) {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ant-collapse:not(.ant-collapse-ghost) .ant-collapse-content {
|
||||
border-top: 0.5px solid var(--color-border) !important;
|
||||
}
|
||||
|
||||
.ant-color-picker .ant-collapse:not(.ant-collapse-ghost) .ant-collapse-content {
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.ant-slider .ant-slider-handle::after {
|
||||
box-shadow: 0 1px 4px 0px rgb(128 128 128 / 50%) !important;
|
||||
}
|
||||
|
||||
.ant-splitter-bar .ant-splitter-bar-dragger::before {
|
||||
background-color: var(--color-border) !important;
|
||||
transition:
|
||||
background-color 0.15s ease,
|
||||
width 0.15s ease;
|
||||
}
|
||||
|
||||
.ant-splitter-bar .ant-splitter-bar-dragger:hover::before {
|
||||
width: 4px !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
transition-delay: 0.15s;
|
||||
}
|
||||
|
||||
.ant-splitter-bar .ant-splitter-bar-dragger-active::before {
|
||||
width: 4px !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
@use './container.scss';
|
||||
|
||||
/* Modal 关闭按钮不应该可拖拽,以确保点击正常 */
|
||||
.ant-modal-close {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
/* 普通 Drawer 内容不应该可拖拽 */
|
||||
.ant-drawer-content {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
/* minapp-drawer 有自己的拖拽规则 */
|
||||
|
||||
/* 下拉菜单和弹出框内容不应该可拖拽 */
|
||||
.ant-dropdown,
|
||||
.ant-dropdown-menu,
|
||||
.ant-popover-content,
|
||||
.ant-tooltip-content,
|
||||
.ant-popconfirm {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
#inputbar {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.ant-image-preview-switch-left {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.ant-btn:not(:disabled):focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// Align lucide icon in Button
|
||||
.ant-btn .ant-btn-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ant-tabs-tabpane:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ant-tabs-tab-btn {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.ant-segmented-group {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.minapp-drawer {
|
||||
[navbar-position='left'] & {
|
||||
max-width: calc(100vw - var(--sidebar-width));
|
||||
.ant-drawer-header {
|
||||
width: calc(100vw - var(--sidebar-width));
|
||||
}
|
||||
}
|
||||
[navbar-position='top'] & {
|
||||
max-width: 100vw;
|
||||
.ant-drawer-header {
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
.ant-drawer-content-wrapper {
|
||||
box-shadow: none;
|
||||
}
|
||||
.ant-drawer-header {
|
||||
position: absolute;
|
||||
-webkit-app-region: drag;
|
||||
min-height: calc(var(--navbar-height) + 0.5px);
|
||||
margin-top: -0.5px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.ant-drawer-body {
|
||||
padding: 0;
|
||||
margin-top: var(--navbar-height);
|
||||
overflow: hidden;
|
||||
@extend #content-container;
|
||||
}
|
||||
.minapp-mask {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-drawer-header {
|
||||
/* 普通 drawer header 不应该可拖拽,除非被 minapp-drawer 覆盖 */
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.message-attachments {
|
||||
.ant-upload-list-item:hover {
|
||||
background-color: initial !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-dropdown-menu .ant-dropdown-menu-sub {
|
||||
max-height: 80vh;
|
||||
width: max-content;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
border: 0.5px solid var(--color-border);
|
||||
}
|
||||
.ant-dropdown {
|
||||
background-color: var(--ant-color-bg-elevated);
|
||||
overflow: hidden;
|
||||
border-radius: var(--ant-border-radius-lg);
|
||||
user-select: none;
|
||||
.ant-dropdown-menu {
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
border: 0.5px solid var(--color-border);
|
||||
|
||||
// Align lucide icon in dropdown menu item extra
|
||||
.ant-dropdown-menu-submenu-expand-icon,
|
||||
.ant-dropdown-menu-item-extra {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.ant-dropdown-arrow + .ant-dropdown-menu {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.ant-select-dropdown {
|
||||
border: 0.5px solid var(--color-border);
|
||||
}
|
||||
.ant-dropdown-menu-submenu {
|
||||
background-color: var(--ant-color-bg-elevated);
|
||||
overflow: hidden;
|
||||
border-radius: var(--ant-border-radius-lg);
|
||||
|
||||
.ant-dropdown-menu-submenu-title {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-popover {
|
||||
.ant-popover-inner {
|
||||
border: 0.5px solid var(--color-border);
|
||||
.ant-popover-inner-content {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
.ant-popover-arrow + .ant-popover-content {
|
||||
.ant-popover-inner {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-modal:not(.ant-modal-confirm) {
|
||||
.ant-modal-confirm-body-has-title {
|
||||
padding: 16px 0 0 0;
|
||||
}
|
||||
.ant-modal-content {
|
||||
border-radius: 10px;
|
||||
border: 0.5px solid var(--color-border);
|
||||
padding: 0 0 8px 0;
|
||||
.ant-modal-close {
|
||||
margin-right: 2px;
|
||||
}
|
||||
.ant-modal-header {
|
||||
padding: 16px 16px 0 16px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.ant-modal-body {
|
||||
/* 保持 body 在视口内,使用标准的最大高度 */
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
padding: 0 16px 0 16px;
|
||||
}
|
||||
.ant-modal-footer {
|
||||
padding: 0 16px 8px 16px;
|
||||
}
|
||||
.ant-modal-confirm-btns {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-modal.ant-modal-confirm.ant-modal-confirm-confirm {
|
||||
.ant-modal-content {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-collapse:not(.ant-collapse-ghost) {
|
||||
border: 1px solid var(--color-border);
|
||||
.ant-color-picker & {
|
||||
border: none;
|
||||
}
|
||||
.ant-collapse-content {
|
||||
border-top: 0.5px solid var(--color-border) !important;
|
||||
.ant-color-picker & {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-slider {
|
||||
.ant-slider-handle::after {
|
||||
box-shadow: 0 1px 4px 0px rgb(128 128 128 / 50%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-splitter-bar {
|
||||
.ant-splitter-bar-dragger {
|
||||
&::before {
|
||||
background-color: var(--color-border) !important;
|
||||
transition:
|
||||
background-color 0.15s ease,
|
||||
width 0.15s ease;
|
||||
}
|
||||
&:hover {
|
||||
&::before {
|
||||
width: 4px !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
transition-delay: 0.15s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-splitter-bar-dragger-active {
|
||||
&::before {
|
||||
width: 4px !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
--color-background-soft: var(--color-black-soft);
|
||||
--color-background-mute: var(--color-black-mute);
|
||||
--color-background-opacity: rgba(34, 34, 34, 0.7);
|
||||
--inner-glow-opacity: 0.3; // For the glassmorphism effect in the dropdown menu
|
||||
--inner-glow-opacity: 0.3; /* For the glassmorphism effect in the dropdown menu */
|
||||
|
||||
--color-primary: #00b96b;
|
||||
--color-primary-soft: #00b96b99;
|
||||
9
src/renderer/src/assets/styles/container.css
Normal file
9
src/renderer/src/assets/styles/container.css
Normal file
@@ -0,0 +1,9 @@
|
||||
#content-container {
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
[navbar-position='left'] #content-container {
|
||||
border-top: 0.5px solid var(--color-border);
|
||||
border-top-left-radius: 10px;
|
||||
border-left: 0.5px solid var(--color-border);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#content-container {
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
[navbar-position='left'] {
|
||||
#content-container {
|
||||
border-top: 0.5px solid var(--color-border);
|
||||
border-top-left-radius: 10px;
|
||||
border-left: 0.5px solid var(--color-border);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
--code-font-family: 'Cascadia Code', 'Fira Code', 'Consolas', Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
// Windows系统专用字体配置
|
||||
/* Windows系统专用字体配置 */
|
||||
body[os='windows'] {
|
||||
--font-family:
|
||||
'Twemoji Country Flags', Ubuntu, -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, Roboto, Oxygen,
|
||||
@@ -1,12 +1,12 @@
|
||||
@use './color.scss';
|
||||
@use './font.scss';
|
||||
@use './markdown.scss';
|
||||
@use './ant.scss';
|
||||
@use './scrollbar.scss';
|
||||
@use './container.scss';
|
||||
@use './animation.scss';
|
||||
@use './richtext.scss';
|
||||
@use './responsive.scss';
|
||||
@import './color.css';
|
||||
@import './font.css';
|
||||
@import './markdown.css';
|
||||
@import './ant.css';
|
||||
@import './scrollbar.css';
|
||||
@import './container.css';
|
||||
@import './animation.css';
|
||||
@import './richtext.css';
|
||||
@import './responsive.css';
|
||||
@import '../fonts/icon-fonts/iconfont.css';
|
||||
@import '../fonts/ubuntu/ubuntu.css';
|
||||
@import '../fonts/country-flag-fonts/flag.css';
|
||||
@@ -15,7 +15,7 @@
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
/* margin: 0; */
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@@ -35,11 +35,11 @@ body,
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#root {
|
||||
/* #root {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
}
|
||||
} */
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
@@ -114,62 +114,62 @@ ul {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.bubble:not(.multi-select-mode) {
|
||||
.block-wrapper {
|
||||
display: flow-root;
|
||||
}
|
||||
.bubble:not(.multi-select-mode) .block-wrapper {
|
||||
display: flow-root;
|
||||
}
|
||||
|
||||
.block-wrapper:last-child > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.bubble:not(.multi-select-mode) .block-wrapper:last-child > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.message-content-container > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.bubble:not(.multi-select-mode) .message-content-container > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.message-thought-container {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.bubble:not(.multi-select-mode) .message-thought-container {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.message-user {
|
||||
.message-header {
|
||||
flex-direction: row-reverse;
|
||||
text-align: right;
|
||||
.message-header-info-wrap {
|
||||
flex-direction: row-reverse;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.message-content-container {
|
||||
border-radius: 10px;
|
||||
padding: 10px 16px 10px 16px;
|
||||
background-color: var(--chat-background-user);
|
||||
align-self: self-end;
|
||||
}
|
||||
.MessageFooter {
|
||||
margin-top: 2px;
|
||||
align-self: self-end;
|
||||
}
|
||||
}
|
||||
.bubble:not(.multi-select-mode) .message-user .message-header {
|
||||
flex-direction: row-reverse;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.message-assistant {
|
||||
.message-content-container {
|
||||
padding-left: 0;
|
||||
}
|
||||
.MessageFooter {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.bubble:not(.multi-select-mode) .message-user .message-header .message-header-info-wrap {
|
||||
flex-direction: row-reverse;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
code {
|
||||
color: var(--color-text);
|
||||
}
|
||||
.markdown {
|
||||
display: flow-root;
|
||||
*:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.bubble:not(.multi-select-mode) .message-user .message-content-container {
|
||||
border-radius: 10px;
|
||||
padding: 10px 16px 10px 16px;
|
||||
background-color: var(--chat-background-user);
|
||||
align-self: self-end;
|
||||
}
|
||||
|
||||
.bubble:not(.multi-select-mode) .message-user .MessageFooter {
|
||||
margin-top: 2px;
|
||||
align-self: self-end;
|
||||
}
|
||||
|
||||
.bubble:not(.multi-select-mode) .message-assistant .message-content-container {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.bubble:not(.multi-select-mode) .message-assistant .MessageFooter {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.bubble:not(.multi-select-mode) code {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.bubble:not(.multi-select-mode) .markdown {
|
||||
display: flow-root;
|
||||
}
|
||||
|
||||
.bubble:not(.multi-select-mode) .markdown *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.lucide:not(.lucide-custom) {
|
||||
@@ -185,8 +185,6 @@ ul {
|
||||
background-color: var(--color-background-highlight-accent);
|
||||
}
|
||||
|
||||
textarea {
|
||||
&::-webkit-resizer {
|
||||
display: none;
|
||||
}
|
||||
textarea::-webkit-resizer {
|
||||
display: none;
|
||||
}
|
||||
388
src/renderer/src/assets/styles/markdown.css
Normal file
388
src/renderer/src/assets/styles/markdown.css
Normal file
@@ -0,0 +1,388 @@
|
||||
.markdown {
|
||||
color: var(--color-text);
|
||||
line-height: 1.6;
|
||||
user-select: text;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.markdown h1:first-child,
|
||||
.markdown h2:first-child,
|
||||
.markdown h3:first-child,
|
||||
.markdown h4:first-child,
|
||||
.markdown h5:first-child,
|
||||
.markdown h6:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.markdown h1,
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
margin: 1.5em 0 1em 0;
|
||||
line-height: 1.3;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2em;
|
||||
border-bottom: 0.5px solid var(--color-border);
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 1.5em;
|
||||
border-bottom: 0.5px solid var(--color-border);
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1.3em 0;
|
||||
white-space: pre-wrap;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.markdown p:last-child {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.markdown p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.markdown p:has(+ ul) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown ul {
|
||||
list-style: initial;
|
||||
}
|
||||
|
||||
.markdown ul,
|
||||
.markdown ol {
|
||||
padding-left: 1.5em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.markdown li pre {
|
||||
margin: 1.5em 0 !important;
|
||||
}
|
||||
|
||||
.markdown li::marker {
|
||||
color: var(--color-text-3);
|
||||
}
|
||||
|
||||
.markdown li > ul,
|
||||
.markdown li > ol {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
border: none;
|
||||
border-top: 0.5px solid var(--color-border);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.markdown span {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.markdown .katex span {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.markdown p code,
|
||||
.markdown li code {
|
||||
background: var(--color-background-mute);
|
||||
padding: 3px 5px;
|
||||
margin: 0 2px;
|
||||
border-radius: 5px;
|
||||
word-break: keep-all;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
font-family: var(--code-font-family);
|
||||
}
|
||||
|
||||
.markdown pre {
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
font-family: var(--code-font-family);
|
||||
background-color: var(--color-background-mute);
|
||||
}
|
||||
|
||||
.markdown pre:has(.special-preview) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.markdown pre:not(pre pre) > code:not(pre pre > code) {
|
||||
padding: 15px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.markdown pre pre {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.markdown pre pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.markdown pre + pre {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.markdown .markdown-alert,
|
||||
.markdown blockquote {
|
||||
margin: 1.5em 0;
|
||||
padding: 1em 1.5em;
|
||||
background-color: var(--color-background-soft);
|
||||
border-left: 4px solid var(--color-primary);
|
||||
border-radius: 0 8px 8px 0;
|
||||
font-style: italic;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.markdown table {
|
||||
--table-border-radius: 8px;
|
||||
margin: 2em 0;
|
||||
font-size: 0.9em;
|
||||
width: 100%;
|
||||
border-radius: var(--table-border-radius);
|
||||
overflow: hidden;
|
||||
border-collapse: separate;
|
||||
border: 0.5px solid var(--color-border);
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.markdown th,
|
||||
.markdown td {
|
||||
border-right: 0.5px solid var(--color-border);
|
||||
border-bottom: 0.5px solid var(--color-border);
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.markdown th:last-child,
|
||||
.markdown td:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.markdown tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.markdown th {
|
||||
background-color: var(--color-background-mute);
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown tr:hover {
|
||||
background-color: var(--color-background-soft);
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown a,
|
||||
.markdown .link {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.markdown a:hover,
|
||||
.markdown .link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.markdown em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.markdown del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.markdown sup,
|
||||
.markdown sub {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.markdown sup {
|
||||
top: -0.5em;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color-reference);
|
||||
color: var(--color-reference-text);
|
||||
padding: 2px 5px;
|
||||
zoom: 0.8;
|
||||
}
|
||||
|
||||
.markdown sup > span.link {
|
||||
color: var(--color-reference-text);
|
||||
}
|
||||
|
||||
.markdown sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
.markdown .footnote-ref {
|
||||
font-size: 0.8em;
|
||||
vertical-align: super;
|
||||
line-height: 0;
|
||||
margin: 0 2px;
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown .footnote-ref:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.footnotes {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding-top: 1em;
|
||||
|
||||
background-color: var(--color-reference-background);
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.footnotes h4 {
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footnotes a {
|
||||
color: var(--color-link);
|
||||
}
|
||||
|
||||
.footnotes ol {
|
||||
padding-left: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footnotes ol li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.footnotes li {
|
||||
font-size: 0.9em;
|
||||
margin-bottom: 0.5em;
|
||||
color: var(--color-text-light);
|
||||
}
|
||||
|
||||
.footnotes li p {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footnotes .footnote-backref {
|
||||
font-size: 0.8em;
|
||||
vertical-align: super;
|
||||
line-height: 0;
|
||||
margin-left: 5px;
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footnotes .footnote-backref:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
emoji-picker {
|
||||
--border-size: 0;
|
||||
}
|
||||
|
||||
.block-wrapper + .block-wrapper {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.katex,
|
||||
mjx-container {
|
||||
display: inline-block;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-wrap: break-word;
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
padding: 1px 2px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
/* Shiki 相关样式 */
|
||||
.shiki {
|
||||
font-family: var(--code-font-family);
|
||||
/* 保持行高为初始值,在 shiki 代码块中处理 */
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
/* CodeMirror 相关样式 */
|
||||
.cm-editor {
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.cm-editor.cm-focused {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.cm-editor .cm-scroller {
|
||||
font-family: var(--code-font-family);
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.cm-editor .cm-scroller .cm-gutters {
|
||||
line-height: 1.6;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.cm-editor .cm-scroller .cm-content {
|
||||
line-height: 1.6;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
.cm-editor .cm-scroller .cm-lineWrapping * {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.cm-editor .cm-announced {
|
||||
position: absolute;
|
||||
display: none;
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
.markdown {
|
||||
color: var(--color-text);
|
||||
line-height: 1.6;
|
||||
user-select: text;
|
||||
word-break: break-word;
|
||||
|
||||
h1:first-child,
|
||||
h2:first-child,
|
||||
h3:first-child,
|
||||
h4:first-child,
|
||||
h5:first-child,
|
||||
h6:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 1.5em 0 1em 0;
|
||||
line-height: 1.3;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2em;
|
||||
border-bottom: 0.5px solid var(--color-border);
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
border-bottom: 0.5px solid var(--color-border);
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1.3em 0;
|
||||
white-space: pre-wrap;
|
||||
line-height: 1.6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:has(+ ul) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: initial;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1.5em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5em;
|
||||
pre {
|
||||
margin: 1.5em 0 !important;
|
||||
}
|
||||
&::marker {
|
||||
color: var(--color-text-3);
|
||||
}
|
||||
}
|
||||
|
||||
li > ul,
|
||||
li > ol {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 0.5px solid var(--color-border);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
span {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.katex span {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
p code,
|
||||
li code {
|
||||
background: var(--color-background-mute);
|
||||
padding: 3px 5px;
|
||||
margin: 0 2px;
|
||||
border-radius: 5px;
|
||||
word-break: keep-all;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--code-font-family);
|
||||
}
|
||||
|
||||
pre {
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
font-family: var(--code-font-family);
|
||||
background-color: var(--color-background-mute);
|
||||
&:has(.special-preview) {
|
||||
background-color: transparent;
|
||||
}
|
||||
&:not(pre pre) {
|
||||
> code:not(pre pre > code) {
|
||||
padding: 15px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
pre {
|
||||
margin: 0 !important;
|
||||
code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pre + pre {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.markdown-alert,
|
||||
blockquote {
|
||||
margin: 1.5em 0;
|
||||
padding: 1em 1.5em;
|
||||
background-color: var(--color-background-soft);
|
||||
border-left: 4px solid var(--color-primary);
|
||||
border-radius: 0 8px 8px 0;
|
||||
font-style: italic;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
table {
|
||||
--table-border-radius: 8px;
|
||||
margin: 2em 0;
|
||||
font-size: 0.9em;
|
||||
width: 100%;
|
||||
border-radius: var(--table-border-radius);
|
||||
overflow: hidden;
|
||||
border-collapse: separate;
|
||||
border: 0.5px solid var(--color-border);
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border-right: 0.5px solid var(--color-border);
|
||||
border-bottom: 0.5px solid var(--color-border);
|
||||
padding: 0.5em;
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: var(--color-background-mute);
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background-color: var(--color-background-soft);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
a,
|
||||
.link {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
sup,
|
||||
sub {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color-reference);
|
||||
color: var(--color-reference-text);
|
||||
padding: 2px 5px;
|
||||
zoom: 0.8;
|
||||
& > span.link {
|
||||
color: var(--color-reference-text);
|
||||
}
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
.footnote-ref {
|
||||
font-size: 0.8em;
|
||||
vertical-align: super;
|
||||
line-height: 0;
|
||||
margin: 0 2px;
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footnotes {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding-top: 1em;
|
||||
|
||||
background-color: var(--color-reference-background);
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
|
||||
h4 {
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 1em;
|
||||
margin: 0;
|
||||
li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 0.9em;
|
||||
margin-bottom: 0.5em;
|
||||
color: var(--color-text-light);
|
||||
|
||||
p {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.footnote-backref {
|
||||
font-size: 0.8em;
|
||||
vertical-align: super;
|
||||
line-height: 0;
|
||||
margin-left: 5px;
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emoji-picker {
|
||||
--border-size: 0;
|
||||
}
|
||||
|
||||
.block-wrapper + .block-wrapper {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.katex,
|
||||
mjx-container {
|
||||
display: inline-block;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-wrap: break-word;
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
padding: 1px 2px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
/* Shiki 相关样式 */
|
||||
.shiki {
|
||||
font-family: var(--code-font-family);
|
||||
// 保持行高为初始值,在 shiki 代码块中处理
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
/* CodeMirror 相关样式 */
|
||||
.cm-editor {
|
||||
border-radius: inherit;
|
||||
|
||||
&.cm-focused {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
font-family: var(--code-font-family);
|
||||
border-radius: inherit;
|
||||
|
||||
.cm-gutters {
|
||||
line-height: 1.6;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.cm-content {
|
||||
line-height: 1.6;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
.cm-lineWrapping * {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-announced {
|
||||
position: absolute;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// xl, xxl, default style
|
||||
/* xl, xxl, default style */
|
||||
:root {
|
||||
--navbar-height: 44px;
|
||||
--sidebar-width: 50px;
|
||||
@@ -17,7 +17,7 @@
|
||||
--list-item-border-radius: 20px;
|
||||
}
|
||||
|
||||
// lg
|
||||
/* lg */
|
||||
@media (max-width: 1080px) {
|
||||
:root {
|
||||
--assistants-width: 210px;
|
||||
522
src/renderer/src/assets/styles/richtext.css
Normal file
522
src/renderer/src/assets/styles/richtext.css
Normal file
@@ -0,0 +1,522 @@
|
||||
.tiptap {
|
||||
/* 预留5px给scrollbar */
|
||||
padding: 12px 55px 12px 60px;
|
||||
outline: none;
|
||||
min-height: 120px;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.tiptap:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.tiptap :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.tiptap h1:first-child,
|
||||
.tiptap h2:first-child,
|
||||
.tiptap h3:first-child,
|
||||
.tiptap h4:first-child,
|
||||
.tiptap h5:first-child,
|
||||
.tiptap h6:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.tiptap h1,
|
||||
.tiptap h2,
|
||||
.tiptap h3,
|
||||
.tiptap h4,
|
||||
.tiptap h5,
|
||||
.tiptap h6 {
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
line-height: 1.1;
|
||||
text-wrap: pretty;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tiptap h1 code,
|
||||
.tiptap h2 code,
|
||||
.tiptap h3 code,
|
||||
.tiptap h4 code,
|
||||
.tiptap h5 code,
|
||||
.tiptap h6 code {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.tiptap h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.tiptap h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.tiptap h3 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.tiptap h4,
|
||||
.tiptap h5,
|
||||
.tiptap h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.tiptap p {
|
||||
margin: 1.1rem 0 0.5rem 0;
|
||||
white-space: normal;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
width: 100%;
|
||||
line-height: 1.6;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.tiptap p:has(+ ul) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tiptap a {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tiptap a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.tiptap blockquote {
|
||||
border-left: 4px solid var(--color-primary);
|
||||
margin: 1.5rem 0;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.tiptap code {
|
||||
background-color: var(--color-inline-code-background);
|
||||
border-radius: 0.4rem;
|
||||
color: var(--color-inline-code-text);
|
||||
font-size: 0.85rem;
|
||||
padding: 0.25em 0.3em;
|
||||
font-family: var(--code-font-family);
|
||||
}
|
||||
|
||||
.tiptap pre {
|
||||
background: var(--color-code-background);
|
||||
border-radius: 0.5rem;
|
||||
color: var(--color-text);
|
||||
font-family: var(--code-font-family);
|
||||
margin: 1.5rem 0;
|
||||
padding: 0.75rem 1rem;
|
||||
border: 1px solid var(--color-border-soft);
|
||||
}
|
||||
|
||||
.tiptap pre code {
|
||||
background: none;
|
||||
color: inherit;
|
||||
font-size: 0.8rem;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.tiptap hr {
|
||||
border: none;
|
||||
border-top: 1px solid var(--color-gray-2);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.tiptap em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.tiptap u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.tiptap strong,
|
||||
.tiptap strong * {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tiptap .placeholder {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tiptap .placeholder:before {
|
||||
content: attr(data-placeholder);
|
||||
position: absolute;
|
||||
color: var(--color-text-secondary);
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
font-style: italic;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/* Ensure drag handles and plus buttons remain interactive */
|
||||
.tiptap .placeholder .drag-handle,
|
||||
.tiptap .placeholder .plus-button {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Show placeholder only when focused or when it's the only empty node */
|
||||
.tiptap .placeholder.has-focus:before {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.tiptap img {
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.tiptap table {
|
||||
border-collapse: collapse;
|
||||
margin: 0;
|
||||
/* Allow action endpoints (rendered as decorations) to slightly overflow table edges */
|
||||
overflow: visible;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tiptap td,
|
||||
.tiptap th {
|
||||
border: 1px solid var(--color-border-soft);
|
||||
box-sizing: border-box;
|
||||
display: table-cell;
|
||||
min-width: 120px;
|
||||
padding: 6px 8px;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tiptap td > *,
|
||||
.tiptap th > * {
|
||||
margin-bottom: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tiptap th,
|
||||
.tiptap th * {
|
||||
background-color: var(--color-gray-3);
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tiptap .selectedCell {
|
||||
position: relative; /* 确保伪元素定位 */
|
||||
}
|
||||
|
||||
.tiptap .selectedCell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
border: 0 solid var(--color-primary);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.tiptap .selectedCell.selection-top::after {
|
||||
border-top-width: 2px;
|
||||
}
|
||||
|
||||
.tiptap .selectedCell.selection-bottom::after {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
|
||||
.tiptap .selectedCell.selection-left::after {
|
||||
border-left-width: 2px;
|
||||
}
|
||||
|
||||
.tiptap .selectedCell.selection-right::after {
|
||||
border-right-width: 2px;
|
||||
}
|
||||
|
||||
.tiptap .column-resize-handle {
|
||||
background-color: var(--color-primary);
|
||||
bottom: -2px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
top: 0;
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.tiptap table:has(.selectedCell) {
|
||||
caret-color: transparent !important;
|
||||
user-select: none !important;
|
||||
}
|
||||
|
||||
.tiptap table:has(.selectedCell) *::selection {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.tiptap table:has(.selectedCell) .column-resize-handle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Position row action buttons relative to first column cells */
|
||||
.tiptap table tbody tr td:first-child,
|
||||
.tiptap table tbody tr th:first-child {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Position column action buttons relative to first row cells */
|
||||
.tiptap table tbody tr:first-child td,
|
||||
.tiptap table tbody tr:first-child th {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper {
|
||||
position: relative;
|
||||
margin: 1rem 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 25px;
|
||||
grid-template-rows: 1fr 25px;
|
||||
grid-template-areas:
|
||||
'table column-btn'
|
||||
'row-btn corner';
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .table-container {
|
||||
grid-area: table;
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .table-container::-webkit-scrollbar {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .table-container::-webkit-scrollbar:horizontal {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .table-container::-webkit-scrollbar-thumb {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .table-container::-webkit-scrollbar-track {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .table-container table {
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .add-row-button,
|
||||
.tiptap .tableWrapper .add-column-button {
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-bg-base);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-text);
|
||||
z-index: 20;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .add-row-button:hover,
|
||||
.tiptap .tableWrapper .add-column-button:hover {
|
||||
background: var(--color-primary);
|
||||
color: white;
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .add-row-button:active,
|
||||
.tiptap .tableWrapper .add-column-button:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .add-row-button::before,
|
||||
.tiptap .tableWrapper .add-column-button::before {
|
||||
content: '+';
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .add-row-button {
|
||||
grid-area: row-btn;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .add-column-button {
|
||||
grid-area: column-btn;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper:hover .add-row-button,
|
||||
.tiptap .tableWrapper:has(.add-row-button:hover) .add-row-button,
|
||||
.tiptap .tableWrapper:has(.add-column-button:hover) .add-row-button,
|
||||
.tiptap .tableWrapper:hover .add-column-button,
|
||||
.tiptap .tableWrapper:has(.add-row-button:hover) .add-column-button,
|
||||
.tiptap .tableWrapper:has(.add-column-button:hover) .add-column-button {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Do not show in readonly even on hover */
|
||||
.tiptap .tableWrapper.is-readonly .add-row-button,
|
||||
.tiptap .tableWrapper.is-readonly:hover .add-row-button,
|
||||
.tiptap .tableWrapper.is-readonly .add-column-button,
|
||||
.tiptap .tableWrapper.is-readonly:hover .add-column-button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .add-row-button:hover,
|
||||
.tiptap .tableWrapper .add-column-button:hover {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
/* Row/Column action triggers (visible on cell selection) */
|
||||
.tiptap .tableWrapper .row-action-trigger,
|
||||
.tiptap .tableWrapper .column-action-trigger {
|
||||
position: absolute;
|
||||
height: 20px;
|
||||
border-radius: 8px;
|
||||
background: var(--color-primary);
|
||||
color: #fff;
|
||||
border: 1px solid var(--color-primary);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
z-index: 30;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.tiptap .tableWrapper .row-action-trigger::before,
|
||||
.tiptap .tableWrapper .column-action-trigger::before {
|
||||
content: '•••';
|
||||
}
|
||||
|
||||
.tiptap.resize-cursor {
|
||||
cursor: ew-resize;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.tiptap ul,
|
||||
.tiptap ol {
|
||||
padding: 0 1rem;
|
||||
margin: 1.25rem 1rem 1.25rem 0.4rem;
|
||||
}
|
||||
|
||||
.tiptap ul li p,
|
||||
.tiptap ol li p {
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
/* Reduce spacing for nested lists */
|
||||
.tiptap ul ul,
|
||||
.tiptap ul ol,
|
||||
.tiptap ol ul,
|
||||
.tiptap ol ol {
|
||||
margin: 0.5rem 0.5rem 0.5rem 0.2rem;
|
||||
}
|
||||
|
||||
.tiptap ul {
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
.tiptap ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.tiptap ul[data-type='taskList'] {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tiptap ul[data-type='taskList'] li {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tiptap ul[data-type='taskList'] li > label {
|
||||
flex: 0 0 auto;
|
||||
margin-right: 0.5rem;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tiptap ul[data-type='taskList'] li > div {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.tiptap ul[data-type='taskList'] li > div p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Checked task item appearance */
|
||||
.tiptap ul[data-type='taskList'] li[data-checked='true'] > div {
|
||||
color: var(--color-text-2);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.tiptap ul[data-type='taskList'] input[type='checkbox'] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Use primary color for checked checkbox */
|
||||
.tiptap ul[data-type='taskList'] input[type='checkbox']:checked {
|
||||
accent-color: var(--color-primary);
|
||||
background-color: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.tiptap ul[data-type='taskList'] ul[data-type='taskList'] {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Math block */
|
||||
.tiptap .block-math-inner {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
/* Bottom spacer to create viewport padding */
|
||||
.tiptap::after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 50px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Code block wrapper and header styles */
|
||||
.code-block-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.code-block-wrapper .code-block-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 6px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.code-block-wrapper:hover .code-block-header {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -1,508 +0,0 @@
|
||||
.tiptap {
|
||||
// 预留5px给scrollbar
|
||||
padding: 12px 55px 12px 60px;
|
||||
outline: none;
|
||||
min-height: 120px;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1:first-child,
|
||||
h2:first-child,
|
||||
h3:first-child,
|
||||
h4:first-child,
|
||||
h5:first-child,
|
||||
h6:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
line-height: 1.1;
|
||||
text-wrap: pretty;
|
||||
font-weight: 600;
|
||||
|
||||
code {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1.1rem 0 0.5rem 0;
|
||||
white-space: normal;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
width: 100%;
|
||||
line-height: 1.6;
|
||||
hyphens: auto;
|
||||
|
||||
&:has(+ ul) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid var(--color-primary);
|
||||
margin: 1.5rem 0;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: var(--color-inline-code-background);
|
||||
border-radius: 0.4rem;
|
||||
color: var(--color-inline-code-text);
|
||||
font-size: 0.85rem;
|
||||
padding: 0.25em 0.3em;
|
||||
font-family: var(--code-font-family);
|
||||
}
|
||||
|
||||
pre {
|
||||
background: var(--color-code-background);
|
||||
border-radius: 0.5rem;
|
||||
color: var(--color-text);
|
||||
font-family: var(--code-font-family);
|
||||
margin: 1.5rem 0;
|
||||
padding: 0.75rem 1rem;
|
||||
border: 1px solid var(--color-border-soft);
|
||||
|
||||
code {
|
||||
background: none;
|
||||
color: inherit;
|
||||
font-size: 0.8rem;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid var(--color-gray-2);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
strong,
|
||||
strong * {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: attr(data-placeholder);
|
||||
position: absolute;
|
||||
color: var(--color-text-secondary);
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
font-style: italic;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/* Ensure drag handles and plus buttons remain interactive */
|
||||
.drag-handle,
|
||||
.plus-button {
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* Show placeholder only when focused or when it's the only empty node */
|
||||
.placeholder.has-focus:before {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
margin: 0;
|
||||
/* Allow action endpoints (rendered as decorations) to slightly overflow table edges */
|
||||
overflow: visible;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
|
||||
td,
|
||||
th {
|
||||
border: 1px solid var(--color-border-soft);
|
||||
box-sizing: border-box;
|
||||
display: table-cell;
|
||||
min-width: 120px;
|
||||
padding: 6px 8px;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
> * {
|
||||
margin-bottom: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
th,
|
||||
th * {
|
||||
background-color: var(--color-gray-3);
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.selectedCell {
|
||||
position: relative; // 确保伪元素定位
|
||||
}
|
||||
.selectedCell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
border: 0 solid var(--color-primary);
|
||||
border-radius: 0;
|
||||
}
|
||||
.selectedCell.selection-top::after {
|
||||
border-top-width: 2px;
|
||||
}
|
||||
.selectedCell.selection-bottom::after {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
.selectedCell.selection-left::after {
|
||||
border-left-width: 2px;
|
||||
}
|
||||
.selectedCell.selection-right::after {
|
||||
border-right-width: 2px;
|
||||
}
|
||||
|
||||
.column-resize-handle {
|
||||
background-color: var(--color-primary);
|
||||
bottom: -2px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
top: 0;
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
&:has(.selectedCell) {
|
||||
caret-color: transparent !important;
|
||||
user-select: none !important;
|
||||
|
||||
*::selection {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.column-resize-handle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Position row action buttons relative to first column cells
|
||||
tbody tr td:first-child,
|
||||
tbody tr th:first-child {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// Position column action buttons relative to first row cells
|
||||
tbody tr:first-child td,
|
||||
tbody tr:first-child th {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.tableWrapper {
|
||||
position: relative;
|
||||
margin: 1rem 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 25px;
|
||||
grid-template-rows: 1fr 25px;
|
||||
grid-template-areas:
|
||||
'table column-btn'
|
||||
'row-btn corner';
|
||||
gap: 5px;
|
||||
|
||||
.table-container {
|
||||
grid-area: table;
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar:horizontal {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
table {
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.add-row-button,
|
||||
.add-column-button {
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-bg-base);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-text);
|
||||
z-index: 20;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
pointer-events: auto;
|
||||
|
||||
&:hover {
|
||||
background: var(--color-primary);
|
||||
color: white;
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '+';
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.add-row-button {
|
||||
grid-area: row-btn;
|
||||
}
|
||||
|
||||
.add-column-button {
|
||||
grid-area: column-btn;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:has(.add-row-button:hover),
|
||||
&:has(.add-column-button:hover) {
|
||||
.add-row-button,
|
||||
.add-column-button {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do not show in readonly even on hover */
|
||||
&.is-readonly,
|
||||
&.is-readonly:hover {
|
||||
.add-row-button,
|
||||
.add-column-button {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.add-row-button:hover,
|
||||
.add-column-button:hover {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
/* Row/Column action triggers (visible on cell selection) */
|
||||
.row-action-trigger,
|
||||
.column-action-trigger {
|
||||
position: absolute;
|
||||
height: 20px;
|
||||
border-radius: 8px;
|
||||
background: var(--color-primary);
|
||||
color: #fff;
|
||||
border: 1px solid var(--color-primary);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
z-index: 30;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.row-action-trigger::before,
|
||||
.column-action-trigger::before {
|
||||
content: '•••';
|
||||
}
|
||||
}
|
||||
|
||||
&.resize-cursor {
|
||||
cursor: ew-resize;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding: 0 1rem;
|
||||
margin: 1.25rem 1rem 1.25rem 0.4rem;
|
||||
|
||||
li p {
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
// Reduce spacing for nested lists
|
||||
ul,
|
||||
ol {
|
||||
margin: 0.5rem 0.5rem 0.5rem 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ul[data-type='taskList'] {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
> label {
|
||||
flex: 0 0 auto;
|
||||
margin-right: 0.5rem;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
> div {
|
||||
flex: 1 1 auto;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Checked task item appearance */
|
||||
li[data-checked='true'] {
|
||||
> div {
|
||||
color: var(--color-text-2);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Use primary color for checked checkbox */
|
||||
input[type='checkbox']:checked {
|
||||
accent-color: var(--color-primary);
|
||||
background-color: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
ul[data-type='taskList'] {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Math block */
|
||||
.block-math-inner {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
/* Bottom spacer to create viewport padding */
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 50px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Code block wrapper and header styles
|
||||
.code-block-wrapper {
|
||||
position: relative;
|
||||
|
||||
.code-block-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 6px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
&:hover .code-block-header {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -31,17 +31,19 @@ body[theme-mode='light'] {
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: var(--scrollbar-thumb-radius);
|
||||
background: var(--color-scrollbar-thumb);
|
||||
&:hover {
|
||||
background: var(--color-scrollbar-thumb-hover);
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--color-scrollbar-thumb-hover);
|
||||
}
|
||||
|
||||
pre:not(.shiki)::-webkit-scrollbar-thumb {
|
||||
border-radius: 0;
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
pre:not(.shiki)::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.shiki-dark {
|
||||
@@ -71,7 +73,8 @@ pre:not(.shiki)::-webkit-scrollbar-thumb {
|
||||
.rc-virtual-list-scrollbar-thumb {
|
||||
border-radius: var(--scrollbar-thumb-radius) !important;
|
||||
background: var(--color-scrollbar-thumb) !important;
|
||||
&:hover {
|
||||
background: var(--color-scrollbar-thumb-hover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.rc-virtual-list-scrollbar-thumb:hover {
|
||||
background: var(--color-scrollbar-thumb-hover) !important;
|
||||
}
|
||||
72
src/renderer/src/assets/styles/selection-toolbar.css
Normal file
72
src/renderer/src/assets/styles/selection-toolbar.css
Normal file
@@ -0,0 +1,72 @@
|
||||
@import './font.css';
|
||||
|
||||
html {
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
|
||||
:root {
|
||||
/* Basic Colors */
|
||||
--color-error: #f44336;
|
||||
|
||||
--selection-toolbar-color-error: var(--color-error);
|
||||
|
||||
/* Toolbar */
|
||||
--selection-toolbar-height: 36px; /* default: 36px max: 42px */
|
||||
--selection-toolbar-font-size: 14px; /* default: 14px */
|
||||
|
||||
--selection-toolbar-logo-display: flex; /* values: flex | none */
|
||||
--selection-toolbar-logo-size: 22px; /* default: 22px */
|
||||
--selection-toolbar-logo-border-width: 0.5px 0 0.5px 0.5px; /* default: none */
|
||||
--selection-toolbar-logo-border-style: solid; /* default: none */
|
||||
--selection-toolbar-logo-border-color: rgba(255, 255, 255, 0.2);
|
||||
--selection-toolbar-logo-margin: 0; /* default: 0 */
|
||||
--selection-toolbar-logo-padding: 0 6px 0 8px; /* default: 0 4px 0 8px */
|
||||
--selection-toolbar-logo-background: transparent; /* default: transparent */
|
||||
|
||||
/* DO NOT MODIFY THESE VALUES, IF YOU DON'T KNOW WHAT YOU ARE DOING */
|
||||
--selection-toolbar-padding: 0; /* default: 0 */
|
||||
--selection-toolbar-margin: 2px 3px 5px 3px; /* default: 2px 3px 5px 3px */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
--selection-toolbar-border-radius: 10px;
|
||||
--selection-toolbar-border: none;
|
||||
--selection-toolbar-box-shadow: 0px 2px 3px rgba(50, 50, 50, 0.3);
|
||||
--selection-toolbar-background: rgba(20, 20, 20, 0.95);
|
||||
|
||||
/* Buttons */
|
||||
--selection-toolbar-buttons-border-width: 0.5px 0.5px 0.5px 0;
|
||||
--selection-toolbar-buttons-border-style: solid;
|
||||
--selection-toolbar-buttons-border-color: rgba(255, 255, 255, 0.2);
|
||||
--selection-toolbar-buttons-border-radius: 0 var(--selection-toolbar-border-radius)
|
||||
var(--selection-toolbar-border-radius) 0;
|
||||
|
||||
--selection-toolbar-button-icon-size: 16px; /* default: 16px */
|
||||
--selection-toolbar-button-direction: row; /* default: row | column */
|
||||
--selection-toolbar-button-text-margin: 0 0 0 0; /* default: 0 0 0 0 */
|
||||
--selection-toolbar-button-margin: 0; /* default: 0 */
|
||||
--selection-toolbar-button-padding: 0 8px; /* default: 0 8px */
|
||||
--selection-toolbar-button-last-padding: 0 12px 0 8px;
|
||||
--selection-toolbar-button-border-radius: 0; /* default: 0 */
|
||||
--selection-toolbar-button-border: none; /* default: none */
|
||||
--selection-toolbar-button-box-shadow: none; /* default: none */
|
||||
|
||||
--selection-toolbar-button-text-color: rgba(255, 255, 245, 0.9);
|
||||
--selection-toolbar-button-icon-color: var(--selection-toolbar-button-text-color);
|
||||
--selection-toolbar-button-bgcolor: transparent; /* default: transparent */
|
||||
--selection-toolbar-button-bgcolor-hover: #333333;
|
||||
}
|
||||
|
||||
[theme-mode='light'] {
|
||||
--selection-toolbar-border: none;
|
||||
--selection-toolbar-box-shadow: 0px 2px 3px rgba(50, 50, 50, 0.1);
|
||||
--selection-toolbar-background: rgba(245, 245, 245, 0.95);
|
||||
|
||||
/* Buttons */
|
||||
--selection-toolbar-buttons-border-color: rgba(0, 0, 0, 0.08);
|
||||
|
||||
--selection-toolbar-logo-border-color: rgba(0, 0, 0, 0.08);
|
||||
|
||||
--selection-toolbar-button-text-color: rgba(0, 0, 0, 1);
|
||||
--selection-toolbar-button-icon-color: var(--selection-toolbar-button-text-color);
|
||||
--selection-toolbar-button-bgcolor-hover: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
@use './font.scss';
|
||||
|
||||
html {
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
|
||||
:root {
|
||||
// Basic Colors
|
||||
--color-error: #f44336;
|
||||
|
||||
--selection-toolbar-color-error: var(--color-error);
|
||||
|
||||
// Toolbar
|
||||
--selection-toolbar-height: 36px; // default: 36px max: 42px
|
||||
--selection-toolbar-font-size: 14px; // default: 14px
|
||||
|
||||
--selection-toolbar-logo-display: flex; // values: flex | none
|
||||
--selection-toolbar-logo-size: 22px; // default: 22px
|
||||
--selection-toolbar-logo-border-width: 0.5px 0 0.5px 0.5px; // default: none
|
||||
--selection-toolbar-logo-border-style: solid; // default: none
|
||||
--selection-toolbar-logo-border-color: rgba(255, 255, 255, 0.2);
|
||||
--selection-toolbar-logo-margin: 0; // default: 0
|
||||
--selection-toolbar-logo-padding: 0 6px 0 8px; // default: 0 4px 0 8px
|
||||
--selection-toolbar-logo-background: transparent; // default: transparent
|
||||
|
||||
// DO NOT MODIFY THESE VALUES, IF YOU DON'T KNOW WHAT YOU ARE DOING
|
||||
--selection-toolbar-padding: 0; // default: 0
|
||||
--selection-toolbar-margin: 2px 3px 5px 3px; // default: 2px 3px 5px 3px
|
||||
// ------------------------------------------------------------
|
||||
|
||||
--selection-toolbar-border-radius: 10px;
|
||||
--selection-toolbar-border: none;
|
||||
--selection-toolbar-box-shadow: 0px 2px 3px rgba(50, 50, 50, 0.3);
|
||||
--selection-toolbar-background: rgba(20, 20, 20, 0.95);
|
||||
|
||||
// Buttons
|
||||
--selection-toolbar-buttons-border-width: 0.5px 0.5px 0.5px 0;
|
||||
--selection-toolbar-buttons-border-style: solid;
|
||||
--selection-toolbar-buttons-border-color: rgba(255, 255, 255, 0.2);
|
||||
--selection-toolbar-buttons-border-radius: 0 var(--selection-toolbar-border-radius)
|
||||
var(--selection-toolbar-border-radius) 0;
|
||||
|
||||
--selection-toolbar-button-icon-size: 16px; // default: 16px
|
||||
--selection-toolbar-button-direction: row; // default: row | column
|
||||
--selection-toolbar-button-text-margin: 0 0 0 0; // default: 0 0 0 0
|
||||
--selection-toolbar-button-margin: 0; // default: 0
|
||||
--selection-toolbar-button-padding: 0 8px; // default: 0 8px
|
||||
--selection-toolbar-button-last-padding: 0 12px 0 8px;
|
||||
--selection-toolbar-button-border-radius: 0; // default: 0
|
||||
--selection-toolbar-button-border: none; // default: none
|
||||
--selection-toolbar-button-box-shadow: none; // default: none
|
||||
|
||||
--selection-toolbar-button-text-color: rgba(255, 255, 245, 0.9);
|
||||
--selection-toolbar-button-icon-color: var(--selection-toolbar-button-text-color);
|
||||
--selection-toolbar-button-bgcolor: transparent; // default: transparent
|
||||
--selection-toolbar-button-bgcolor-hover: #333333;
|
||||
}
|
||||
|
||||
[theme-mode='light'] {
|
||||
--selection-toolbar-border: none;
|
||||
--selection-toolbar-box-shadow: 0px 2px 3px rgba(50, 50, 50, 0.1);
|
||||
--selection-toolbar-background: rgba(245, 245, 245, 0.95);
|
||||
|
||||
// Buttons
|
||||
--selection-toolbar-buttons-border-color: rgba(0, 0, 0, 0.08);
|
||||
|
||||
--selection-toolbar-logo-border-color: rgba(0, 0, 0, 0.08);
|
||||
|
||||
--selection-toolbar-button-text-color: rgba(0, 0, 0, 1);
|
||||
--selection-toolbar-button-icon-color: var(--selection-toolbar-button-text-color);
|
||||
--selection-toolbar-button-bgcolor-hover: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
156
src/renderer/src/assets/styles/tailwind.css
Normal file
156
src/renderer/src/assets/styles/tailwind.css
Normal file
@@ -0,0 +1,156 @@
|
||||
@import 'tailwindcss' source('../../../../renderer');
|
||||
@import 'tw-animate-css';
|
||||
|
||||
/* heroui */
|
||||
@plugin '../../hero.ts';
|
||||
@source '../../../../../node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}';
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
/* 如需自定义:
|
||||
1. 清晰地组织自定义 CSS 到相应的层中。
|
||||
2. 基础样式(如全局重置、链接样式)放入 base 层;
|
||||
3. 可复用的组件样式(如果仍使用 @apply 或原生 CSS 嵌套创建)放入 components 层;
|
||||
4. 新的自定义工具类放入 utilities 层。
|
||||
*/
|
||||
/*To customize:
|
||||
1. Clearly organize custom CSS into the corresponding layers.
|
||||
2. Place basic styles (such as global reset and link styles) in the base layer;
|
||||
3. Put reusable component styles (if still created using @ apply or native CSS nesting) into the components layer;
|
||||
4. Put the new custom utility class into the utilities layer.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.141 0.005 285.823);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.141 0.005 285.823);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.141 0.005 285.823);
|
||||
--primary: oklch(0.21 0.006 285.885);
|
||||
--primary-foreground: oklch(0.985 0 0);
|
||||
--secondary: oklch(0.967 0.001 286.375);
|
||||
--secondary-foreground: oklch(0.21 0.006 285.885);
|
||||
--muted: oklch(0.967 0.001 286.375);
|
||||
--muted-foreground: oklch(0.552 0.016 285.938);
|
||||
--accent: oklch(0.967 0.001 286.375);
|
||||
--accent-foreground: oklch(0.21 0.006 285.885);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.92 0.004 286.32);
|
||||
--input: oklch(0.92 0.004 286.32);
|
||||
--ring: oklch(0.705 0.015 286.067);
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
--chart-3: oklch(0.398 0.07 227.392);
|
||||
--chart-4: oklch(0.828 0.189 84.429);
|
||||
--chart-5: oklch(0.769 0.188 70.08);
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
||||
--sidebar-primary: oklch(0.21 0.006 285.885);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.967 0.001 286.375);
|
||||
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
||||
--sidebar-border: oklch(0.92 0.004 286.32);
|
||||
--sidebar-ring: oklch(0.705 0.015 286.067);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.141 0.005 285.823);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.21 0.006 285.885);
|
||||
--card-foreground: oklch(0.985 0 0);
|
||||
--popover: oklch(0.21 0.006 285.885);
|
||||
--popover-foreground: oklch(0.985 0 0);
|
||||
--primary: oklch(0.92 0.004 286.32);
|
||||
--primary-foreground: oklch(0.21 0.006 285.885);
|
||||
--secondary: oklch(0.274 0.006 286.033);
|
||||
--secondary-foreground: oklch(0.985 0 0);
|
||||
--muted: oklch(0.274 0.006 286.033);
|
||||
--muted-foreground: oklch(0.705 0.015 286.067);
|
||||
--accent: oklch(0.274 0.006 286.033);
|
||||
--accent-foreground: oklch(0.985 0 0);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.552 0.016 285.938);
|
||||
--chart-1: oklch(0.488 0.243 264.376);
|
||||
--chart-2: oklch(0.696 0.17 162.48);
|
||||
--chart-3: oklch(0.769 0.188 70.08);
|
||||
--chart-4: oklch(0.627 0.265 303.9);
|
||||
--chart-5: oklch(0.645 0.246 16.439);
|
||||
--sidebar: oklch(0.21 0.006 285.885);
|
||||
--sidebar-foreground: oklch(0.985 0 0);
|
||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.274 0.006 286.033);
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.552 0.016 285.938);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--animate-marquee: marquee var(--duration) infinite linear;
|
||||
--animate-marquee-vertical: marquee-vertical var(--duration) linear infinite;
|
||||
@keyframes marquee {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
}
|
||||
to {
|
||||
transform: translateX(calc(-100% - var(--gap)));
|
||||
}
|
||||
}
|
||||
@keyframes marquee-vertical {
|
||||
from {
|
||||
transform: translateY(0);
|
||||
}
|
||||
to {
|
||||
transform: translateY(calc(-100% - var(--gap)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Button } from '@heroui/button'
|
||||
import { formatErrorMessage } from '@renderer/utils/error'
|
||||
import { Alert, Button, Space } from 'antd'
|
||||
import { Alert, Space } from 'antd'
|
||||
import { ComponentType, ReactNode } from 'react'
|
||||
import { ErrorBoundary, FallbackProps } from 'react-error-boundary'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const DefaultFallback: ComponentType<FallbackProps> = (props: FallbackProps): ReactNode => {
|
||||
const { t } = useTranslation()
|
||||
const { error } = props
|
||||
@@ -23,10 +23,10 @@ const DefaultFallback: ComponentType<FallbackProps> = (props: FallbackProps): Re
|
||||
type="error"
|
||||
action={
|
||||
<Space>
|
||||
<Button size="small" danger onClick={debug}>
|
||||
<Button size="sm" onPress={debug}>
|
||||
{t('error.boundary.default.devtools')}
|
||||
</Button>
|
||||
<Button size="small" danger onClick={reload}>
|
||||
<Button size="sm" onPress={reload}>
|
||||
{t('error.boundary.default.reload')}
|
||||
</Button>
|
||||
</Space>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { lightbulbVariants } from '@renderer/utils/motionVariants'
|
||||
import { motion } from 'framer-motion'
|
||||
import { motion } from 'motion/react'
|
||||
import { SVGProps } from 'react'
|
||||
|
||||
export const StreamlineGoodHealthAndWellBeing = (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '@renderer/assets/styles/CommandListPopover.scss'
|
||||
import '@renderer/assets/styles/CommandListPopover.css'
|
||||
|
||||
import { DynamicVirtualList, type DynamicVirtualListRef } from '@renderer/components/VirtualList'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
|
||||
27
src/renderer/src/components/ToastPortal.tsx
Normal file
27
src/renderer/src/components/ToastPortal.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { ToastProvider } from '@heroui/toast'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
|
||||
export const ToastPortal = () => {
|
||||
const [mounted, setMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
return () => setMounted(false)
|
||||
}, [])
|
||||
|
||||
if (!mounted) return null
|
||||
|
||||
return createPortal(
|
||||
<ToastProvider
|
||||
placement="bottom-center"
|
||||
regionProps={{
|
||||
className: 'z-[1001]'
|
||||
}}
|
||||
toastProps={{
|
||||
timeout: 3000
|
||||
}}
|
||||
/>,
|
||||
document.body
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// import { loggerService } from '@logger'
|
||||
import { addToast, closeAll, closeToast, getToastQueue, isToastClosing } from '@heroui/toast'
|
||||
import TopViewMinappContainer from '@renderer/components/MinApp/TopViewMinappContainer'
|
||||
import { useAppInit } from '@renderer/hooks/useAppInit'
|
||||
import { useShortcuts } from '@renderer/hooks/useShortcuts'
|
||||
@@ -43,6 +44,13 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
|
||||
useEffect(() => {
|
||||
window.message = messageApi
|
||||
window.modal = modal
|
||||
window.toast = {
|
||||
getToastQueue: getToastQueue,
|
||||
addToast: addToast,
|
||||
closeToast: closeToast,
|
||||
closeAll: closeAll,
|
||||
isToastClosing: isToastClosing
|
||||
}
|
||||
}, [messageApi, modal])
|
||||
|
||||
onPop = () => {
|
||||
|
||||
@@ -23,6 +23,12 @@ interface ThemeProviderProps extends PropsWithChildren {
|
||||
defaultTheme?: ThemeMode
|
||||
}
|
||||
|
||||
const tailwindThemeChange = (theme: ThemeMode) => {
|
||||
const root = window.document.documentElement
|
||||
root.classList.remove('light', 'dark')
|
||||
root.classList.add(theme)
|
||||
}
|
||||
|
||||
export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
|
||||
// 用户设置的主题
|
||||
const { theme: settedTheme, setTheme: setSettedTheme } = useSettings()
|
||||
@@ -63,6 +69,7 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
|
||||
}, [actualTheme, initUserTheme, navbarPosition, setSettedTheme, settedTheme])
|
||||
|
||||
useEffect(() => {
|
||||
tailwindThemeChange(settedTheme)
|
||||
window.api.setTheme(settedTheme)
|
||||
}, [settedTheme])
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import './assets/styles/index.scss'
|
||||
import './assets/styles/index.css'
|
||||
import './assets/styles/tailwind.css'
|
||||
import '@ant-design/v5-patch-for-react-19'
|
||||
|
||||
import { createRoot } from 'react-dom/client'
|
||||
|
||||
11
src/renderer/src/env.d.ts
vendored
11
src/renderer/src/env.d.ts
vendored
@@ -1,5 +1,6 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
import { addToast, closeAll, closeToast, getToastQueue, isToastClosing } from '@heroui/toast'
|
||||
import type KeyvStorage from '@kangfenmao/keyv-storage'
|
||||
import { MessageInstance } from 'antd/es/message/interface'
|
||||
import { HookAPI } from 'antd/es/modal/useModal'
|
||||
@@ -16,10 +17,20 @@ interface ImportMeta {
|
||||
declare global {
|
||||
interface Window {
|
||||
root: HTMLElement
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
message: MessageInstance
|
||||
modal: HookAPI
|
||||
keyv: KeyvStorage
|
||||
store: any
|
||||
navigate: NavigateFunction
|
||||
toast: {
|
||||
getToastQueue: typeof getToastQueue
|
||||
addToast: typeof addToast
|
||||
closeToast: typeof closeToast
|
||||
closeAll: typeof closeAll
|
||||
isToastClosing: typeof isToastClosing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
src/renderer/src/hero.ts
Normal file
2
src/renderer/src/hero.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import { heroui } from '@heroui/react'
|
||||
export default heroui()
|
||||
@@ -37,7 +37,7 @@ export const useMinappPopup = () => {
|
||||
|
||||
const createLRUCache = useCallback(() => {
|
||||
return new LRUCache<string, MinAppType>({
|
||||
max: maxKeepAliveMinapps,
|
||||
max: maxKeepAliveMinapps ?? 10,
|
||||
disposeAfter: (_value, key) => {
|
||||
// Clean up WebView state when app is disposed from cache
|
||||
clearWebviewState(key)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Button } from '@heroui/button'
|
||||
import CodeViewer from '@renderer/components/CodeViewer'
|
||||
import { useTimer } from '@renderer/hooks/useTimer'
|
||||
import { getHttpMessageLabel, getProviderLabel } from '@renderer/i18n/label'
|
||||
@@ -33,7 +34,7 @@ import {
|
||||
} from '@renderer/types/error'
|
||||
import type { ErrorMessageBlock, Message } from '@renderer/types/newMessage'
|
||||
import { formatAiSdkError, formatError, safeToString } from '@renderer/utils/error'
|
||||
import { Alert as AntdAlert, Button, Modal } from 'antd'
|
||||
import { Alert as AntdAlert, Modal } from 'antd'
|
||||
import React, { useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { Link } from 'react-router-dom'
|
||||
@@ -143,13 +144,7 @@ const MessageErrorInfo: React.FC<{ block: ErrorMessageBlock; message: Message }>
|
||||
onClick={showErrorDetail}
|
||||
style={{ cursor: 'pointer' }}
|
||||
action={
|
||||
<Button
|
||||
size="small"
|
||||
type="text"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
showErrorDetail()
|
||||
}}>
|
||||
<Button size="sm" className="p-0" variant="light" onPress={showErrorDetail}>
|
||||
{t('common.detail')}
|
||||
</Button>
|
||||
}
|
||||
@@ -181,7 +176,7 @@ const ErrorDetailModal: React.FC<ErrorDetailModalProps> = ({ open, onClose, erro
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(errorText)
|
||||
window.message.success(t('message.copied'))
|
||||
window.toast.addToast({ title: t('message.copied') })
|
||||
}
|
||||
|
||||
const renderErrorDetails = (error?: SerializedError) => {
|
||||
@@ -203,10 +198,10 @@ const ErrorDetailModal: React.FC<ErrorDetailModalProps> = ({ open, onClose, erro
|
||||
open={open}
|
||||
onCancel={onClose}
|
||||
footer={[
|
||||
<Button key="copy" onClick={copyErrorDetails}>
|
||||
<Button key="copy" size="sm" variant="light" onPress={copyErrorDetails}>
|
||||
{t('common.copy')}
|
||||
</Button>,
|
||||
<Button key="close" onClick={onClose}>
|
||||
<Button key="close" size="sm" variant="light" onPress={onClose}>
|
||||
{t('common.close')}
|
||||
</Button>
|
||||
]}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export const lightbulbVariants = {
|
||||
import type { Variants } from 'motion/react'
|
||||
export const lightbulbVariants: Variants = {
|
||||
active: {
|
||||
opacity: [1, 0.2, 1],
|
||||
transition: {
|
||||
@@ -17,7 +18,7 @@ export const lightbulbVariants = {
|
||||
}
|
||||
}
|
||||
|
||||
export const lightbulbSoftVariants = {
|
||||
export const lightbulbSoftVariants: Variants = {
|
||||
active: {
|
||||
opacity: [1, 0.5, 1],
|
||||
transition: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '@renderer/assets/styles/index.scss'
|
||||
import '@renderer/assets/styles/index.css'
|
||||
import '@ant-design/v5-patch-for-react-19'
|
||||
|
||||
import KeyvStorage from '@kangfenmao/keyv-storage'
|
||||
|
||||
@@ -169,7 +169,7 @@ const WindowFooter: FC<FooterProps> = ({
|
||||
<Pause size={14} className="btn-icon loading-icon" style={{ position: 'absolute', left: 1, top: 1 }} />
|
||||
<LoadingOutlined
|
||||
style={{ fontSize: 16, position: 'absolute', left: 0, top: 0 }}
|
||||
className="btn-icon loading-icon"
|
||||
className="btn-icon loading-icon"
|
||||
spin
|
||||
/>
|
||||
</LoadingIconWrapper>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '@renderer/assets/styles/index.scss'
|
||||
import '@renderer/assets/styles/index.css'
|
||||
import '@ant-design/v5-patch-for-react-19'
|
||||
|
||||
import KeyvStorage from '@kangfenmao/keyv-storage'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '@renderer/assets/styles/selection-toolbar.scss'
|
||||
import '@renderer/assets/styles/selection-toolbar.css'
|
||||
|
||||
import { loggerService } from '@logger'
|
||||
import { AppLogo } from '@renderer/config/env'
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"useDefineForClassFields": true
|
||||
"useDefineForClassFields": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@renderer/*": ["src/renderer/src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"incremental": true,
|
||||
"moduleResolution": "bundler",
|
||||
"tsBuildInfoFile": ".tsbuildinfo/tsconfig.node.tsbuildinfo",
|
||||
"types": [
|
||||
"electron-vite/node",
|
||||
@@ -24,7 +25,8 @@
|
||||
"@main/*": ["src/main/*"],
|
||||
"@types": ["src/renderer/src/types/index.ts"],
|
||||
"@shared/*": ["packages/shared/*"],
|
||||
"@mcp-trace/*": ["packages/mcp-trace/*"]
|
||||
"@mcp-trace/*": ["packages/mcp-trace/*"],
|
||||
"@modelcontextprotocol/sdk/*": ["node_modules/@modelcontextprotocol/sdk/dist/esm/*"]
|
||||
},
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
|
||||
@@ -25,7 +25,7 @@ export default defineConfig({
|
||||
// 渲染进程单元测试配置
|
||||
{
|
||||
extends: true,
|
||||
plugins: rendererConfig.plugins,
|
||||
plugins: rendererConfig.plugins.filter((plugin: any) => plugin.name !== 'tailwindcss'),
|
||||
resolve: {
|
||||
alias: rendererConfig.resolve.alias
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user