页头与页身之间的一条真实占位带(搜索 / 筛选 / 操作),宽度跟随容器, contained 时与侧栏 + 内容同宽,height=screen 下不参与内容区滚动。 用它替代「搜索框 fixed + contentOffset 让位」的写法。 - Layout.tsx / Layout.module.css:新增 toolbar prop 与样式 - 展示页 #layout 增加「页头下的工具条」示例 - COMPONENTS.md 补契约、与 contentOffset 的分工说明、changelog
650 lines
13 KiB
CSS
650 lines
13 KiB
CSS
:root {
|
||
font-family: var(--su-font-sans);
|
||
font-size: var(--su-font-size-md);
|
||
line-height: var(--su-line-height-md);
|
||
color: var(--su-text-main);
|
||
background-color: var(--su-bg-page);
|
||
color-scheme: light;
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
}
|
||
|
||
* {
|
||
box-sizing: border-box;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
a {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
}
|
||
|
||
button {
|
||
font: inherit;
|
||
color: inherit;
|
||
border: none;
|
||
background: none;
|
||
}
|
||
|
||
:focus-visible {
|
||
outline: 2px solid var(--su-color-primary);
|
||
outline-offset: 2px;
|
||
}
|
||
|
||
code {
|
||
font-family: var(--su-font-mono);
|
||
font-size: 0.92em;
|
||
}
|
||
|
||
/* ---------- 文档骨架 ---------- */
|
||
|
||
.doc-shell {
|
||
display: grid;
|
||
grid-template-columns: 248px minmax(0, 1fr);
|
||
max-width: 1240px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.doc-sidebar {
|
||
position: sticky;
|
||
top: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-5);
|
||
height: 100vh;
|
||
padding: var(--su-space-8) var(--su-space-5);
|
||
border-right: 1px solid var(--su-border);
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.doc-brand {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--su-space-3);
|
||
}
|
||
|
||
.doc-brand-mark {
|
||
display: grid;
|
||
place-items: center;
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: var(--su-radius-sm);
|
||
background-image: linear-gradient(135deg, #4d6bff, var(--su-color-primary));
|
||
color: var(--su-white);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.doc-brand strong {
|
||
display: block;
|
||
font-size: var(--su-font-size-lg);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.doc-brand em {
|
||
font-size: var(--su-font-size-sm);
|
||
font-style: normal;
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.doc-brand-desc {
|
||
font-size: var(--su-font-size-sm);
|
||
line-height: 1.7;
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.doc-nav {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-5);
|
||
}
|
||
|
||
.doc-nav h2 {
|
||
margin-bottom: var(--su-space-2);
|
||
font-size: var(--su-font-size-sm);
|
||
font-weight: 600;
|
||
letter-spacing: 0.08em;
|
||
color: var(--su-text-muted);
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.doc-nav ul {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
list-style: none;
|
||
}
|
||
|
||
.doc-nav a {
|
||
display: block;
|
||
padding: 6px var(--su-space-3);
|
||
border-radius: var(--su-radius-sm);
|
||
font-size: var(--su-font-size-md);
|
||
color: var(--su-text-sub);
|
||
transition:
|
||
background-color var(--su-duration-fast) var(--su-ease-out),
|
||
color var(--su-duration-fast) var(--su-ease-out);
|
||
}
|
||
|
||
.doc-nav a:hover {
|
||
background-color: var(--su-gray-2);
|
||
color: var(--su-text-main);
|
||
}
|
||
|
||
.doc-nav a.is-active {
|
||
background-color: var(--su-color-primary-soft);
|
||
color: var(--su-color-primary);
|
||
font-weight: var(--su-font-weight-bold);
|
||
}
|
||
|
||
.doc-sidebar-footer {
|
||
margin-top: auto;
|
||
padding-top: var(--su-space-4);
|
||
border-top: 1px solid var(--su-border);
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.doc-demo-link {
|
||
display: inline-block;
|
||
margin-top: var(--su-space-2);
|
||
padding: 4px 10px;
|
||
border: 1px solid var(--su-border-strong);
|
||
border-radius: var(--su-radius-pill);
|
||
color: var(--su-color-primary);
|
||
transition:
|
||
background-color var(--su-duration-fast) var(--su-ease-in-out),
|
||
border-color var(--su-duration-fast) var(--su-ease-in-out);
|
||
}
|
||
|
||
.doc-demo-link:hover {
|
||
border-color: var(--su-color-primary);
|
||
background-color: var(--su-color-primary-soft);
|
||
}
|
||
|
||
/* ---------- 正文 ---------- */
|
||
|
||
.doc-main {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-6);
|
||
padding: var(--su-space-10) var(--su-space-10) 160px;
|
||
}
|
||
|
||
.doc-hero {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-3);
|
||
padding-bottom: var(--su-space-6);
|
||
border-bottom: 1px solid var(--su-border);
|
||
}
|
||
|
||
.doc-eyebrow {
|
||
font-family: var(--su-font-mono);
|
||
font-size: var(--su-font-size-sm);
|
||
letter-spacing: 0.16em;
|
||
color: var(--su-color-primary);
|
||
}
|
||
|
||
.doc-hero h1 {
|
||
font-size: 40px;
|
||
line-height: 1.2;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.doc-hero-desc {
|
||
max-width: 68ch;
|
||
font-size: var(--su-font-size-md);
|
||
line-height: 1.8;
|
||
color: var(--su-text-sub);
|
||
}
|
||
|
||
.doc-hero-meta {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--su-space-2);
|
||
margin-top: var(--su-space-2);
|
||
}
|
||
|
||
.doc-hero-meta span {
|
||
padding: 3px 10px;
|
||
border: 1px solid var(--su-border);
|
||
border-radius: var(--su-radius-pill);
|
||
background-color: var(--su-bg-card);
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.doc-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-4);
|
||
scroll-margin-top: 24px;
|
||
}
|
||
|
||
.doc-section-title {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: var(--su-space-3);
|
||
}
|
||
|
||
.doc-section-title h2 {
|
||
font-size: var(--su-font-size-xl);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.doc-section-title code {
|
||
color: var(--su-text-muted);
|
||
font-size: var(--su-font-size-sm);
|
||
}
|
||
|
||
.doc-section-desc {
|
||
max-width: 76ch;
|
||
color: var(--su-text-sub);
|
||
line-height: 1.8;
|
||
}
|
||
|
||
/* ---------- 示例块 ---------- */
|
||
|
||
.demo {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-3);
|
||
padding-top: var(--su-space-5);
|
||
border-top: 1px dashed var(--su-border);
|
||
}
|
||
|
||
.demo:first-of-type {
|
||
padding-top: 0;
|
||
border-top: none;
|
||
}
|
||
|
||
.demo-title {
|
||
font-size: var(--su-font-size-lg);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.demo-desc {
|
||
font-size: var(--su-font-size-md);
|
||
color: var(--su-text-muted);
|
||
line-height: 1.7;
|
||
}
|
||
|
||
.demo-preview {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--su-space-3);
|
||
padding: var(--su-space-6);
|
||
border: 1px solid var(--su-border);
|
||
border-radius: var(--su-radius-md);
|
||
background-color: var(--su-bg-card);
|
||
}
|
||
|
||
/*
|
||
* 纵向示例用 grid 而不是 flex column:
|
||
* flex 纵向容器会把子项(尤其是带 aspect-ratio 封面的 Grid)按内容高度压缩,
|
||
* grid 的行高严格按内容算,卡片不会被裁掉一截。
|
||
*/
|
||
.demo-preview--column {
|
||
display: grid;
|
||
grid-template-columns: minmax(0, 1fr);
|
||
align-content: start;
|
||
}
|
||
|
||
.demo-preview--muted {
|
||
background-color: var(--su-gray-1);
|
||
}
|
||
|
||
.demo-code {
|
||
padding: var(--su-space-4);
|
||
border-radius: var(--su-radius-md);
|
||
background-color: #1d2129;
|
||
color: #e5e6eb;
|
||
font-family: var(--su-font-mono);
|
||
font-size: var(--su-font-size-sm);
|
||
line-height: 1.7;
|
||
overflow-x: auto;
|
||
white-space: pre;
|
||
}
|
||
|
||
/* ---------- 令牌表 ---------- */
|
||
|
||
.token-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||
gap: var(--su-space-3);
|
||
}
|
||
|
||
.token-swatch {
|
||
overflow: hidden;
|
||
border: 1px solid var(--su-border);
|
||
border-radius: var(--su-radius-md);
|
||
background-color: var(--su-bg-card);
|
||
}
|
||
|
||
.token-swatch-color {
|
||
height: 56px;
|
||
}
|
||
|
||
.token-swatch-meta {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
padding: var(--su-space-2) var(--su-space-3);
|
||
}
|
||
|
||
.token-swatch-name {
|
||
font-family: var(--su-font-mono);
|
||
font-size: var(--su-font-size-sm);
|
||
}
|
||
|
||
.token-swatch-value {
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.token-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
border: 1px solid var(--su-border);
|
||
border-radius: var(--su-radius-md);
|
||
background-color: var(--su-bg-card);
|
||
}
|
||
|
||
.token-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--su-space-4);
|
||
padding: var(--su-space-3) var(--su-space-4);
|
||
border-top: 1px solid var(--su-border);
|
||
}
|
||
|
||
.token-row:first-child {
|
||
border-top: none;
|
||
}
|
||
|
||
.token-row-label {
|
||
width: 160px;
|
||
flex-shrink: 0;
|
||
font-family: var(--su-font-mono);
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.token-row-demo {
|
||
display: flex;
|
||
flex: 1;
|
||
align-items: center;
|
||
gap: var(--su-space-3);
|
||
min-width: 0;
|
||
}
|
||
|
||
.token-row-note {
|
||
flex-shrink: 0;
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.token-bar {
|
||
height: 8px;
|
||
border-radius: var(--su-radius-pill);
|
||
background-color: var(--su-color-primary);
|
||
}
|
||
|
||
.type-sample-xl {
|
||
font-size: var(--su-font-size-xl);
|
||
line-height: var(--su-line-height-xl);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.type-sample-lg {
|
||
font-size: var(--su-font-size-lg);
|
||
line-height: var(--su-line-height-lg);
|
||
}
|
||
|
||
.type-sample-md {
|
||
font-size: var(--su-font-size-md);
|
||
line-height: var(--su-line-height-md);
|
||
}
|
||
|
||
.type-sample-sm {
|
||
font-size: var(--su-font-size-sm);
|
||
line-height: var(--su-line-height-sm);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
.radius-sample {
|
||
width: 72px;
|
||
height: 48px;
|
||
border: 1px solid var(--su-border-strong);
|
||
background-color: var(--su-gray-2);
|
||
}
|
||
|
||
.shadow-sample {
|
||
display: grid;
|
||
place-items: center;
|
||
width: 120px;
|
||
height: 56px;
|
||
border-radius: var(--su-radius-md);
|
||
background-color: var(--su-bg-card);
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
/* ---------- Props 表 ---------- */
|
||
|
||
.props-table-wrap {
|
||
width: 100%;
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.props-table {
|
||
width: 100%;
|
||
min-width: 520px;
|
||
border-collapse: collapse;
|
||
border: 1px solid var(--su-border);
|
||
border-radius: var(--su-radius-md);
|
||
background-color: var(--su-bg-card);
|
||
font-size: var(--su-font-size-sm);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.props-table th,
|
||
.props-table td {
|
||
padding: var(--su-space-2) var(--su-space-4);
|
||
border-top: 1px solid var(--su-border);
|
||
text-align: left;
|
||
vertical-align: top;
|
||
}
|
||
|
||
.props-table thead th {
|
||
border-top: none;
|
||
background-color: var(--su-gray-1);
|
||
font-weight: 600;
|
||
color: var(--su-text-sub);
|
||
}
|
||
|
||
.props-table code {
|
||
color: var(--su-color-primary);
|
||
}
|
||
|
||
.props-table .props-type {
|
||
color: var(--su-text-sub);
|
||
}
|
||
|
||
/* ---------- 图标墙 ---------- */
|
||
|
||
.icon-count {
|
||
align-self: center;
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-muted);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.icon-wall {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
|
||
gap: var(--su-space-2);
|
||
width: 100%;
|
||
}
|
||
|
||
.icon-wall--scroll {
|
||
max-height: 460px;
|
||
padding-right: var(--su-space-1);
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.icon-cell {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: var(--su-space-2);
|
||
padding: var(--su-space-3);
|
||
border: 1px solid var(--su-border);
|
||
border-radius: var(--su-radius-sm);
|
||
background-color: var(--su-bg-card);
|
||
font-size: var(--su-font-size-lg);
|
||
color: var(--su-text-sub);
|
||
cursor: pointer;
|
||
transition:
|
||
color var(--su-duration-fast) var(--su-ease-in-out),
|
||
border-color var(--su-duration-fast) var(--su-ease-in-out),
|
||
background-color var(--su-duration-fast) var(--su-ease-in-out);
|
||
}
|
||
|
||
.icon-cell:hover {
|
||
border-color: var(--su-color-primary);
|
||
background-color: var(--su-color-primary-soft);
|
||
color: var(--su-color-primary);
|
||
}
|
||
|
||
.icon-cell code {
|
||
max-width: 100%;
|
||
overflow: hidden;
|
||
font-size: var(--su-font-size-xs);
|
||
color: var(--su-text-muted);
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.icon-empty {
|
||
font-size: var(--su-font-size-md);
|
||
color: var(--su-text-muted);
|
||
}
|
||
|
||
/* ---------- Layout 示例的迷你页面 ---------- */
|
||
|
||
.layout-frame {
|
||
height: 440px;
|
||
overflow: auto;
|
||
border: 1px solid var(--su-border);
|
||
border-radius: var(--su-radius-md);
|
||
background-color: var(--su-bg-page);
|
||
}
|
||
|
||
.layout-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--su-space-4);
|
||
height: 56px;
|
||
padding: 0 var(--su-space-5);
|
||
border-bottom: 1px solid var(--su-border);
|
||
}
|
||
|
||
.layout-brand {
|
||
font-size: var(--su-font-size-lg);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
|
||
.layout-bar-actions {
|
||
display: flex;
|
||
gap: var(--su-space-1);
|
||
}
|
||
|
||
/* 工具条:页头与页身之间的一条搜索带(toolbar 插槽) */
|
||
.layout-toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: var(--su-space-3) var(--su-space-5);
|
||
border-bottom: 1px solid var(--su-border);
|
||
}
|
||
|
||
.layout-toolbar > * {
|
||
width: min(360px, 100%);
|
||
}
|
||
|
||
.layout-side {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
padding: var(--su-space-4);
|
||
}
|
||
|
||
.layout-nav-item {
|
||
padding: 6px var(--su-space-3);
|
||
border-radius: var(--su-radius-sm);
|
||
font-size: var(--su-font-size-sm);
|
||
color: var(--su-text-sub);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* 窄屏演示:页头只留当前项,模拟真实导航收起 */
|
||
@media (max-width: 640px) {
|
||
.layout-bar {
|
||
padding: 0 var(--su-space-3);
|
||
}
|
||
|
||
.layout-bar-actions .layout-nav-item:nth-child(n + 2) {
|
||
display: none;
|
||
}
|
||
}
|
||
|
||
.layout-nav-item.is-active {
|
||
background-color: var(--su-color-primary-soft);
|
||
color: var(--su-color-primary);
|
||
}
|
||
|
||
.layout-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-4);
|
||
}
|
||
|
||
.layout-aside {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--su-space-2);
|
||
padding: var(--su-space-5) var(--su-space-4);
|
||
}
|
||
|
||
.layout-aside-item {
|
||
padding: 2px var(--su-space-2);
|
||
border-radius: var(--su-radius-xs);
|
||
font-size: var(--su-font-size-xs);
|
||
color: var(--su-text-sub);
|
||
}
|
||
|
||
.layout-aside-item.is-active {
|
||
background-color: var(--su-bg-light);
|
||
color: var(--su-text-main);
|
||
}
|
||
|
||
@media (max-width: 980px) {
|
||
.doc-shell {
|
||
grid-template-columns: minmax(0, 1fr);
|
||
}
|
||
|
||
.doc-sidebar {
|
||
position: static;
|
||
height: auto;
|
||
border-right: none;
|
||
border-bottom: 1px solid var(--su-border);
|
||
}
|
||
|
||
.doc-main {
|
||
padding: var(--su-space-6) var(--su-space-5) 120px;
|
||
}
|
||
}
|