feat(banner): 首页常驻滚动通知与管理配置及类型样式支持

This commit is contained in:
✨await
2026-09-17 23:17:09 +08:00
parent 772c551989
commit a3b6761ba9
34 changed files with 3345 additions and 10 deletions

View File

@@ -10669,3 +10669,218 @@ html[data-magicui-theme-vt="active"] .admin-shell * {
grid-template-columns: 100px minmax(0, 1fr);
}
}
/* 常驻通知标题:富文本编辑区与明暗两态预览。
* 预览固定明暗两套底色,编辑时不受当前主题影响,便于同时校验两种主题下的可读性。 */
.admin-banner-title-editor {
border: 1px solid var(--admin-card-border);
border-radius: 8px;
background: var(--admin-layer-1);
padding: 8px 12px;
transition: border-color 160ms ease;
}
.admin-banner-title-editor:focus-within {
border-color: color-mix(in srgb, var(--foreground) 30%, var(--admin-card-border));
}
.admin-banner-title-editor .ProseMirror {
min-height: 26px;
outline: none;
line-height: 1.6;
white-space: pre-wrap;
word-break: break-word;
}
.admin-banner-title-editor .ProseMirror p {
margin: 0;
}
.admin-banner-title-editor .ProseMirror p.is-editor-empty:first-child::before {
float: left;
height: 0;
color: color-mix(in srgb, var(--foreground) 34%, transparent);
content: attr(data-placeholder);
pointer-events: none;
}
/* 预览容器强制指定四种通知类型的明 / 暗底色,不依赖页面当前主题。 */
.admin-banner-title-preview-light {
--notice-banner-surface-notice: var(--palette-banner-notice-500);
--notice-banner-surface-activity: var(--palette-banner-activity-500);
--notice-banner-surface-update: var(--palette-banner-update-500);
--notice-banner-surface-warning: var(--palette-banner-warning-500);
}
.admin-banner-title-preview-dark {
--notice-banner-surface-notice: var(--palette-banner-notice-700);
--notice-banner-surface-activity: var(--palette-banner-activity-700);
--notice-banner-surface-update: var(--palette-banner-update-700);
--notice-banner-surface-warning: var(--palette-banner-warning-700);
}
/* 常驻通知标题图标选择器 */
.admin-banner-icon-picker {
border: 1px solid var(--admin-card-border);
border-radius: 8px;
background: var(--admin-layer-1);
}
.admin-banner-icon-picker-search {
position: sticky;
top: 0;
z-index: 1;
padding: 8px;
border-bottom: 1px solid var(--admin-divider);
background: var(--admin-layer-1);
}
.admin-banner-icon-picker-body {
max-height: 208px;
overflow-y: auto;
padding: 2px 8px 8px;
}
.admin-banner-icon-picker-group-label {
display: block;
padding: 8px 2px 4px;
color: color-mix(in srgb, var(--foreground) 45%, transparent);
font-size: var(--fs-micro);
}
.admin-banner-icon-picker-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
gap: 4px;
}
.admin-banner-icon-picker-option {
display: grid;
height: 34px;
place-items: center;
border: 1px solid transparent;
border-radius: 6px;
background: transparent;
color: color-mix(in srgb, var(--foreground) 62%, transparent);
cursor: pointer;
transition:
background-color 160ms ease,
border-color 160ms ease,
color 160ms ease;
}
.admin-banner-icon-picker-option:hover {
background: color-mix(in srgb, var(--foreground) 7%, transparent);
color: var(--foreground);
}
/* emoji 素材项:emoji 是文本字符,用原生字号渲染(彩色字形不受 color 影响) */
.admin-banner-icon-picker-option-emoji {
font-size: 16px;
line-height: 1;
}
.admin-banner-icon-picker-option.is-active {
border-color: color-mix(in srgb, var(--foreground) 22%, transparent);
background: var(--control-selected-bg);
color: var(--foreground);
}
.admin-banner-icon-picker-option:focus-visible {
outline: 1px solid color-mix(in srgb, var(--ring) 62%, transparent);
outline-offset: 1px;
}
.admin-banner-icon-picker-empty {
padding: 14px 2px;
color: color-mix(in srgb, var(--foreground) 45%, transparent);
font-size: var(--fs-label);
text-align: center;
}
/* 通知类型选择:卡片直接铺出该类型的真实底色,比文字描述颜色更直观。 */
.admin-banner-type-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 8px;
}
.admin-banner-type-card {
display: flex;
flex-direction: column;
gap: 2px;
border: 1px solid var(--admin-card-border);
border-radius: 8px;
background: var(--admin-layer-1);
padding: 8px 10px 10px;
text-align: left;
cursor: pointer;
transition:
border-color 160ms ease,
background-color 160ms ease;
}
.admin-banner-type-card:hover {
background: color-mix(in srgb, var(--foreground) 4%, var(--admin-layer-1));
}
.admin-banner-type-card.is-active {
border-color: color-mix(in srgb, var(--foreground) 26%, transparent);
background: var(--control-selected-bg);
}
.admin-banner-type-card:focus-visible {
outline: 1px solid color-mix(in srgb, var(--ring) 62%, transparent);
outline-offset: 1px;
}
.admin-banner-type-card-name {
display: flex;
align-items: center;
gap: 6px;
color: var(--foreground);
font-size: var(--fs-label);
font-weight: 600;
}
.admin-banner-type-card-check {
margin-left: auto;
color: var(--foreground);
}
.admin-banner-type-card-hint {
color: color-mix(in srgb, var(--foreground) 45%, transparent);
font-size: var(--fs-micro);
line-height: 1.5;
}
/* 类型卡片上的真实底色条;颜色由卡片的 data-banner-type 选中对应 token。 */
.admin-banner-type-card-preview {
display: flex;
align-items: center;
gap: 6px;
margin-top: 8px;
border-radius: 4px;
padding: 4px 8px;
color: #ffffff;
font-size: var(--fs-micro);
line-height: 1.4;
}
.admin-banner-type-card[data-banner-type="notice"] .admin-banner-type-card-preview {
background: var(--notice-banner-surface-notice);
}
.admin-banner-type-card[data-banner-type="activity"] .admin-banner-type-card-preview {
background: var(--notice-banner-surface-activity);
}
.admin-banner-type-card[data-banner-type="update"] .admin-banner-type-card-preview {
background: var(--notice-banner-surface-update);
}
.admin-banner-type-card[data-banner-type="warning"] .admin-banner-type-card-preview {
background: var(--notice-banner-surface-warning);
}

View File

@@ -53,6 +53,17 @@
--palette-status-loading: #2563eb;
--palette-status-warning: #d97706;
/* 顶部常驻通知条主题色:按「通知类型」区分底色(类型定义见 lib/announcements/banner-notice)
两档取值都由白字对比度反推——light 档 ≥ 4.5:1(WCAG AA 正文),dark 档约 8.5:1(压暗避免刺眼)*/
--palette-banner-notice-500: #5c67e2; /* 公告 · 白字 4.67:1 */
--palette-banner-notice-700: #3f4590; /* 白字 8.52:1 */
--palette-banner-activity-500: #da2470; /* 活动 · 白字 4.70:1 */
--palette-banner-activity-700: #7b3552; /* 白字 8.49:1 */
--palette-banner-update-500: #138279; /* 更新 · 白字 4.67:1 */
--palette-banner-update-700: #235450; /* 白字 8.55:1 */
--palette-banner-warning-500: #b55b0c; /* 警告 · 白字 4.70:1 */
--palette-banner-warning-700: #6a4424; /* 白字 8.52:1 */
/* --- 2. 间距(4px 栅格 + 半距)--- */
--space-0: 0px;
--space-half: 2px;
@@ -529,7 +540,10 @@
--color-cn-stroke: var(--cn-stroke);
--color-cn-fill: var(--cn-fill);
/* 字号(可用 text-fs-body / text-fs-caption 等)*/
/* 字号
注意:Tailwind v4 的字号命名空间是 --text-*,--font-size-* 不被识别,
因此下面这组声明不会生成 text-micro / text-caption 之类的工具类。
组件请沿用既有惯例直接引用 Primitive:text-[var(--fs-label)]、text-[var(--fs-caption)] 等。 */
--font-size-micro: var(--fs-micro);
--font-size-tiny: var(--fs-tiny);
--font-size-label: var(--fs-label);
@@ -595,6 +609,15 @@
--accent-soft: var(--workspace-accent-soft);
--muted: var(--color-neutral-100);
/* 顶部常驻通知条(Layer 3 组件引用;文字恒为白)
四个 --notice-banner-surface-<type> 与通知类型一一对应,dark 覆盖见 .dark 语义覆盖区;
--notice-banner-surface 是「公告」的别名,供不区分类型的引用使用。*/
--notice-banner-surface-notice: var(--palette-banner-notice-500);
--notice-banner-surface-activity: var(--palette-banner-activity-500);
--notice-banner-surface-update: var(--palette-banner-update-500);
--notice-banner-surface-warning: var(--palette-banner-warning-500);
--notice-banner-surface: var(--notice-banner-surface-notice);
/* Canvas Theme 语义(从 CSS 变量反序列化到 TS 主题对象,对应 #96 决策3)*/
--cn-text: var(--color-neutral-950);
--cn-muted: var(--color-neutral-500);
@@ -754,6 +777,13 @@
--surface-active: rgba(255, 255, 255, 0.12);
--muted: var(--color-neutral-900);
/* 顶部常驻通知条:暗色下四种类型统一压暗,白字对比度约 8.5:1 */
--notice-banner-surface-notice: var(--palette-banner-notice-700);
--notice-banner-surface-activity: var(--palette-banner-activity-700);
--notice-banner-surface-update: var(--palette-banner-update-700);
--notice-banner-surface-warning: var(--palette-banner-warning-700);
--notice-banner-surface: var(--notice-banner-surface-notice);
/* composio 文字层级(dark 直取)*/
--workspace-text-body: #a8a8a8; /* body(tokens.json text/body)*/
--workspace-text-muted: #888888; /* muted(tokens.json text/muted)*/

View File

@@ -456,15 +456,15 @@
transform: translateX(2px);
}
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link { min-height: 62px; flex-direction: column; justify-content: center; gap: 4px; padding: 8px 2px; border-radius: 14px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-main { flex-direction: column; gap: 4px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link.is-collapsed .app-workspace-nav-title { display: block !important; max-width: 100%; color: var(--user-ink-muted); font-size: 10px; line-height: 1.1; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link { min-height: 52px; flex-direction: column; justify-content: center; gap: 2px; padding: 6px 2px; border-radius: 12px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-main { flex-direction: column; gap: 2px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link.is-collapsed .app-workspace-nav-title { display: block !important; max-width: 100%; color: var(--user-ink-muted); font-size: 10px; line-height: 1.1; margin-top: -1px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link.is-active .app-workspace-nav-title { color: var(--user-ink); }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link.is-collapsed .app-workspace-nav-meta { display: none !important; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-group { gap: 10px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link { width: 54px !important; padding: 6px 0 !important; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-group { gap: 6px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link { width: 54px !important; padding: 4px 0 !important; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-main { width: 100%; align-items: center; justify-content: center; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-icon { width: 30px; height: 30px; flex-basis: 30px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-icon { width: 24px; height: 24px; flex-basis: 24px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link .app-workspace-nav-icon svg,
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-nav-link .app-workspace-nav-main > svg { width: 18px !important; height: 18px !important; flex: 0 0 18px; }
.app-user-workspace .app-workspace-sidebar-nav.is-collapsed .app-workspace-sidebar-profile-row { width: 100%; justify-content: center; }