import { useEffect, useState } from 'react' import { Toaster } from '../src' import { Avatars } from './sections/Avatars' import { Breadcrumbs } from './sections/Breadcrumbs' import { Buttons } from './sections/Buttons' import { Cards } from './sections/Cards' import { Covers } from './sections/Covers' import { Checkboxes } from './sections/Checkboxes' import { Composition } from './sections/Composition' import { Drawers } from './sections/Drawers' import { Feedback } from './sections/Feedback' import { Icons } from './sections/Icons' import { Images } from './sections/Images' import { Inputs } from './sections/Inputs' import { Layouts } from './sections/Layouts' import { SiteChrome } from './sections/SiteChrome' import { Marks } from './sections/Marks' import { MenuSection } from './sections/MenuSection' import { Sortables } from './sections/Sortables' import { Modals } from './sections/Modals' import { Overview } from './sections/Overview' import { PageLayout } from './sections/PageLayout' import { Paginations } from './sections/Paginations' import { Progresses } from './sections/Progresses' import { RadioGroups } from './sections/RadioGroups' import { Results } from './sections/Results' import { ScrollTopSection } from './sections/ScrollTopSection' import { Segmenteds } from './sections/Segmenteds' import { Selects } from './sections/Selects' import { Skeletons } from './sections/Skeletons' import { Spinners } from './sections/Spinners' import { StepsSection } from './sections/StepsSection' import { Switches } from './sections/Switches' import { Tables } from './sections/Tables' import { TabsSection } from './sections/TabsSection' import { Toasts } from './sections/Toasts' import { Tooltips } from './sections/Tooltips' import { Typographies } from './sections/Typographies' /** * 组件展示站:左侧目录 + 右侧示例。 * * 页面只负责摆示例,所有样式都来自组件库本身; * 站点自己的排版样式收在 `app.css`,不污染组件。 */ const NAV = [ { title: '基础', items: [ { id: 'overview', label: '设计令牌' }, { id: 'typography', label: '排版 Typography' }, { id: 'icons', label: '图标 Icon' }, { id: 'buttons', label: '按钮 Button' }, ], }, { title: '展示', items: [ { id: 'cards', label: '卡片 Card' }, { id: 'cover', label: '封面卡 Cover' }, { id: 'image', label: '图片 Image' }, { id: 'marks', label: '标记 Tag / Badge' }, { id: 'avatars', label: '头像 Avatar' }, { id: 'table', label: '表格 Table' }, { id: 'result', label: '结果 Result' }, { id: 'progress', label: '进度 Progress' }, { id: 'steps', label: '步骤 Steps' }, ], }, { title: '表单', items: [ { id: 'inputs', label: '输入框 Input' }, { id: 'select', label: '下拉 Select' }, { id: 'switch', label: '开关 Switch' }, { id: 'checkbox', label: '复选框 Checkbox' }, { id: 'radio', label: '单选 Radio' }, { id: 'segmented', label: '分段 Segmented' }, ], }, { title: '导航', items: [ { id: 'breadcrumb', label: '面包屑 Breadcrumb' }, { id: 'tabs', label: '标签页 Tabs' }, { id: 'menu', label: '菜单 Menu' }, { id: 'sortable', label: '排序列表 SortableList' }, ], }, { title: '交互', items: [ { id: 'skeleton', label: '骨架屏 Skeleton' }, { id: 'spinner', label: '加载 Spinner' }, { id: 'feedback', label: '提示与空态' }, { id: 'toast', label: '轻提示 Toast' }, { id: 'modal', label: '弹窗 Modal' }, { id: 'drawer', label: '抽屉 Drawer' }, { id: 'pagination', label: '分页 Pagination' }, { id: 'scrolltop', label: '回到顶部' }, { id: 'tooltip', label: '工具提示 Tooltip' }, ], }, { title: '布局与组合', items: [ { id: 'layout', label: '页面骨架 Layout' }, { id: 'layouts', label: '网格与间距' }, { id: 'site-chrome', label: '站点外壳' }, { id: 'composition', label: '组合示例' }, ], }, ] as const const SECTION_IDS = NAV.flatMap((group) => group.items.map((item) => item.id)) /** 滚动监听:当前视口里最靠上的那一节高亮 */ function useActiveSection(): string { const [active, setActive] = useState(SECTION_IDS[0]) useEffect(() => { const observer = new IntersectionObserver( (entries) => { const visible = entries .filter((entry) => entry.isIntersecting) .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top) if (visible.length > 0) setActive(visible[0].target.id) }, { rootMargin: '-72px 0px -68% 0px' }, ) for (const id of SECTION_IDS) { const element = document.getElementById(id) if (element !== null) observer.observe(element) } return () => observer.disconnect() }, []) return active } export function App() { const active = useActiveSection() return (

DESIGN SYSTEM

Stash UI

独立于应用的设计系统项目:令牌、基础组件、以及一个可以直接翻的组件展示页。 组件只依赖令牌,不依赖任何页面数据,所以换页面、换应用都能直接拼。

42 个基础组件 零运行时依赖 CSS Modules + 设计令牌 对齐 Alright 参考站
) }