ProComponents, templates & AI tooling
HeroUI
27.7k

设计原则

指导 HeroUI v3 设计和开发的核心原则

HeroUI v3 遵循 10 项核心原则,注重清晰度、无障碍、可定制性以及开发者体验。

核心原则

1. 语义意图优于视觉风格

使用语义命名(primary、secondary、tertiary),而非视觉描述(solid、flat、bordered)。灵感来自 Uber 的 Base 设计系统,变体遵循清晰的层次结构:

语义意图层次结构
// ✅ Semantic variants communicate hierarchy
<Button variant="primary">Save</Button>
<Button variant="secondary">Edit</Button>
<Button variant="tertiary">Cancel</Button>
变体用途使用方式
Primary推进流程的主要操作每种场景 1 个
Secondary备选操作可使用多个
Tertiary次要操作(取消、跳过)谨慎使用
Danger破坏性操作需要时使用

2. 无障碍是基础

基于 React Aria Components 构建,符合 WCAG 2.1 AA 标准。内置自动 ARIA 属性、键盘导航与屏幕阅读器支持。

import { Tabs, TabList, Tab, TabPanel } from '@heroui/react';

<Tabs defaultSelectedKey="profile">
  <TabList aria-label="Settings">
    <Tab id="profile">Profile</Tab>
    <Tab id="security">Security</Tab>
  </TabList>
  <TabPanel id="profile">Content</TabPanel>
  <TabPanel id="security">Content</TabPanel>
</Tabs>

3. 组合优于配置

复合组件允许你按需重新组合、自定义或省略其中的各个部分。可以使用点号语法、命名导出,或两者混合使用。

// Compose parts to build exactly what you need
import {
  Accordion,
  AccordionItem,
  AccordionHeading,
  AccordionTrigger,
  AccordionIndicator,
  AccordionPanel,
  AccordionBody
} from '@heroui/react';

<Accordion>
  <AccordionItem id="1">
    <AccordionHeading>
      <AccordionTrigger>
        Question Text
        <AccordionIndicator />
      </AccordionTrigger>
    </AccordionHeading>
    <AccordionPanel>
      <AccordionBody>Answer content</AccordionBody>
    </AccordionPanel>
  </AccordionItem>
</Accordion>

4. 渐进式呈现

从简单开始,仅在需要时才增加复杂度。组件只需最少的 props 即可工作,并能随需求增长而扩展。

// Level 1: Minimal
<Button>Click me</Button>

// Level 2: Enhanced
<Button variant="primary" size="lg">
  <Icon icon="gravity-ui:check" className="mr-2" />
  Submit
</Button>

// Level 3: Advanced
<Button variant="primary" isDisabled={isLoading}>
  {isLoading ? <><Spinner size="sm" className="mr-2" /> Loading...</> : 'Submit'}
</Button>

5. 可预测的行为

所有组件遵循一致的模式:尺寸(smmdlg)、变体、className 支持以及 data 属性。相同的 API,相同的行为。

// All components follow the same patterns
<Button size="lg" variant="primary" className="custom" data-pressed="true" />
<Chip size="lg" variant="success" className="custom" />
<Avatar size="lg" className="custom" />

// Compound components support both named exports and dot notation
import { Alert, AlertIcon, CardHeader, AccordionTrigger } from '@heroui/react';

// Named exports
<Alert>
  <AlertIcon />
</Alert>

// Dot notation
<Alert>
  <Alert.Icon />
</Alert>

6. 类型安全优先

完整的 TypeScript 支持,包括 IntelliSense、自动补全与编译时错误检测。可为自定义组件扩展类型。

import type { ButtonProps } from '@heroui/react';

// Type-safe props and event handlers
<Button
  variant="primary"  // Autocomplete: primary | secondary | tertiary | danger | ghost
  size="md"          // Type checked: sm | md | lg
  onPress={(e) => {  // e is properly typed as PressEvent
    console.log(e.target);
  }}
/>

// Extend types for custom components
interface CustomButtonProps extends Omit<ButtonProps, 'variant'> {
  intent: 'save' | 'cancel' | 'delete';
}

7. 样式与逻辑分离

样式(@heroui/styles)与逻辑(@heroui/react)相互分离,可与任何框架或纯 HTML 一同使用。参见 Tailwind Play 示例

<!-- Use with plain HTML -->
<button class="button button--primary">Click me</button>

或与 React 一同使用:

// Apply styles to any component
import { buttonVariants } from '@heroui/styles';

<Link className={buttonVariants({ variant: "primary" })} href="/home">
  Home
</Link>

8. 卓越的开发者体验

清晰的 API、富含信息的错误提示、IntelliSense、对 AI 友好的 Markdown 文档,以及用于可视化测试的 Storybook。

9. 完全可定制

开箱即用的精美默认样式。使用 CSS 变量或 BEM 类即可彻底改变整体外观。每一个插槽都可定制。

/* Theme-wide changes with variables */
:root {
  --accent: oklch(0.7 0.25 260);
  --radius: 0.375rem;
  --spacing: 0.5rem;
}

/* Component-specific customization */
@layer components {
  .button {
    @apply uppercase tracking-wider;
  }
  .button--primary {
    @apply bg-gradient-to-r from-purple-500 to-pink-500;
  }
}

10. 开放且可扩展

可以包装、扩展或自定义组件以满足你的需求。可以使用变体函数、直接应用 BEM 类,或创建自定义的包装组件。

使用变体函数应用样式:

import { Link } from '@heroui/react';
import { linkVariants } from '@heroui/styles';
import NextLink from 'next/link';

// Use variant functions to style framework-specific components
const slots = linkVariants({ underline: "hover" });

<NextLink className={slots.base()} href="/about">
  About Page
  <Link.Icon className={slots.icon()} />
</NextLink>

直接应用 BEM 类:

import Link from 'next/link';

// Apply HeroUI's BEM classes directly to any element
<Link className="button button--primary" href="/dashboard">
  Dashboard
</Link>

创建自定义包装组件:

// Custom wrapper component
const CTAButton = ({
  intent = 'primary-cta',
  children,
  ref,
  ...props
}: CTAButtonProps) => {
  const variantMap = {
    'primary-cta': 'primary',
    'secondary-cta': 'secondary',
    'minimal': 'ghost'
  };

  return (
    <Button ref={ref} variant={variantMap[intent]} {...props}>
      {children}
    </Button>
  );
};

使用 Tailwind Variants 扩展:

import { Button } from '@heroui/react';
import { buttonVariants, tv } from '@heroui/styles';

// Extend button styles with custom variants
const myButtonVariants = tv({
  extend: buttonVariants,
  variants: {
    variant: {
      'primary-cta': 'bg-gradient-to-r from-blue-500 to-purple-600 text-white shadow-lg',
      'secondary-cta': 'border-2 border-blue-500 text-blue-500 hover:bg-blue-50',
    }
  }
});

// Use the custom variants
function CustomButton({ variant, className, ...props }) {
  return <Button className={myButtonVariants({ variant, className })} {...props} />;
}

// Usage
<CustomButton variant="primary-cta">Get Started</CustomButton>
<CustomButton variant="secondary-cta">Learn More</CustomButton>

与 HeroUI v2 的对比

维度HeroUI v2HeroUI v3
动画Framer MotionCSS + GPU 加速
组件模式带有大量 props 的单一组件复合组件
变体基于视觉(solid、bordered、flat)基于语义(primary、secondary、tertiary)
样式部分支持 Tailwind v4完整支持 Tailwind v4
无障碍优秀(基于 React Aria)优秀(基于 React Aria)
打包体积较大(整体打包)较小(支持 tree-shaking)
自定义难度中等(基于 props)简单(复合组件 + 原生 CSS)

本页目录