diff --git a/blog.config.js b/blog.config.js
index 24c2a049cf2..755b4d6b711 100644
--- a/blog.config.js
+++ b/blog.config.js
@@ -24,6 +24,8 @@ const BLOG = {
BEI_AN_LINK: process.env.NEXT_PUBLIC_BEI_AN_LINK || 'https://beian.miit.gov.cn/', // 备案查询链接,如果用了萌备等备案请在这里填写
BEI_AN_GONGAN: process.env.NEXT_PUBLIC_BEI_AN_GONGAN || '', // 公安备案号,例如 '浙公网安备3xxxxxxxx8号'
+ CODE_COLLAPSE_MIN_LINES: 30,//“长代码”阈值
+
// RSS订阅
ENABLE_RSS: process.env.NEXT_PUBLIC_ENABLE_RSS || true, // 是否开启RSS订阅功能
@@ -71,4 +73,4 @@ const BLOG = {
UUID_REDIRECT: process.env.UUID_REDIRECT || false
}
-module.exports = BLOG
\ No newline at end of file
+module.exports = BLOG
diff --git a/components/PrismMac.js b/components/PrismMac.js
index a0aff890233..2b8d422b33e 100644
--- a/components/PrismMac.js
+++ b/components/PrismMac.js
@@ -108,30 +108,50 @@ const renderCollapseCode = (codeCollapse, codeCollapseExpandDefault) => {
if (!codeCollapse) {
return
}
+
+ const COLLAPSE_MIN_LINES = Number(siteConfig('CODE_COLLAPSE_MIN_LINES', 18))
const codeBlocks = document.querySelectorAll('.code-toolbar')
+
for (const codeBlock of codeBlocks) {
- // 判断当前元素是否被包裹
if (codeBlock.closest('.collapse-wrapper')) {
- continue // 如果被包裹了,跳过当前循环
+ continue
}
const code = codeBlock.querySelector('code')
- const language = code.getAttribute('class').match(/language-(\w+)/)[1]
+ if (!code) {
+ continue
+ }
+
+ const className = code.getAttribute('class') || ''
+ const languageMatch = className.match(/language-([\w-]+)/)
+ const language = languageMatch ? languageMatch[1] : ''
+
+ const text = code.textContent || ''
+ const lineCount = text ? text.split('\n').length : 0
+
+ // 方案 C:仅当代码行数超过阈值时才启用折叠
+ if (lineCount && lineCount < COLLAPSE_MIN_LINES) {
+ continue
+ }
const collapseWrapper = document.createElement('div')
collapseWrapper.className = 'collapse-wrapper w-full py-2'
+
const panelWrapper = document.createElement('div')
- panelWrapper.className =
- 'border dark:border-gray-600 rounded-md hover:border-indigo-500 duration-200 transition-colors'
+ panelWrapper.className = 'collapse-panel-wrapper'
+
+ const header = document.createElement('button')
+ header.type = 'button'
+ header.className = 'collapse-header'
+
+ const label = language
+ ? `${language.toUpperCase()} · ${lineCount} lines`
+ : `${lineCount} lines`
- const header = document.createElement('div')
- header.className =
- 'flex justify-between items-center px-4 py-2 cursor-pointer select-none'
- header.innerHTML = `
${language}
`
+ header.innerHTML = `${label}`
const panel = document.createElement('div')
- panel.className =
- 'invisible h-0 transition-transform duration-200 border-t border-gray-300'
+ panel.className = 'collapse-panel'
panelWrapper.appendChild(header)
panelWrapper.appendChild(panel)
@@ -140,20 +160,18 @@ const renderCollapseCode = (codeCollapse, codeCollapseExpandDefault) => {
codeBlock.parentNode.insertBefore(collapseWrapper, codeBlock)
panel.appendChild(codeBlock)
- function collapseCode() {
- panel.classList.toggle('invisible')
- panel.classList.toggle('h-0')
- panel.classList.toggle('h-auto')
- header.querySelector('svg').classList.toggle('rotate-180')
- panelWrapper.classList.toggle('border-gray-300')
+ function setExpanded(expanded) {
+ panelWrapper.classList.toggle('is-expanded', expanded)
+ panel.classList.toggle('is-expanded', expanded)
+ header.setAttribute('aria-expanded', expanded ? 'true' : 'false')
}
- // 点击后折叠展开代码
- header.addEventListener('click', collapseCode)
- // 是否自动展开
- if (codeCollapseExpandDefault) {
- header.click()
- }
+ header.addEventListener('click', () => {
+ const expanded = panelWrapper.classList.contains('is-expanded')
+ setExpanded(!expanded)
+ })
+
+ setExpanded(Boolean(codeCollapseExpandDefault))
}
}
diff --git a/public/css/prism-mac-style.css b/public/css/prism-mac-style.css
index 2162f359bce..0b72a92166b 100644
--- a/public/css/prism-mac-style.css
+++ b/public/css/prism-mac-style.css
@@ -1,58 +1,184 @@
/**
* @author https://github.com/txs
- * 当配置文件 CODE_MAC_BAR 开启时,此样式会被动态引入,将开启代码组件左上角的mac图标
+ * 通用 Mac 风格代码块样式 (NotionNext Universal)
**/
+
+/* 1. Mac 窗口容器样式 */
.code-toolbar {
position: relative;
- padding-top: 0 !important;
- padding-bottom: 0 !important;
width: 100%;
- border-radius: 0.5rem;
- margin-bottom: 0.5rem;
+ margin: 1rem 0;
+ border-radius: 14px;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ background: rgba(27, 28, 32, 0.94); /* 浅色模式下默认暗底 */
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 18px 44px rgba(0, 0, 0, 0.18);
+ overflow: hidden;
+ transition: box-shadow 0.3s ease, transform 0.3s ease;
}
-.collapse-wrapper .code-toolbar {
- margin-bottom: 0;
+/* 暗色模式适配 */
+html.dark .code-toolbar {
+ border-color: rgba(255, 255, 255, 0.12);
+ background: rgba(27, 28, 32, 0.72);
+ -webkit-backdrop-filter: saturate(140%) blur(12px);
+ backdrop-filter: saturate(140%) blur(12px);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 18px 44px rgba(0, 0, 0, 0.45);
}
-.toolbar-item{
- white-space: nowrap;
+/* 2. Mac 三色点 */
+.pre-mac {
+ position: absolute;
+ left: 12px;
+ top: 11px;
+ z-index: 13;
+ display: flex;
+ gap: 7px;
}
-.toolbar-item > button {
- margin-top: -0.1rem;
+.pre-mac > span {
+ width: 10px;
+ height: 10px;
+ border-radius: 999px;
}
-pre[class*='language-'] {
- margin-top: 0rem !important;
- // margin-bottom: 0rem !important;
- padding-top: 1.5rem !important;
+.pre-mac > span:nth-child(1) { background: #ff5f57; }
+.pre-mac > span:nth-child(2) { background: #febc2e; }
+.pre-mac > span:nth-child(3) { background: #28c840; }
+/* 3. Toolbar 工具栏 (复制按钮、语言标签) */
+.code-toolbar > .toolbar {
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 34px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 0 10px;
+ z-index: 12;
}
-.pre-mac {
- position: absolute;
- left: 0.9rem;
- top: 0.5rem;
- z-index: 10;
+.code-toolbar .toolbar-item > button {
+ font-size: 12px !important;
+ line-height: 1 !important;
+ padding: 6px 8px !important;
+ border-radius: 999px !important;
+ border: 1px solid rgba(255, 255, 255, 0.15) !important;
+ background: rgba(255, 255, 255, 0.1) !important;
+ color: rgba(255, 255, 255, 0.82) !important;
+ cursor: pointer;
+ transition: all 0.2s ease;
}
-.pre-mac > span {
- width: 10px;
- height: 10px;
- border-radius: 50%;
- margin-right: 5px;
- float: left;
+.code-toolbar .toolbar-item > button:hover {
+ background: rgba(255, 255, 255, 0.2) !important;
+ color: #fff !important;
+}
+
+/* 4. 代码正文排版 */
+pre.notion-code {
+ font-size: 0.92em !important;
+ line-height: 1.6 !important;
+ margin: 0 !important;
+ padding: 46px 1.1rem 1rem !important;
+ border-radius: 0 !important;
+ border: none !important;
+ background: transparent !important;
+ color: rgba(255, 255, 255, 0.9) !important;
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+/* 5. 智能折叠 S1 极简 UI */
+.collapse-wrapper {
+ margin: 1rem 0;
}
-.pre-mac > span:nth-child(1) {
- background: red;
+.collapse-panel-wrapper {
+ border-radius: 14px;
+ border: 1px solid rgba(0, 0, 0, 0.08);
+ background: rgba(255, 255, 255, 0.55);
+ -webkit-backdrop-filter: saturate(160%) blur(10px);
+ backdrop-filter: saturate(160%) blur(10px);
+ overflow: hidden;
+ transition: all 0.3s ease;
}
-.pre-mac > span:nth-child(2) {
- background: sandybrown;
+html.dark .collapse-panel-wrapper {
+ border-color: rgba(255, 255, 255, 0.12);
+ background: rgba(27, 28, 32, 0.6);
}
-.pre-mac > span:nth-child(3) {
- background: limegreen;
+.collapse-header {
+ width: 100%;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 12px;
+ cursor: pointer;
+ user-select: none;
+ border: none;
+ background: transparent;
+ color: rgba(60, 60, 67, 0.6);
+}
+
+html.dark .collapse-header {
+ color: rgba(235, 235, 245, 0.6);
+}
+
+.collapse-label {
+ font-size: 13px;
+ letter-spacing: 0.02em;
+}
+
+.collapse-chevron {
+ width: 18px;
+ height: 18px;
+ transition: transform 0.3s ease;
+ opacity: 0.8;
+}
+
+.collapse-panel-wrapper.is-expanded .collapse-chevron {
+ transform: rotate(180deg);
+}
+
+.collapse-panel {
+ max-height: 0;
+ overflow: hidden;
+ border-top: 1px solid rgba(0, 0, 0, 0.06);
+ transition: max-height 0.32s ease;
+}
+
+html.dark .collapse-panel {
+ border-top-color: rgba(255, 255, 255, 0.08);
+}
+
+.collapse-panel.is-expanded {
+ max-height: 3000px;
}
+
+/* 6. Prism 代码高亮补丁 (暗底优化) */
+.code-toolbar .token.comment,
+.code-toolbar .token.prolog,
+.code-toolbar .token.doctype,
+.code-toolbar .token.cdata { color: rgba(235, 235, 245, 0.46); }
+.code-toolbar .token.punctuation { color: rgba(235, 235, 245, 0.6); }
+.code-toolbar .token.property,
+.code-toolbar .token.tag,
+.code-toolbar .token.boolean,
+.code-toolbar .token.number,
+.code-toolbar .token.constant,
+.code-toolbar .token.symbol,
+.code-toolbar .token.deleted { color: #7ee787; }
+.code-toolbar .token.selector,
+.code-toolbar .token.attr-name,
+.code-toolbar .token.string,
+.code-toolbar .token.char,
+.code-toolbar .token.builtin,
+.code-toolbar .token.inserted { color: #a5d6ff; }
+.code-toolbar .token.atrule,
+.code-toolbar .token.attr-value,
+.code-toolbar .token.keyword { color: #ff7ab2; }
+.code-toolbar .token.function,
+.code-toolbar .token.class-name { color: #ffd479; }