Skip to content

UI 设计系统

LD-Notion 的 UI 由三个面板组成,共享统一的设计 token 体系,支持亮色/暗色主题切换。

设计 Token 架构

Token 作用域

所有 --ldb-ui-* token 定义在以下选择器上,确保面板内所有元素都能继承:

css
.ldb-panel,
.ldb-notion-panel,
.gclip-panel,
.ldb-notion-float-btn,
.ldb-mini-btn,
.gclip-float-btn,
.ldb-undo-toast {
    --ldb-ui-*: ...;
}

完整 Token 列表

Token亮色值暗色值用途
--ldb-ui-font-apple-system, BlinkMacSystemFont...(同)字体族
--ldb-ui-radius14px(同)大圆角
--ldb-ui-radius-sm10px(同)中圆角
--ldb-ui-radius-xs8px(同)小圆角
--ldb-ui-shadow0 18px 55px rgba(2,6,23,0.22)(同)大阴影
--ldb-ui-shadow-sm0 10px 26px rgba(2,6,23,0.16)(同)小阴影
--ldb-ui-text#0f172a#e5e7eb主文本
--ldb-ui-muted#64748b#9ca3af次要文本
--ldb-ui-borderrgba(15,23,42,0.14)rgba(148,163,184,0.22)边框
--ldb-ui-surfacergba(255,255,255,0.94)rgba(17,24,39,0.92)主背景
--ldb-ui-surface-2rgba(248,250,252,0.94)rgba(15,23,42,0.92)次背景
--ldb-ui-surface-3rgba(241,245,249,0.94)rgba(2,6,23,0.60)三级背景
--ldb-ui-accent#2563eb#60a5fa强调色
--ldb-ui-accent-2#7c3aed#c4b5fd次强调色
--ldb-ui-success#16a34a(同)成功色
--ldb-ui-warning#d97706(同)警告色
--ldb-ui-danger#dc2626(同)危险色
--ldb-ui-badge-teal#0f766e#2dd4bf徽章色(teal)
--ldb-ui-badge-blue#1d4ed8#93c5fd徽章色(blue)
--ldb-ui-focus-ringrgba(37,99,235,0.35)rgba(96,165,250,0.35)聚焦环
--ldb-ui-backdroprgba(2,6,23,0.35)rgba(0,0,0,0.45)遮罩
--ldb-ui-white#fff(同)纯白(按钮文本)

主题无关 Token

以下 token 主题无关,仅在亮色作用域定义一次,暗色自动继承:

Token用途
--ldb-ui-radius-2xs6px极小圆角
--ldb-ui-radius-md12px中大圆角
--ldb-ui-radius-pill999px胶囊圆角
--ldb-ui-spacing-3xs2px间距 3xs
--ldb-ui-spacing-xs4px间距 xs
--ldb-ui-spacing-sm6px间距 sm
--ldb-ui-spacing-md8px间距 md
--ldb-ui-spacing-lg10px间距 lg
--ldb-ui-spacing-xl12px间距 xl
--ldb-ui-spacing-2xl14px间距 2xl
--ldb-ui-spacing-3xl18px间距 3xl
--ldb-ui-font-size-xs11px字号 xs
--ldb-ui-font-size-sm12px字号 sm
--ldb-ui-font-size-md13px字号 md
--ldb-ui-font-size-lg14px字号 lg
--ldb-ui-font-size-xl20px字号 xl
--ldb-ui-font-size-2xl22px字号 2xl
--ldb-ui-z-index-panel2147483640面板层
--ldb-ui-z-index-panel-top2147483641面板顶层
--ldb-ui-z-index-overlay2147483646遮罩层
--ldb-ui-z-index-float2147483647浮动按钮层
--ldb-ui-warning-bright#f59e0b警告亮色(渐变起点)
--ldb-ui-success-bright#10b981成功亮色(渐变起点)
--ldb-ui-danger-bright#ef4444危险亮色(渐变起点)
--ldb-ui-disabled-opacity0.65禁用透明度
--ldb-ui-disabled-cursornot-allowed禁用光标

硬编码消除原则:UI 文件中的颜色、圆角、间距、字号、z-index 必须通过 var(--ldb-ui-*) 引用,禁止裸 #hexrgba()Npx、z-index 字面量。仅 token 定义行本身(:root / 面板选择器内)允许字面值。

主题切换

  • Auto 模式prefers-color-scheme 媒体查询自动适配系统主题
  • 手动切换DesignSystem.toggleTheme()data-ldb-theme="dark|light" on [data-ldb-root]
  • 持久化Storage.set(CONFIG.STORAGE_KEYS.THEME_PREFERENCE)
  • 降级:未设置 data-ldb-theme 时,@media (prefers-color-scheme: dark) 作为回退

交互状态规范

所有可交互元素必须定义完整的交互状态三件套:

状态实现方式示例
:hoverfilter: brightness(1.08) 或背景加深.ldb-btn:hover { filter: brightness(1.08); }
:activetransform: scale(0.97) 按下缩放.ldb-btn:active { transform: scale(0.97); }
:focus-visiblebox-shadow: 0 0 0 3px var(--ldb-ui-focus-ring).ldb-btn:focus-visible { ... }
:disabledopacity: var(--ldb-ui-disabled-opacity); cursor: var(--ldb-ui-disabled-cursor).ldb-btn:disabled { ... }

过渡

所有交互状态变化需添加 transition

css
transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;

可访问性规范

折叠区域

html
<div class="ldb-toggle-section" role="button" tabindex="0"
     aria-expanded="false" aria-controls="content-id">
    标题 <span class="ldb-arrow">▶</span>
</div>
<div class="ldb-toggle-content collapsed" id="content-id">
    内容
</div>
  • aria-expanded 必须与内容区折叠状态同步
  • 必须支持 EnterSpace 键盘触发

Tab 面板

html
<div class="ldb-tabs" role="tablist">
    <button class="ldb-tab active" role="tab" aria-selected="true" aria-controls="panel-1">Tab 1</button>
    <button class="ldb-tab" role="tab" aria-selected="false" aria-controls="panel-2">Tab 2</button>
</div>
<div class="ldb-tab-content active" role="tabpanel" id="panel-1">Content 1</div>
<div class="ldb-tab-content" role="tabpanel" id="panel-2">Content 2</div>

减少动画

prefers-reduced-motion: reduce 媒体查询禁用所有 transition 和 animation:

css
@media (prefers-reduced-motion: reduce) {
    .ldb-panel, .ldb-panel *, .ldb-btn, .ldb-spin, ... {
        transition: none !important;
        animation: none !important;
    }
}

响应式布局

三个固定宽度面板均设置了响应式回退:

css
.ldb-panel        { width: 380px; max-width: calc(100vw - 32px); }
.ldb-notion-panel { width: 380px; max-width: calc(100vw - 32px); }
.gclip-panel      { width: 320px; max-width: calc(100vw - 32px); }

CSS 工具类

类名作用
.ldb-text-successcolor: var(--ldb-ui-success)
.ldb-text-dangercolor: var(--ldb-ui-danger)
.ldb-text-infocolor: var(--ldb-ui-accent)
.ldb-text-mutedcolor: var(--ldb-ui-muted)
.ldb-spin0.8s 无限旋转动画
.ldb-status-text就地状态文本基类(font-weight: 500
.ldb-status-text--dangercolor: var(--ldb-ui-danger)
.ldb-status-text--successcolor: var(--ldb-ui-success)
.ldb-status-text--warningcolor: var(--ldb-ui-warning)
.ldb-status-text--accentcolor: var(--ldb-ui-accent)
.ldb-status-text--mutedcolor: var(--ldb-ui-muted)

就地状态文本 vs 全局状态栏.ldb-status-text 用于紧邻操作按钮的持久状态显示(如 Obsidian 测试连接结果、书签扩展状态),消息会一直保留直到下次操作。UI.showStatus(message, type) 用于全局状态栏(面板顶部 #ldb-status-container),消息 3-10 秒后自动清除。两者不可混用——把就地持久状态误用 showStatus 会导致消息被自动清除。

安全规范

  • 所有 innerHTML 中的动态内容必须经过 Utils.escapeHtml() 转义
  • 状态文本着色必须使用 .ldb-status-text--* 语义类,禁止内联 style="color: var(--ldb-ui-*)" 直接设置错误/成功文本颜色
  • 使用 textContent 赋值是更安全的选择(如 GenericUI.showStatus
  • 导出操作按钮必须有 disabled 防重入机制
  • 定时器清理:状态显示函数连续调用前必须 clearTimeout 旧定时器