基础 UI 组件库
常用的基础界面元素,包括按钮、输入框、卡片等。
组件配额 5
状态 ACTIVE
01. 玻璃拟态卡片 (Glass Card)
具有磨砂玻璃质感的卡片容器,支持背景模糊和半透明边框。
Glass Card
Interactive Component
玻璃拟态 (Glassmorphism) 是一种现代 UI 设计趋势,通过模拟磨砂玻璃的物理特性(如模糊、反射和透明度)来创造深度的层次感。
Blur 12px
Opacity 3%
---
interface Props {
class?: string;
title?: string;
icon?: string;
subtitle?: string;
}
const {
class: className,
title = "Glass Card",
icon = "💎",
subtitle = "Interactive Component"
} = Astro.props;
---
<div class={`glass-card-preview ${className}`}>
{ (Astro.slots.has('header') || title || icon) && (
<div class="card-header">
<slot name="header">
<div class="header-content">
{icon && <span class="header-icon">{icon}</span>}
{title && <h3 class="header-title">{title}</h3>}
</div>
</slot>
</div>
)}
{ (Astro.slots.has('subheader') || subtitle) && (
<div class="card-subheader">
<slot name="subheader">
<span class="subheader-text">{subtitle}</span>
</slot>
</div>
)}
<div class="card-content">
<slot>
<div class="card-demo-content">
<p>玻璃拟态 (Glassmorphism) 是一种现代 UI 设计趋势,通过模拟磨砂玻璃的物理特性(如模糊、反射和透明度)来创造深度的层次感。</p>
<div class="demo-stats">
<div class="stat">
<span class="label">Blur</span>
<span class="value">12px</span>
</div>
<div class="stat">
<span class="label">Opacity</span>
<span class="value">3%</span>
</div>
</div>
</div>
</slot>
</div>
{ (Astro.slots.has('footer') || true) && (
<div class="card-footer">
<slot name="footer">
<div class="footer-demo-content">
<span class="footer-tag">Design System</span>
<span class="footer-version">v1.0.4</span>
</div>
</slot>
</div>
)}
</div>
<style>
.glass-card-preview {
background: var(--glass-bg);
backdrop-filter: var(--glass-blur);
-webkit-backdrop-filter: var(--glass-blur);
border: var(--glass-border);
border-radius: 16px;
padding: 1.25rem;
box-shadow: var(--glass-shadow);
width: 100%;
max-width: 320px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
flex-direction: column;
gap: 0.75rem;
position: relative;
overflow: hidden;
}
.glass-card-preview::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
transition: 0.5s;
}
.glass-card-preview:hover::before {
left: 100%;
}
.glass-card-preview:hover {
transform: translateY(-5px);
border-color: var(--color-primary-start);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.08);
}
/* Header Styles */
.card-header {
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
padding-bottom: 0.75rem;
}
.header-content {
display: flex;
align-items: center;
gap: 0.6rem;
}
.header-icon {
font-size: 1.2rem;
filter: drop-shadow(0 0 8px rgba(var(--color-primary-rgb), 0.3));
}
.header-title {
margin: 0;
font-size: 1.05rem;
font-weight: 600;
color: var(--color-text-title);
letter-spacing: 0.5px;
}
/* Subheader Styles */
.card-subheader {
font-size: 0.8rem;
color: var(--color-neutral);
margin-top: -0.25rem;
font-family: var(--font-mono);
}
/* Content Styles */
.card-content {
flex: 1;
color: var(--color-text-body);
font-size: 0.9rem;
line-height: 1.6;
margin: 0.5rem 0;
}
/* Footer Styles */
.card-footer {
border-top: 1px solid rgba(0, 0, 0, 0.05);
padding-top: 0.75rem;
margin-top: 0.25rem;
font-size: 0.85rem;
color: var(--color-neutral);
}
.footer-demo-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.footer-tag {
color: var(--color-primary-start);
font-weight: 500;
}
.footer-version {
opacity: 0.6;
font-family: var(--font-mono);
font-size: 0.75rem;
}
.card-demo-content {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.demo-stats {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
padding: 0.75rem;
background: rgba(var(--color-primary-rgb), 0.03);
border-radius: 8px;
border: 1px solid rgba(var(--color-primary-rgb), 0.05);
}
.stat {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.stat .label {
font-size: 0.65rem;
text-transform: uppercase;
letter-spacing: 1px;
color: var(--color-neutral);
}
.stat .value {
font-size: 0.9rem;
font-weight: 600;
color: var(--color-primary-start);
font-family: var(--font-mono);
}
</style> 组件特性
- 结构化布局:内置 Header、Subheader、Content 和 Footer 区域。
- 磨砂玻璃效果:利用
backdrop-filter: blur()实现。 - 插槽灵活性:支持通过
slot="header"、slot="subheader"和slot="footer"自定义各个区域的内容。 - 悬停交互:平滑的上移和阴影加深效果。
视觉细节
建议在具有彩色或复杂背景的容器中使用,以突出玻璃的透明感。可以使用内置的 title 和 icon 属性快速构建卡片头部。
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| title | 卡片顶部标题 | `string` | - |
| icon | 标题旁的图标 (支持 Emoji 或图标组件) | `string` | - |
| subtitle | 标题下方的副标题 | `string` | - |
| class | 自定义样式类名 | `string` | '' |
02. 新拟态按钮 (Neumorphic Button)
具有独特光影反馈的按钮,支持多种类型、尺寸和形状,内置扫光动效。
---
interface Props {
text?: string;
type?: 'primary' | 'secondary' | 'outline' | 'ghost';
size?: 'sm' | 'md' | 'lg';
shape?: 'square' | 'rounded' | 'pill';
class?: string;
}
const {
text = "PUSH_ME",
type = 'primary',
size = 'md',
shape = 'rounded',
class: className
} = Astro.props;
---
<button class:list={[
'neo-button-preview',
`type-${type}`,
`size-${size}`,
`shape-${shape}`,
className
]}>
<span class="btn-text">{text}</span>
<div class="btn-glitch"></div>
</button>
<style>
.neo-button-preview {
position: relative;
border: none;
font-family: var(--font-mono);
font-weight: 700;
letter-spacing: 1px;
cursor: pointer;
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: inline-flex;
align-items: center;
justify-content: center;
white-space: nowrap;
outline: none;
}
/* Sizes */
.size-sm {
padding: 0.4rem 1rem;
font-size: 0.75rem;
}
.size-md {
padding: 0.7rem 1.75rem;
font-size: 0.9rem;
}
.size-lg {
padding: 1rem 2.5rem;
font-size: 1.1rem;
}
/* Shapes */
.shape-square { border-radius: 0; }
.shape-rounded { border-radius: 6px; }
.shape-pill { border-radius: 9999px; }
/* Types */
.type-primary {
background: var(--color-primary-start);
color: white;
box-shadow: 0 4px 15px rgba(var(--color-primary-rgb), 0.3);
}
.type-primary:hover {
background: var(--color-primary-end);
box-shadow: 0 6px 20px rgba(var(--color-primary-rgb), 0.4);
transform: translateY(-2px);
}
.type-secondary {
background: rgba(var(--color-primary-rgb), 0.1);
color: var(--color-primary-start);
border: 1px solid rgba(var(--color-primary-rgb), 0.2);
}
.type-secondary:hover {
background: rgba(var(--color-primary-rgb), 0.15);
border-color: var(--color-primary-start);
transform: translateY(-2px);
}
.type-outline {
background: transparent;
color: var(--color-primary-start);
border: 2px solid var(--color-primary-start);
}
.type-outline:hover {
background: var(--color-primary-start);
color: white;
transform: translateY(-2px);
}
.type-ghost {
background: transparent;
color: var(--color-text-body);
}
.type-ghost:hover {
background: rgba(0, 0, 0, 0.05);
color: var(--color-primary-start);
}
.neo-button-preview:active {
transform: translateY(0) scale(0.98);
}
.btn-glitch {
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
transition: 0.5s;
}
.neo-button-preview:hover .btn-glitch {
left: 100%;
}
.btn-text {
position: relative;
z-index: 1;
}
</style> 组件特性
- 多样化风格:预设四种核心类型,满足不同场景的权重需求。
- 扫光动效:悬停时触发平滑的扫光效果,增强科技感。
- 交互反馈:内置活跃态(Active)缩放效果,模拟真实的按压触感。
- 灵活布局:支持三种常用尺寸和三种边框形状,高度可配置。
使用建议
推荐在深色或具有玻璃质感的容器中使用,以获得最佳的视觉表现。primary 类型自带发光阴影,适合作为页面的 Call-to-Action 按钮。
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| text | 按钮显示的文字内容 | `string` | 'PUSH_ME' |
| type | 按钮风格类型 | `'primary' | 'secondary' | 'outline' | 'ghost'` | 'primary' |
| size | 按钮尺寸大小 | `'sm' | 'md' | 'lg'` | 'md' |
| shape | 按钮圆角形状 | `'square' | 'rounded' | 'pill'` | 'rounded' |
| class | 自定义样式类名 | `string` | '' |
03. 赛博开关 (Cyber Toggle)
具有未来科技感的二进制切换开关,支持多种尺寸和禁用状态。
SYSTEM_CORE
---
interface Props {
label?: string;
checked?: boolean;
size?: 'sm' | 'md' | 'lg';
disabled?: boolean;
class?: string;
}
const {
label = "SYSTEM_CORE",
checked = true,
size = 'md',
disabled = false,
class: className
} = Astro.props;
---
<div class:list={["cyber-toggle-container", size, { disabled }, className]}>
{label && <span class="toggle-label">{label}</span>}
<label class="toggle-wrapper">
<input type="checkbox" checked={checked} disabled={disabled} />
<div class="toggle-track">
<div class="toggle-thumb">
<div class="thumb-core"></div>
</div>
<div class="track-glitch"></div>
</div>
</label>
</div>
<style>
.cyber-toggle-container {
display: inline-flex;
align-items: center;
gap: 1rem;
font-family: var(--font-mono);
user-select: none;
}
.toggle-label {
font-size: 0.85rem;
font-weight: 700;
color: var(--color-text-title);
letter-spacing: 1px;
text-transform: uppercase;
}
.toggle-wrapper {
position: relative;
cursor: pointer;
display: block;
}
.toggle-wrapper input {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
/* Track Styling */
.toggle-track {
position: relative;
width: 54px;
height: 28px;
background: rgba(0, 0, 0, 0.4);
border: 1px solid rgba(var(--color-primary-rgb), 0.3);
border-radius: 4px;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
overflow: hidden;
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5);
}
.toggle-wrapper input:checked + .toggle-track {
background: rgba(var(--color-primary-rgb), 0.1);
border-color: var(--color-primary-start);
box-shadow: 0 0 15px rgba(var(--color-primary-rgb), 0.2);
}
/* Thumb Styling */
.toggle-thumb {
position: absolute;
top: 3px;
left: 3px;
width: 20px;
height: 20px;
background: #2a2a2a;
border: 1px solid #444;
border-radius: 2px;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
}
.thumb-core {
width: 8px;
height: 8px;
background: #666;
border-radius: 1px;
transition: all 0.3s ease;
}
.toggle-wrapper input:checked + .toggle-track .toggle-thumb {
transform: translateX(26px);
background: var(--color-primary-start);
border-color: #fff;
box-shadow: 0 0 10px var(--color-primary-start);
}
.toggle-wrapper input:checked + .toggle-track .thumb-core {
background: #fff;
box-shadow: 0 0 5px #fff;
}
/* Glitch Effect on Track */
.track-glitch {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(var(--color-primary-rgb), 0.2), transparent);
transform: translateX(-100%);
transition: transform 0.6s ease;
}
.toggle-wrapper:hover .track-glitch {
transform: translateX(100%);
}
/* Size Variations */
.sm .toggle-track { width: 44px; height: 22px; }
.sm .toggle-thumb { width: 14px; height: 14px; top: 3px; left: 3px; }
.sm .toggle-wrapper input:checked + .toggle-track .toggle-thumb { transform: translateX(22px); }
.sm .toggle-label { font-size: 0.7rem; }
.lg .toggle-track { width: 64px; height: 34px; }
.lg .toggle-thumb { width: 26px; height: 26px; top: 3px; left: 3px; }
.lg .toggle-wrapper input:checked + .toggle-track .toggle-thumb { transform: translateX(30px); }
.lg .toggle-label { font-size: 1rem; }
/* Disabled State */
.disabled {
opacity: 0.5;
pointer-events: none;
}
.disabled .toggle-track {
border-color: #333;
background: #111;
}
</style> 组件特性
- 工业设计:采用硬朗的方角设计,区别于传统的圆润风格,更具工业和科幻感。
- 动态反馈:开关切换时带有平滑的位移动效,并伴有核心发光效果。
- 扫描特效:鼠标悬停时,轨道内部会触发一层流光扫描特效。
- 多尺寸适配:预设了三种尺寸,能够灵活适配从侧边栏到主面板的不同布局需求。
使用建议
推荐在深色模式或具有科技感的 UI 界面中使用。作为核心功能的开关时,建议搭配 lg 尺寸以增强视觉引导。
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label | 开关旁的标签文字 | `string` | 'SYSTEM_CORE' |
| checked | 开关的初始状态 | `boolean` | true |
| size | 开关的尺寸 | `'sm' | 'md' | 'lg'` | 'md' |
| disabled | 是否禁用开关 | `boolean` | false |
| class | 自定义样式类名 | `string` | '' |
04. 赛博徽章 (Cyber Badge)
极小尺寸的高信息密度标签,支持多种语义颜色和交互特效。
STABLE
---
interface Props {
text?: string;
type?: 'primary' | 'success' | 'warning' | 'error' | 'neutral';
variant?: 'solid' | 'outline' | 'glitch';
size?: 'xs' | 'sm' | 'md';
class?: string;
}
const {
text = "STABLE",
type = 'primary',
variant = 'outline',
size = 'sm',
class: className
} = Astro.props;
---
<span class:list={["cyber-badge", type, variant, size, className]}>
<span class="badge-content">{text}</span>
{variant === 'glitch' && <span class="badge-glitch" aria-hidden="true">{text}</span>}
</span>
<style>
.cyber-badge {
display: inline-flex;
align-items: center;
padding: 2px 10px;
font-family: var(--font-mono);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
border-radius: 2px;
position: relative;
white-space: nowrap;
user-select: none;
font-size: 0.7rem;
}
/* Sizes */
.xs { padding: 1px 6px; font-size: 0.6rem; }
.sm { padding: 2px 10px; font-size: 0.7rem; }
.md { padding: 4px 14px; font-size: 0.8rem; }
/* Types (Colors) */
.primary {
--badge-color: var(--color-primary-start);
--badge-rgb: var(--color-primary-rgb);
}
.success {
--badge-color: #10b981;
--badge-rgb: 16, 185, 129;
}
.warning {
--badge-color: #f59e0b;
--badge-rgb: 245, 158, 11;
}
.error {
--badge-color: #ef4444;
--badge-rgb: 239, 68, 68;
}
.neutral {
--badge-color: var(--color-neutral);
--badge-rgb: 156, 163, 175;
}
/* Variants */
.solid {
background: var(--badge-color);
color: #000;
box-shadow: 0 0 10px rgba(var(--badge-rgb), 0.3);
}
.outline {
background: rgba(var(--badge-rgb), 0.1);
border: 1px solid var(--badge-color);
color: var(--badge-color);
box-shadow: inset 0 0 5px rgba(var(--badge-rgb), 0.2);
}
.glitch {
background: transparent;
border: 1px solid var(--badge-color);
color: var(--badge-color);
overflow: hidden;
}
.badge-glitch {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--badge-color);
color: #000;
display: flex;
align-items: center;
justify-content: center;
transform: translateX(-101%);
transition: transform 0.3s cubic-bezier(0.7, 0, 0.3, 1);
}
.cyber-badge:hover .badge-glitch {
transform: translateX(0);
}
.badge-content {
position: relative;
z-index: 1;
}
</style> 组件特性
- 工业语义化:内置五种核心语义颜色,能够清晰传递系统状态信息。
- Glitch 特效:
glitch变体在悬停时会触发一个覆盖式的色块滑动效果,增加交互的动感。 - 紧凑布局:专为高密度信息流设计,即使在
xs尺寸下也能保持极佳的可读性。 - 等宽字体:强制使用等宽字体,确保在不同文字内容下徽章的视觉重心保持一致。
使用建议
推荐用于文章标签、代码版本号标记或监控面板的状态显示。在列表项中使用时,建议保持 size="sm" 以维持视觉平衡。
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| text | 徽章显示的文字内容 | `string` | 'STABLE' |
| type | 语义化颜色类型 | `'primary' | 'success' | 'warning' | 'error' | 'neutral'` | 'primary' |
| variant | 视觉风格:实心、轮廓或带有 Glitch 悬停特效 | `'solid' | 'outline' | 'glitch'` | 'outline' |
| size | 徽章尺寸 | `'xs' | 'sm' | 'md'` | 'sm' |
| class | 自定义样式类名 | `string` | '' |
05. 全息头像 (Hologram Avatar)
具有全息投影质感的头像组件,支持扫描线、外发光环和故障特效。
---
interface Props {
src?: string;
size?: 'sm' | 'md' | 'lg';
glowColor?: string;
scanline?: boolean;
class?: string;
}
const {
src = "https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?auto=format&fit=crop&w=200&h=200",
size = 'md',
glowColor = "var(--color-primary-start)",
scanline = true,
class: className
} = Astro.props;
const sizeMap = {
sm: '60px',
md: '100px',
lg: '160px'
};
---
<div class:list={["hologram-avatar-container", size, className]} style={{ '--glow-color': glowColor, '--avatar-size': sizeMap[size] }}>
<div class="avatar-wrapper">
<div class="avatar-image" style={{ backgroundImage: `url(${src})` }}></div>
<div class="hologram-layer"></div>
{scanline && <div class="scanline-layer"></div>}
<div class="glitch-layer"></div>
</div>
<div class="avatar-ring"></div>
<div class="avatar-glow"></div>
</div>
<style>
.hologram-avatar-container {
position: relative;
width: var(--avatar-size);
height: var(--avatar-size);
display: flex;
align-items: center;
justify-content: center;
}
.avatar-wrapper {
position: relative;
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
z-index: 2;
border: 2px solid rgba(255, 255, 255, 0.1);
}
.avatar-image {
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
filter: saturate(0.5) contrast(1.2) brightness(1.1) sepia(0.2);
}
/* Hologram Effect */
.hologram-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
rgba(var(--color-primary-rgb), 0.2) 0%,
transparent 100%
);
mix-blend-mode: screen;
pointer-events: none;
}
.scanline-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
to bottom,
transparent,
rgba(var(--color-primary-rgb), 0.1) 50%,
transparent
);
background-size: 100% 4px;
animation: scanMove 3s linear infinite;
pointer-events: none;
}
@keyframes scanMove {
from { background-position: 0 0; }
to { background-position: 0 100%; }
}
/* Ring and Glow */
.avatar-ring {
position: absolute;
top: -5px;
left: -5px;
right: -5px;
bottom: -5px;
border: 1px solid var(--glow-color);
border-radius: 50%;
opacity: 0.5;
animation: rotate 10s linear infinite;
z-index: 1;
}
.avatar-ring::after {
content: '';
position: absolute;
top: -2px;
left: 50%;
width: 4px;
height: 4px;
background: #fff;
border-radius: 50%;
box-shadow: 0 0 10px #fff;
}
.avatar-glow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--glow-color);
filter: blur(25px);
opacity: 0.2;
border-radius: 50%;
z-index: 0;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Glitch on Hover */
.hologram-avatar-container:hover .avatar-image {
animation: glitch 0.2s infinite;
}
@keyframes glitch {
0% { transform: translate(0); }
20% { transform: translate(-2px, 1px); filter: hue-rotate(90deg); }
40% { transform: translate(2px, -1px); filter: hue-rotate(180deg); }
60% { transform: translate(-1px, 2px); filter: hue-rotate(270deg); }
80% { transform: translate(1px, -2px); }
100% { transform: translate(0); }
}
</style> 组件特性
- 全息质感:通过色彩偏移(Sepia)、对比度调整和半透明遮罩,模拟全息影像的半透明和不稳定感。
- 动态光环:头像外围环绕一个持续旋转的能量环,带有一个亮白色的“轨道卫星”点。
- 故障交互:鼠标悬停时,头像会触发强烈的 Glitch 故障动效,包括位置抖动和色相旋转。
- 扫描动画:内置垂直移动的扫描线,增强了老式科幻界面的临场感。
使用建议
推荐在侧边栏用户信息、评论系统头像或 AI 对话框中使用。由于全息效果会降低图片的色彩饱和度,建议使用对比度较高的原始图片以获得最佳效果。
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| src | 图片源地址 | `string` | - |
| size | 头像尺寸 | `'sm' | 'md' | 'lg'` | 'md' |
| glowColor | 外发光颜色 | `string` | 'var(--color-primary-start)' |
| scanline | 是否显示扫描线 | `boolean` | true |
| class | 自定义样式类名 | `string` | '' |