SuperAPI AI 工具集

shadcn-layouts

前端与建站

查看项目

更新于 10-15 15:20

技能介绍

用途

shadcn-layouts 用于帮助生成能一次正确渲染的 shadcn/Tailwind 组件。多数 Agent 生成的 UI 之所以失败,并非语法错误,而是缺少关于 CSS 布局工作方式的心智模型,存在假设缺口。

适用场景:

  • 创建 shadcn/Tailwind 布局
  • 调试高度/滚动问题
  • 修复 flex/grid 问题
  • 搭建整页应用外壳

不适用场景:

  • 编写后端代码
  • 非 Tailwind CSS 项目
  • 设计工作(应先使用 frontend-design)

核心原则

CSS 布局由约束驱动。高度从显式的祖先元素向下传递,宽度由内容向上撑开。Agent 失败的原因在于只套用 class 而不理解约束链。

关键心智模型

模型 1:高度继承链

h-full 表示 height: 100%。100% 是谁的 100%?是父元素计算高度的 100%。

失效(链条不完整):

<html>                        <!-- 无高度 -->
  <body>                      <!-- 无高度 -->
    <div class="h-full">      <!-- 没有可继承的高度 = 0 -->

可用(链条完整):

<html class="h-full">         <!-- 视口的 100% -->
  <body class="h-full">       <!-- html 的 100% -->
    <div class="h-full">      <!-- body 的 100% = 生效 -->

规则:从元素向上追溯到 <html>。每个祖先都需要显式高度,或使用视口单位(h-screen)打破链条。

模型 2:Flex 溢出陷阱

Flex 子元素有隐式的 min-height: auto,阻止其收缩到内容尺寸以下。

// 失效(无法滚动)
<div className="flex flex-col h-screen">
  <main className="flex-1 overflow-y-auto">  {/* 无法收缩! */}

// 可用(正确滚动)
<div className="flex flex-col h-screen">
  <main className="flex-1 overflow-y-auto min-h-0">  {/* 可以收缩 */}

规则:需要滚动的 Flex 子元素需要 min-h-0。不应收缩的子元素需要 shrink-0。

模型 3:Grid 父子分离

Grid 定义在父元素上。子元素只是占据单元格。

// 失效
<div className="grid-cols-3">           {/* 缺少 'grid'! */}

// 可用
<div className="grid grid-cols-3">      {/* 'grid' 启用 grid-cols-* */}

规则:必须先声明 flex 或 grid,方向/模板类才能生效。

模型 4:滚动容器尺寸

滚动容器需要显式尺寸才能判断何时滚动。

// 失效(永不滚动)
<ScrollArea>  {/* 无高度约束 */}

// 可用(由 flex 约束)
<div className="flex flex-col h-screen">
  <ScrollArea className="flex-1 min-h-0">

诊断状态

  • SL1:高度链断裂。症状:元素塌陷,h-full 不生效。修复:追溯到 html,添加高度或使用 h-screen。
  • SL2:Flex 溢出受阻。症状:滚动不工作,内容溢出。修复:为需要滚动的 flex 子元素添加 min-h-0。
  • SL3:Grid 结构错误。症状:项目纵向堆叠而非分列。修复:确保父元素上有 grid grid-cols-*。
  • SL4:样式未应用。症状:组件无样式,颜色错误。修复:检查 Tailwind content 路径、globals.css 中的 CSS 变量。
  • SL5:组件依赖缺失。症状:“Module not found”,功能损坏。修复:npx shadcn add [component],安装 peer 依赖。

常见布局模式

整页应用外壳:

// layout.tsx
<html lang="en" className="h-full">
  <body className="h-full">{children}</body>
</html>

// page.tsx
<div className="flex h-full">
  <aside className="w-64 shrink-0 border-r overflow-y-auto">
    <nav>...</nav>
  </aside>
  <main className="flex-1 min-w-0 overflow-y-auto">
    {children}
  </main>
</div>

带页头的仪表盘:

<div className="flex flex-col h-screen">
  <header className="h-16 shrink-0 border-b">...</header>
  <div className="flex flex-1 min-h-0">
    <aside className="w-64 shrink-0 border-r overflow-y-auto">...</aside>
    <main className="flex-1 min-w-0 overflow-y-auto p-6">
      {children}
    </main>
  </div>
</div>

卡片网格:

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  {items.map(item => (
    <Card key={item.id}>
      <CardHeader><CardTitle>{item.title}</CardTitle></CardHeader>
      <CardContent>{item.content}</CardContent>
    </Card>
  ))}
</div>

反模式

  • 高度假设:使用 h-full 而未验证祖先链。修复:追溯到 html。使用 h-screen 打破链条。
  • 忽视溢出:在 flex 子元素上添加 overflow-y-auto 却没有 min-h-0。修复:flex 子元素需要 min-h-0 才能收缩。
  • 猜测导入:猜测 shadcn/ui 之类的导入路径。修复:检查 components.json 中的别名。通常是 @/components/ui/*。
  • 扁平复合组件:将复合组件扁平化(如 Dialog 缺少 DialogTrigger/DialogContent)。修复:保持所需的嵌套结构。

生成前检查清单

  • 导入别名已知(@/components/ui/*)
  • html 有 h-full
  • body 有 h-full 或 min-h-full
  • 滚动容器有显式高度
  • Flex 滚动子元素有 min-h-0
  • 固定元素有 shrink-0

相关技能

  • frontend-design:实现前的设计决策
  • react-pwa:React 应用的 PWA 功能