Files
stash-ui/site/app.css
T
CNWei 93bb5cbb28 feat(ui): Layout 新增 toolbar 插槽
页头与页身之间的一条真实占位带(搜索 / 筛选 / 操作),宽度跟随容器,
contained 时与侧栏 + 内容同宽,height=screen 下不参与内容区滚动。
用它替代「搜索框 fixed + contentOffset 让位」的写法。

- Layout.tsx / Layout.module.css:新增 toolbar prop 与样式
- 展示页 #layout 增加「页头下的工具条」示例
- COMPONENTS.md 补契约、与 contentOffset 的分工说明、changelog
2026-11-01 15:15:14 +08:00

650 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
: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;
}
}