# Animation **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/animation **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(handbook)/animation.mdx > Add smooth animations and transitions to HeroUI v3 components HeroUI components support multiple animation approaches: built-in CSS transitions, custom CSS animations, and JavaScript libraries like Framer Motion. ## Built-in Animations HeroUI components use data attributes to expose their state for animation: ```css /* Popover entrance/exit */ .popover[data-entering] { @apply animate-in zoom-in-90 fade-in-0 duration-200; } .popover[data-exiting] { @apply animate-out zoom-out-95 fade-out duration-150; } /* Button press effect */ .button:active, .button[data-pressed="true"] { transform: scale(0.97); } /* Accordion expansion */ .accordion__panel[aria-hidden="false"] { @apply h-[var(--panel-height)] opacity-100; } ``` **State attributes for styling:** * `[data-hovered="true"]` - Hover state * `[data-pressed="true"]` - Active/pressed state * `[data-focus-visible="true"]` - Keyboard focus * `[data-disabled="true"]` - Disabled state * `[data-entering]` / `[data-exiting]` - Transition states * `[aria-expanded="true"]` - Expanded state ## CSS Animations **Using Tailwind utilities:** ```tsx // Pulse on hover // Fade in entrance Welcome message // Staggered list
Item 1 Item 2
``` **Custom transitions:** ```css /* Slower accordion */ .accordion__panel { @apply transition-all duration-500; } /* Bouncy button */ .button:active { animation: bounce 0.3s; } @keyframes bounce { 50% { transform: scale(0.95); } } ``` ## Framer Motion HeroUI components work seamlessly with Framer Motion for advanced animations. **Basic usage:** ```tsx import { motion } from 'framer-motion'; import { Button } from '@heroui/react'; const MotionButton = motion(Button); Animated Button ``` **Entrance animations:** ```tsx Welcome! ``` **Layout animations:** ```tsx import { AnimatePresence, motion } from 'framer-motion'; function Tabs({ items, selected }) { return (
{items.map((item, i) => ( ))}
); } ``` ## Render Props Apply dynamic animations based on component state: ```tsx ``` ## Accessibility **Respecting motion preferences:** HeroUI automatically respects user motion preferences using Tailwind's `motion-reduce:` utility. All built-in transitions and animations are disabled when users enable "reduce motion" in their system settings. HeroUI extends Tailwind's `motion-reduce:` variant to support both the native `prefers-reduced-motion` media query and the `data-reduce-motion` attribute. ```css /* HeroUI pattern - uses Tailwind's motion-reduce: */ .button { @apply transition-colors motion-reduce:transition-none; } /* Expands to support both approaches: */ @media (prefers-reduced-motion: reduce) { .button { transition: none; } } [data-reduce-motion="true"] .button { transition: none; } ``` With Framer Motion: ```tsx import { useReducedMotion } from 'framer-motion'; function AnimatedCard() { const shouldReduceMotion = useReducedMotion(); return ( Content ); } ``` **Disabling animations globally:** Add `data-reduce-motion="true"` to the `` or `` tag: ```html ``` HeroUI automatically detects the user's `prefers-reduced-motion: reduce` setting and disables animations accordingly. ## Performance Tips **Use GPU-accelerated properties:** Prefer `transform` and `opacity` for smooth animations: ```css /* Good - GPU accelerated */ .slide-in { transform: translateX(-100%); transition: transform 0.3s; } /* Avoid - Triggers layout */ .slide-in { left: -100%; transition: left 0.3s; } ``` **Will-change optimization:** Use `will-change` to optimize animations, but remove it when not animating: ```css .button { will-change: transform; } .button:not(:hover) { will-change: auto; } ``` ## Next Steps * Learn about [Styling](/docs/handbook/styling) approaches * Explore [Component](/docs/react/components) examples * View [Theming](/docs/handbook/theming) documentation
# Colors **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/colors **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(handbook)/colors.mdx > Color palette and theming system for HeroUI v3 import {ColorSectionSideBySide, ColorSectionStacked, ColorSectionFormField, ColorSectionPrimitive} from "@/components/color-section"; HeroUI's color system is built around semantic intent, not visual abundance. Instead of exposing large raw palettes, the system defines a small, meaningful set of color roles that cover the majority of interface needs. Most colors in the system are derived automatically from a limited number of base values. This allows HeroUI to maintain consistent contrast, hierarchy, and theming behavior while keeping the system easy to reason about and modify. Colors should communicate purpose and state first. Visual variation comes from scale, emphasis, and context. **Want to create your own theme?** Try the [Theme Builder](/themes) to visually customize colors, radius, fonts, and more — then export the CSS to use in your project. ## Accent The accent color represents the primary brand or product identity. It is used to draw attention to key actions, highlights, and moments of emphasis. Accent should be used intentionally and sparingly. Overuse reduces its impact and can harm visual hierarchy. In most cases, components derive multiple accent-related values (hover, subtle backgrounds, focus states) automatically from the base accent color. ## Default (neutrals) Default colors form the neutral backbone of the system. They are used for most non-emphasized UI elements. ## Success Success colors communicate positive outcomes, confirmations, and completed states. They are typically used in feedback components, status indicators, and validation states. ## Warning Warning colors indicate caution, risk, or actions that require attention but are not destructive. They are commonly used for alerts, messages, and transitional states where the user should pause or review information. ## Danger Danger colors represent destructive, irreversible, or critical actions and states. They should be immediately recognizable and used consistently for errors, destructive buttons, and critical alerts. ## Foreground Foreground colors are used for primary content such as text and icons. These colors are optimized for readability and accessibility and adapt automatically to background and surface contexts. Foreground colors should never be hard-coded at the component level. ## Background Background colors define the base canvas of the interface. They establish overall contrast and mood while staying visually quiet. ## Surface Surface colors sit on top of backgrounds and are used for containers such as cards, panels, modals, and dropdown. Surfaces help create visual separation and hierarchy through elevation, contrast, and layering rather than strong color shifts. ## Form field Form field colors are specialized tokens used for inputs, controls, and interactive fields. They account for multiple states such as default, focus, and hover. Isolating them ensures form elements have a distinct visual language from buttons and the rest of the UI. ## Separator Separator colors are used for dividers, outlines, and subtle boundaries. They exist to structure content and guide the eye without adding noise. Separator colors should remain low contrast and unobtrusive. ## Other Other colors serve specific utility roles across the interface. They exist to structure content and guide the eye without adding noise. ## Primitive Primitive colors are mode agnostic values used as foundations for semantic color tokens. They do not change between light and dark themes. ## How to Use Colors **In your components:** ```jsx
``` **In CSS files:** ```css title="global.css" /* Direct CSS variables */ .my-component { background: var(--accent); color: var(--accent-foreground); border: 1px solid var(--border); } /* With @apply and @layer */ @layer components { .button { @apply bg-accent text-accent-foreground; &:hover, &[data-hovered="true"] { @apply bg-accent-hover; } &:active, &[data-pressed="true"] { @apply bg-accent-hover; transform: scale(0.97); } } } ``` ## Default Theme The complete theme definition can be found in ([variables.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css)). This theme automatically switches between light and dark modes based on the `class="dark"` or `data-theme="dark"` attributes. ```css @layer base { /* HeroUI Default Theme */ :root { color-scheme: light; /* == Common Variables == */ /* Primitive Colors (Do not change between light and dark) */ --white: oklch(100% 0 0); --black: oklch(0% 0 0); --snow: oklch(0.9911 0 0); --eclipse: oklch(0.2103 0.0059 285.89); /* Spacing scale */ --spacing: 0.25rem; /* Border */ --border-width: 1px; --field-border-width: 0px; --disabled-opacity: 0.5; /* Ring offset - Used for focus ring */ --ring-offset-width: 2px; /* Cursor */ --cursor-interactive: pointer; --cursor-disabled: not-allowed; /* Radius */ --radius: 0.5rem; --field-radius: calc(var(--radius) * 1.5); /* == Light Theme Variables == */ /* Base Colors */ --background: oklch(0.9702 0 0); --foreground: var(--eclipse); /* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */ --surface: var(--white); --surface-foreground: var(--foreground); /* Overlay: Used for floating/overlay components (tooltips, popovers, modals, menus) */ --overlay: var(--white); --overlay-foreground: var(--foreground); --muted: oklch(0.5517 0.0138 285.94); --scrollbar: oklch(87.1% 0.006 286.286); --default: oklch(94% 0.001 286.375); --default-foreground: var(--eclipse); --accent: oklch(0.6204 0.195 253.83); --accent-foreground: var(--snow); /* Form Field Defaults - Colors */ --field-background: var(--white); --field-foreground: oklch(0.2103 0.0059 285.89); --field-placeholder: var(--muted); --field-border: transparent; /* no border by default on form fields */ /* Status Colors */ --success: oklch(0.7329 0.1935 150.81); --success-foreground: var(--eclipse); --warning: oklch(0.7819 0.1585 72.33); --warning-foreground: var(--eclipse); --danger: oklch(0.6532 0.2328 25.74); --danger-foreground: var(--snow); /* Component Colors */ --segment: var(--white); --segment-foreground: var(--eclipse); /* Misc Colors */ --border: oklch(92% 0.004 286.32); --separator: oklch(92% 0.004 286.32); --focus: var(--accent); --link: var(--foreground); /* Backdrop */ --backdrop: rgba(0, 0, 0, 0.5); /* Shadows */ --surface-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); /* Overlay shadow */ --overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09); --field-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); /* Skeleton Default Global Animation */ --skeleton-animation: shimmer; /* shimmer, pulse, none */ /* Tooltip Default Delays */ --tooltip-delay: 1500ms; --tooltip-close-delay: 500ms; } .dark, [data-theme="dark"] { color-scheme: dark; /* == Dark Theme Variables == */ /* Base Colors */ --background: oklch(12% 0.005 285.823); --foreground: var(--snow); /* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */ --surface: oklch(0.2103 0.0059 285.89); --surface-foreground: var(--foreground); /* Overlay: Used for floating/overlay components (tooltips, popovers, modals, menus) - lighter for contrast */ --overlay: oklch(0.22 0.0059 285.89); /* A bit lighter than surface for visibility in dark mode */ --overlay-foreground: var(--foreground); --muted: oklch(70.5% 0.015 286.067); --scrollbar: oklch(70.5% 0.015 286.067); --default: oklch(27.4% 0.006 286.033); --default-foreground: var(--snow); /* Form Field Defaults - Colors (only the ones that are different from light theme) */ --field-background: var(--default); --field-foreground: var(--foreground); /* Status Colors */ --warning: oklch(0.8203 0.1388 76.34); --warning-foreground: var(--eclipse); --danger: oklch(0.594 0.1967 24.63); --danger-foreground: var(--snow); /* Component Colors */ --segment: oklch(0.3964 0.01 285.93); --segment-foreground: var(--foreground); /* Misc Colors */ --border: oklch(22% 0.006 286.033); --separator: oklch(22% 0.006 286.033); --focus: var(--accent); --link: var(--foreground); /* Backdrop */ --backdrop: rgba(0, 0, 0, 0.6); /* Shadows */ --surface-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */ --overlay-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */ --field-shadow: 0 0 0 0 transparent inset; /* Transparent shadow to allow ring utilities to work */ } } ``` ## Customizing Colors **Override existing colors:** ```css :root { /* Override default colors */ --accent: oklch(0.7 0.15 250); --success: oklch(0.65 0.15 155); } [data-theme="dark"] { /* Override dark theme colors */ --accent: oklch(0.8 0.12 250); --success: oklch(0.75 0.12 155); } ``` **Tip:** Convert colors at [oklch.com](https://oklch.com) **Add your own colors:** ```css :root, [data-theme="light"] { --info: oklch(0.6 0.15 210); --info-foreground: oklch(0.98 0 0); } .dark, [data-theme="dark"] { --info: oklch(0.7 0.12 210); --info-foreground: oklch(0.15 0 0); } /* Make the color available to Tailwind */ @theme inline { --color-info: var(--info); --color-info-foreground: var(--info-foreground); } ``` Now you can use it: ```tsx
Info message
``` > **Note**: To learn more about theme variables and how they work in Tailwind CSS v4, see the [Tailwind CSS Theme documentation](https://tailwindcss.com/docs/theme).
# Composition **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/composition **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(handbook)/composition.mdx > Build flexible UI with component composition patterns HeroUI uses composition patterns to create flexible, customizable components. Change the rendered element, compose components together, and maintain full control over markup. ## Framework-Agnostic Styles HeroUI's variant functions are available in the `@heroui/styles` package, which can be used independently of React. This enables Vue, Svelte, and other frameworks to use HeroUI's design system: ```tsx // Import directly from @heroui/styles (framework-agnostic) import { buttonVariants } from '@heroui/styles'; // Or import from @heroui/react (re-exports the same functions) import { buttonVariants } from '@heroui/react'; ``` Both imports work identically. Use `@heroui/styles` when building for non-React frameworks or when you want to avoid pulling in React dependencies. ## Polymorphic Styling Apply HeroUI styles to any element using variant functions or BEM classes. Extend component styles to framework components, native HTML elements, or custom components with full type safety. **Example: Styling a Link as a Button** You can use `buttonVariants` to style a Link component with button styles: ```tsx import { buttonVariants } from '@heroui/styles'; import Link from 'next/link'; // Style a Next.js Link as a primary button About // Style a native anchor as a secondary button with custom size External Link ``` **Using BEM classes directly:** ```tsx import Link from 'next/link'; // Apply button styles directly using BEM classes About ``` **Working with Compound Components** When using a custom root element instead of HeroUI's Root component, child components cannot access context slots. You can manually pass `className` to child components using variant functions or BEM classes: ```tsx import { Link } from '@heroui/react'; import { linkVariants } from '@heroui/styles'; import NextLink from 'next/link'; // With custom root - pass className manually const slots = linkVariants(); About Page About Page ``` This approach works because HeroUI's variant functions and BEM classes can be applied to any element, giving you complete flexibility to style framework components, native elements, or custom components with HeroUI's design system. ## Direct Class Application The simplest way to style links or other elements is to apply HeroUI's [BEM](https://getbem.com/) classes directly. This approach is straightforward and works with any framework or vanilla HTML. **With Next.js Link:** ```tsx import Link from 'next/link'; Return Home ``` **With native anchor:** ```tsx Go to Dashboard ``` **Available button classes:** * `.button` — Base button styles * `.button--primary`, `.button--secondary`, `.button--tertiary`, `.button--danger`, `.button--ghost` — Variants * `.button--sm`, `.button--md`, `.button--lg` — Sizes * `.button--icon-only` — Icon-only button This approach works because HeroUI uses [BEM](https://getbem.com/) classes that can be applied to any element. It's perfect when you don't need the component's interactive features (like `onPress` handlers) and just want the visual styling. ## Using Variant Functions For more control and type safety, use variant functions to apply HeroUI styles to framework-specific components or custom elements. Variant functions are available from both `@heroui/styles` (framework-agnostic) and `@heroui/react` (re-exports). **With Next.js Link:** ```tsx import { Link } from '@heroui/react'; import { linkVariants } from '@heroui/styles'; import NextLink from 'next/link'; const slots = linkVariants(); About Page ``` **With Button styles:** ```tsx import { buttonVariants } from '@heroui/styles'; import Link from 'next/link'; Dashboard ``` **Available variant functions:** Each component exports its variant function (`buttonVariants`, `chipVariants`, `linkVariants`, `spinnerVariants`, and more) from `@heroui/styles`. Use them to apply HeroUI's design system to any element while maintaining type safety. ## Compound Components HeroUI components are built as compound components—they export multiple parts that work together. Use them in three flexible ways: **Option 1: Compound pattern (recommended)** — Use the main component directly without `.Root` suffix: ```tsx import { Alert } from '@heroui/react'; Success Your changes have been saved. ``` **Option 2: Compound pattern with .Root** — Use the `.Root` suffix if you prefer explicit naming: ```tsx import { Alert } from '@heroui/react'; Success Your changes have been saved. ``` **Option 3: Named exports** — Import each part separately: ```tsx import { AlertRoot, AlertIcon, AlertContent, AlertTitle, AlertDescription, AlertClose } from '@heroui/react'; Success Your changes have been saved. ``` **Mixed syntax:** Mix compound and named exports in the same component: ```tsx import { Alert, AlertTitle, AlertDescription } from '@heroui/react'; Success Your changes have been saved. ``` **Simple components:** Simple components like `Button` work the same way—no `.Root` needed: ```tsx import { Button } from '@heroui/react'; // Recommended - no .Root needed // Or with .Root Click me // Or named export import { ButtonRoot } from '@heroui/react'; Click me ``` **Benefits:** All three patterns provide flexibility, customization, control, and consistency. Choose the pattern that fits your codebase. ## Mixing Variant Functions You can combine variant functions from different components to create unique styles: ```tsx import { Link } from '@heroui/react'; import { linkVariants, buttonVariants } from '@heroui/styles'; // Link styled with button variants const buttonStyles = buttonVariants({ variant: "tertiary", size: "md" }); HeroUI ``` ## Custom Components Create your own components by composing HeroUI primitives: ```tsx import { Button, Tooltip } from '@heroui/react'; import { buttonVariants } from '@heroui/styles'; // Link button component using variant functions function LinkButton({ href, children, variant = "primary", ...props }) { return ( {children} ); } // Icon button with tooltip function IconButton({ icon, label, ...props }) { return ( {label} ); } ``` ## Custom Variants Create custom variants by extending the component's variant function: ```tsx import type { ButtonRootProps } from "@heroui/react"; import type { VariantProps } from "tailwind-variants"; import { Button } from "@heroui/react"; import { buttonVariants, tv } from "@heroui/styles"; const myButtonVariants = tv({ extend: buttonVariants, base: "text-md text-shadow-lg font-semibold shadow-md data-[pending=true]:opacity-40", variants: { radius: { lg: "rounded-lg", md: "rounded-md", sm: "rounded-sm", full: "rounded-full", }, size: { sm: "h-10 px-4", md: "h-11 px-6", lg: "h-12 px-8", xl: "h-13 px-10", }, variant: { primary: "text-white dark:bg-white/10 dark:text-white dark:hover:bg-white/15", }, }, defaultVariants: { radius: "full", variant: "primary", }, }); type MyButtonVariants = VariantProps; export type MyButtonProps = Omit & MyButtonVariants & { className?: string }; function CustomButton({ className, radius, variant, ...props }: MyButtonProps) { return ``` The `render` prop is also useful for rendering link components from client-side routers, or reusing existing presentational components. ```tsx import {Link} from '@heroui/react'; import NextLink from 'next/link'; ( } href="/privacy-policy" /> )} > Privacy Policy ``` Follow these rules to avoid breaking the behavior and accessibility of the component: * Always render the expected element type (e.g. if ` ); } ``` ### Pages Router For `pages/`, wrap your application in `pages/_app.tsx`. ```tsx // pages/_app.tsx import "@/styles/globals.css"; import type {AppProps} from "next/app"; import {ThemeProvider as NextThemesProvider} from "next-themes"; export default function App({Component, pageProps}: AppProps) { return ( ); } ``` ## Using custom theme names The `attribute="class"` setup works well for the built-in `light` and `dark` themes. If your custom theme CSS is written with `data-theme` selectors, configure `next-themes` to write `data-theme` instead. ```tsx {children} ``` When you pass a custom `themes` list, include `"light"` and `"dark"` if you still want the built-in themes available. ## React with useTheme Use HeroUI's `useTheme` hook when you are building a plain React app, such as Vite or Create React App, and do not need `next-themes`. The hook is exported from `@heroui/react`. It stores the selected theme in `localStorage`, resolves `"system"` from the user's OS preference, and applies both the class and `data-theme` attribute to ``. ```tsx // src/components/theme-switcher.tsx import {Button, useTheme} from "@heroui/react"; export function ThemeSwitcher() { const {resolvedTheme, setTheme, theme} = useTheme("system"); return (
); } ``` Use one theme controller per app. In Next.js, prefer `next-themes` and its `useTheme` hook. In plain React apps, use `useTheme` from `@heroui/react`. ## Styling for both themes Theme-aware utilities work automatically because they read CSS variables: ```tsx
Theme-aware content
``` Use the `dark:` variant for one-off changes that only apply in dark mode: ```tsx
Custom dark-mode adjustment
```
# Styling **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/styling **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(handbook)/styling.mdx > Style HeroUI components with CSS, Tailwind, or CSS-in-JS HeroUI components provide flexible styling options: Tailwind CSS utilities, CSS with [BEM](https://getbem.com/) classes or data attributes, CSS-in-JS libraries, and render props for dynamic styling. ## Basic Styling **Using className:** All HeroUI components accept `className` props: ```tsx {/* content */} ``` **Using style:** Components also accept inline styles: ```tsx ``` ## Scrollbars HeroUI scroll slots use `@apply scrollbar` in component CSS. For your own overflow containers, use the utilities from `@heroui/styles`: ```tsx
{/* long content */}
``` | Utility | Effect | | ------------------- | ---------------------------------------------------- | | `scrollbar` | HeroUI thumb (reads theme `--scrollbar-*` variables) | | `scrollbar-thin` | HeroUI themed thin scrollbar | | `scrollbar-default` | OS / browser scrollbars | | `scrollbar-none` | Hidden scrollbar | Global and per-subtree control uses `data-scrollbar` on an ancestor. See [Theming](/docs/handbook/theming#scrollbars) for tokens and modes. ## State-Based Styling HeroUI components expose their state through data attributes, similar to CSS pseudo-classes: ```css /* Target different states */ .button[data-hovered="true"], .button:hover { background: var(--accent-hover); } .button[data-pressed="true"], .button:active { transform: scale(0.97); } .button[data-focus-visible="true"], .button:focus-visible { outline: 2px solid var(--focus); } ``` ## Render Props Apply dynamic styling based on component state: ```tsx // Dynamic classes // Dynamic content ``` ## BEM Classes HeroUI uses [BEM methodology](https://getbem.com/) for consistent class naming: ```css /* Block */ .button { } .accordion { } /* Element */ .accordion__trigger { } .accordion__panel { } /* Modifier */ .button--primary { } .button--lg { } .accordion--outline { } ``` **Customizing components globally:** ```css /* global.css */ @layer components { /* Override button styles */ .button { @apply font-semibold uppercase; } .button--primary { @apply bg-indigo-600 hover:bg-indigo-700; } /* Add custom variant */ .button--gradient { @apply bg-gradient-to-r from-purple-500 to-pink-500; } } ``` ## Creating Wrapper Components Create reusable custom components using [tailwind-variants](https://tailwind-variants.org/)—a Tailwind CSS first-class variant API: ```tsx import { Button as HeroButton, type ButtonProps } from '@heroui/react'; import { buttonVariants, tv, type VariantProps } from '@heroui/styles'; const customButtonVariants = tv({ extend: buttonVariants, base: 'font-medium transition-all', variants: { intent: { primary: 'bg-blue-500 hover:bg-blue-600 text-white', secondary: 'bg-gray-200 hover:bg-gray-300', danger: 'bg-red-500 hover:bg-red-600 text-white', }, size: { small: 'text-sm px-2 py-1', medium: 'text-base px-4 py-2', large: 'text-lg px-6 py-3', }, }, defaultVariants: { intent: 'primary', size: 'medium', }, }); type CustomButtonVariants = VariantProps; interface CustomButtonProps extends Omit, CustomButtonVariants { className?: string; } export function CustomButton({ intent, size, className, ...props }: CustomButtonProps) { return ( ); } ``` ## CSS-in-JS Integration **Styled Components:** ```tsx import styled from 'styled-components'; import { Button } from '@heroui/react'; const StyledButton = styled(Button)` background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%); border-radius: 8px; color: white; padding: 12px 24px; &:hover { box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3); } `; ``` **Emotion:** ```tsx import { css } from '@emotion/css'; import { Button } from '@heroui/react'; const buttonStyles = css` background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%); border-radius: 8px; color: white; padding: 12px 24px; &:hover { box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3); } `; ``` ## Responsive Design **Using Tailwind utilities:** ```tsx ``` **Or with CSS:** ```css .button { font-size: 0.875rem; padding: 0.5rem 1rem; } @media (min-width: 768px) { .button { font-size: 1rem; padding: 0.75rem 1.5rem; } } ``` ## CSS Modules For scoped styles, use CSS Modules: ```css /* Button.module.css */ .button { background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 12px 24px; border-radius: 8px; } .button:hover { transform: translateY(-2px); } .button--primary { background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 12px 24px; border-radius: 8px; } ``` ```tsx import styles from './Button.module.css'; import { Button } from '@heroui/react'; ``` ## Component Classes Reference **Button:** `.button`, `.button--{variant}`, `.button--{size}`, `.button--icon-only` **Accordion:** `.accordion`, `.accordion__item`, `.accordion__trigger`, `.accordion__panel`, `.accordion--outline` > **Note:** See component docs for complete class references: [Button](/docs/components/button#css-classes), [Accordion](/docs/components/accordion#css-classes) View all component classes in [@heroui/styles/components](https://github.com/heroui-inc/heroui/tree/main/packages/styles/components). ## Next Steps * Learn about [Animation](/docs/handbook/animation) techniques * Explore [Theming](/docs/handbook/theming) system * Browse [Component](/docs/react/components) examples
# Theming **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/theming **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(handbook)/theming.mdx > Customize HeroUI's design system with CSS variables and global styles HeroUI uses CSS variables and [BEM](https://getbem.com/) classes for theming. Customize everything from colors to component styles using standard CSS. **Want to create your own theme?** Try the [Theme Builder](/themes) to visually customize colors, radius, fonts, and more — then export the CSS to use in your project. ## How It Works HeroUI's theming system is built on top of [Tailwind CSS v4](https://tailwindcss.com/docs/theme)'s theme. When you import `@heroui/styles`, it uses Tailwind's built-in color palettes, maps them to semantic variables, automatically switches between light and dark themes, and uses CSS layers and the `@theme` directive for organization. **Naming pattern:** * Colors without a suffix are backgrounds (e.g., `--accent`) * Colors with `-foreground` are for text on that background (e.g., `--accent-foreground`) ## Quick Start **Apply a theme:** Add a theme class to your HTML and apply colors to the body: ```html ``` **Switch themes:** ```html ``` **Switch themes programmatically with [next-themes](https://github.com/pacocoursey/next-themes) (For Next.js):** First, wrap your app with `ThemeProvider`: ```tsx // app/providers.tsx "use client"; import { ThemeProvider } from "next-themes"; export function Providers({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` ```tsx // app/layout.tsx import { Providers } from "./providers"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` Then use `useTheme` to toggle between themes: ```tsx "use client"; import { useTheme } from "next-themes"; export function ThemeSwitch() { const { theme, setTheme } = useTheme(); return ( ); } ``` **Override colors:** ```css /* app/globals.css */ @import "tailwindcss"; @import "@heroui/styles"; :root { /* Override any color variable */ --accent: oklch(0.7 0.25 260); --success: oklch(0.65 0.15 155); } ``` > **Note**: See [Colors](/docs/handbook/colors) for the complete color palette and visual reference. > **Dark mode**: For a complete setup guide with `next-themes` and HeroUI's `useTheme` hook, see [Dark Mode](/docs/handbook/dark-mode). **Create your own theme:** ```css /* src/themes/ocean.css */ @layer base { /* Ocean Light */ [data-theme="ocean"] { color-scheme: light; /* Primitive Colors (Do not change between light and dark) */ --white: oklch(100% 0 0); --black: oklch(0% 0 0); --snow: oklch(0.9911 0 0); --eclipse: oklch(0.2103 0.0059 285.89); /* Spacing & Layout */ --spacing: 0.25rem; --border-width: 1px; --field-border-width: 0px; --disabled-opacity: 0.5; --ring-offset-width: 2px; --cursor-interactive: pointer; --cursor-disabled: not-allowed; /* Radius */ --radius: 0.75rem; --field-radius: calc(var(--radius) * 1.5); /* Base Colors */ --background: oklch(0.985 0.015 225); --foreground: var(--eclipse); /* Surface: Used for non-overlay components */ --surface: var(--white); --surface-foreground: var(--foreground); /* Overlay: Used for floating/overlay components */ --overlay: var(--white); --overlay-foreground: var(--foreground); --muted: oklch(0.5517 0.0138 285.94); --scrollbar-thumb: color-mix(in oklch, var(--foreground) 15%, transparent); --scrollbar-track: transparent; --scrollbar-gutter: auto; --scrollbar-width: thin; --scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); --scrollbar: var(--scrollbar-thumb); --default: oklch(94% 0.001 286.375); --default-foreground: var(--eclipse); /* Ocean accent */ --accent: oklch(0.450 0.150 230); --accent-foreground: var(--snow); /* Form Field Defaults */ --field-background: var(--white); --field-foreground: oklch(0.2103 0.0059 285.89); --field-placeholder: var(--muted); --field-border: transparent; /* Status (kept compatible) */ --success: oklch(0.7329 0.1935 150.81); --success-foreground: var(--eclipse); --warning: oklch(0.7819 0.1585 72.33); --warning-foreground: var(--eclipse); --danger: oklch(0.6532 0.2328 25.74); --danger-foreground: var(--snow); /* Component Colors */ --segment: var(--white); --segment-foreground: var(--foreground); /* Misc */ --border: oklch(0.50 0.060 230 / 22%); --separator: oklch(92% 0.004 286.32); --focus: var(--accent); --link: var(--accent); /* Shadows */ --surface-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); --overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09); --field-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); /* Skeleton Default Global Animation */ --skeleton-animation: shimmer; /* Possible values: shimmer, pulse, none */ /* Tooltip Default Delays */ --tooltip-delay: 1500ms; --tooltip-close-delay: 500ms; } /* Ocean Dark */ [data-theme="ocean-dark"] { color-scheme: dark; /* Base Colors */ --background: oklch(0.140 0.020 230); --foreground: var(--snow); /* Surface: Used for non-overlay components */ --surface: oklch(0.2103 0.0059 285.89); --surface-foreground: var(--foreground); /* Overlay: Used for floating/overlay components */ --overlay: oklch(0.22 0.0059 285.89); --overlay-foreground: var(--foreground); --muted: oklch(70.5% 0.015 286.067); --scrollbar-thumb: color-mix(in oklch, var(--foreground) 15%, transparent); --scrollbar-track: transparent; --scrollbar-gutter: auto; --scrollbar-width: thin; --scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); --scrollbar: var(--scrollbar-thumb); --default: oklch(27.4% 0.006 286.033); --default-foreground: var(--snow); /* Form Field Defaults */ --field-background: var(--default); --field-foreground: var(--foreground); /* Ocean accent */ --accent: oklch(0.860 0.080 230); --accent-foreground: var(--eclipse); /* Status */ --success: oklch(0.7329 0.1935 150.81); --success-foreground: var(--eclipse); --warning: oklch(0.8203 0.1388 76.34); --warning-foreground: var(--eclipse); --danger: oklch(0.594 0.1967 24.63); --danger-foreground: var(--snow); /* Component Colors */ --segment: oklch(0.3964 0.01 285.93); --segment-foreground: var(--foreground); /* Misc */ --border: oklch(22% 0.006 286.033); --separator: oklch(22% 0.006 286.033); --focus: var(--accent); --link: var(--accent); /* Shadows */ --surface-shadow: 0 0 0 0 transparent inset; --overlay-shadow: 0 0 0 0 transparent inset; --field-shadow: 0 0 0 0 transparent inset; } } ``` Use your theme: ```css /* app/globals.css */ @layer theme, base, components, utilities; @import "tailwindcss"; @import "@heroui/styles"; @import "./src/themes/ocean.css" layer(theme); /* [!code highlight]*/ ``` Apply your theme: ```html ``` ## Customize Components **Global component styles:** Override any component using BEM classes: ```css @layer components { /* Customize buttons */ .button { @apply font-semibold tracking-wide; } .button--primary { @apply bg-blue-600 hover:bg-blue-700; } /* Customize accordions */ .accordion__trigger { @apply text-lg font-bold; } } ``` > **Note**: See [Styling](/docs/handbook/styling) for the complete styling reference. **Find component classes:** Each component docs page lists all available classes (base classes, modifiers, elements, states). Example: [Button classes](/docs/components/button#css-classes) ## Import Strategies **Full import (recommended):** Get everything with two lines: ```css @import "tailwindcss"; @import "@heroui/styles"; ``` **Selective import:** Import only what you need: ```css /* Define layers */ @layer theme, base, components, utilities; /* Base requirements */ @import "tailwindcss"; @import "@heroui/styles/base" layer(base); /* OR specific base file */ @import "@heroui/styles/base/base.css" layer(base); /* Theme variables */ @import "@heroui/styles/themes/shared/theme.css" layer(theme); @import "@heroui/styles/themes/default" layer(theme); /* OR specific theme files */ @import "@heroui/styles/themes/default/index.css" layer(theme); @import "@heroui/styles/themes/default/variables.css" layer(theme); /* Components (all components) */ @import "@heroui/styles/components" layer(components); /* OR specific component files */ @import "@heroui/styles/components/index.css" layer(components); @import "@heroui/styles/components/button.css" layer(components); @import "@heroui/styles/components/accordion.css" layer(components); /* Utilities (optional) */ @import "@heroui/styles/utilities" layer(utilities); /* Variants (optional) */ @import "@heroui/styles/variants" layer(utilities); ``` > **Note**: Directory imports (e.g., `@heroui/styles/components`) automatically resolve to their `index.css` file. Use explicit file paths (e.g., `@heroui/styles/components/button.css`) to import individual component styles. **Headless mode:** Build your own styles from scratch: ```css @import "tailwindcss"; @import "@heroui/styles/base/base.css"; /* Your custom styles */ .button { /* Your button styles */ } ``` ## Adding Custom Colors Add your own semantic colors to the theme: ```css /* Define in both light and dark themes */ :root, [data-theme="light"] { --info: oklch(0.6 0.15 210); --info-foreground: oklch(0.98 0 0); } .dark, [data-theme="dark"] { --info: oklch(0.7 0.12 210); --info-foreground: oklch(0.15 0 0); } /* Make the color available to Tailwind */ @theme inline { --color-info: var(--info); --color-info-foreground: var(--info-foreground); } ``` Now use it in your components: ```tsx
Info message
``` ## Variables Reference HeroUI defines three types of variables in [`variables.css`](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css): 1. **Base Variables** — Non-changing values like `--white`, `--black`, spacing, and typography 2. **Theme Variables** — Colors that change between light/dark themes, plus scrollbar tokens (`--scrollbar-thumb`, `--scrollbar-width`, etc.) 3. **Calculated Variables** — Hover states, soft variants, and border/separator levels (the **Calculated Colors** block in each light/dark theme, using `color-mix()`) For a complete reference, see: [Colors Documentation](/docs/handbook/colors), [Default Theme Variables](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css), [Shared Theme Utilities](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/shared/theme.css) **Tailwind theme bridge (`@theme inline`):** [`themes/shared/theme.css`](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/shared/theme.css) maps semantic variables to Tailwind tokens (`--color-*`, `--radius-*`, `--ease-*`). Calculated colors reference underlying vars (e.g. `--surface-hover`, `--accent-soft`) from `variables.css` — they are not inlined with `color-mix()` in this file: ```css @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-surface: var(--surface); --color-surface-foreground: var(--surface-foreground); --color-surface-hover: var(--surface-hover); --color-surface-secondary: var(--surface-secondary); --color-surface-secondary-foreground: var(--surface-secondary-foreground); --color-surface-tertiary: var(--surface-tertiary); --color-surface-tertiary-foreground: var(--surface-tertiary-foreground); --color-overlay: var(--overlay); --color-overlay-foreground: var(--overlay-foreground); --color-muted: var(--muted); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-segment: var(--segment); --color-segment-foreground: var(--segment-foreground); --color-border: var(--border); --color-separator: var(--separator); --color-focus: var(--focus); --color-link: var(--link); --color-default: var(--default); --color-default-foreground: var(--default-foreground); --color-success: var(--success); --color-success-foreground: var(--success-foreground); --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); --color-danger: var(--danger); --color-danger-foreground: var(--danger-foreground); --color-backdrop: var(--backdrop); --shadow-surface: var(--surface-shadow); --shadow-overlay: var(--overlay-shadow); --shadow-field: var(--field-shadow); /* Form Field Tokens */ --color-field: var(--field-background, var(--default)); --color-field-hover: var(--field-hover); --color-field-foreground: var(--field-foreground, var(--foreground)); --color-field-placeholder: var(--field-placeholder, var(--muted)); --color-field-border: var(--field-border, var(--border)); --radius-field: var(--field-radius, calc(var(--radius) * 1.5)); --border-width-field: var(--field-border-width, var(--border-width)); /* Color Tokens */ --color-background-secondary: var(--background-secondary); --color-background-tertiary: var(--background-tertiary); --color-background-inverse: var(--background-inverse); --color-default-hover: var(--default-hover); --color-accent-hover: var(--accent-hover); --color-success-hover: var(--success-hover); --color-warning-hover: var(--warning-hover); --color-danger-hover: var(--danger-hover); /* Form Field Colors */ --color-field-focus: var(--field-focus); --color-field-border-hover: var(--field-border-hover); --color-field-border-focus: var(--field-border-focus); /* Soft Colors */ --color-default-soft: var(--default-soft); --color-default-soft-foreground: var(--default-soft-foreground); --color-default-soft-hover: var(--default-soft-hover); --color-accent-soft: var(--accent-soft); --color-accent-soft-foreground: var(--accent-soft-foreground); --color-accent-soft-hover: var(--accent-soft-hover); --color-danger-soft: var(--danger-soft); --color-danger-soft-foreground: var(--danger-soft-foreground); --color-danger-soft-hover: var(--danger-soft-hover); --color-warning-soft: var(--warning-soft); --color-warning-soft-foreground: var(--warning-soft-foreground); --color-warning-soft-hover: var(--warning-soft-hover); --color-success-soft: var(--success-soft); --color-success-soft-foreground: var(--success-soft-foreground); --color-success-soft-hover: var(--success-soft-hover); /* Separator Colors - Levels */ --color-separator-secondary: var(--separator-secondary); --color-separator-tertiary: var(--separator-tertiary); /* Border Colors - Levels */ --color-border-secondary: var(--border-secondary); --color-border-tertiary: var(--border-tertiary); /* Radius and default sizes - defaults can change by just changing the --radius */ --radius-xs: calc(var(--radius) * 0.25); /* 0.125rem (2px) */ --radius-sm: calc(var(--radius) * 0.5); /* 0.25rem (4px) */ --radius-md: calc(var(--radius) * 0.75); /* 0.375rem (6px) */ --radius-lg: calc(var(--radius) * 1); /* 0.5rem (8px) */ --radius-xl: calc(var(--radius) * 1.5); /* 0.75rem (12px) */ --radius-2xl: calc(var(--radius) * 2); /* 1rem (16px) */ --radius-3xl: calc(var(--radius) * 3); /* 1.5rem (24px) */ --radius-4xl: calc(var(--radius) * 4); /* 2rem (32px) */ /* Transition Timing Functions */ --ease-smooth: ease; /* same as transition: ease; */ /* These custom curves are made by https://twitter.com/bdc */ /* From smoother to faster */ --ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53); --ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19); --ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22); --ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06); --ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035); --ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335); /* From slower to faster */ --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94); --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1); --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1); --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1); --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1); --ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1); /* Custom smooth-out curve: fast start, smooth stop - Apple style */ --ease-out-fluid: cubic-bezier(0.32, 0.72, 0, 1); /* From slower to faster */ --ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955); --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1); --ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1); --ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1); --ease-in-out-expo: cubic-bezier(1, 0, 0, 1); --ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86); /* Linear */ --ease-linear: linear; /* Animations */ --animate-spin-fast: spin 0.75s linear infinite; --animate-skeleton: skeleton 2s linear infinite; --animate-caret-blink: caret-blink 1.2s ease-out infinite; @keyframes skeleton { 100% { transform: translateX(200%); } } @keyframes caret-blink { 0%, 70%, 100% { opacity: 1; } 20%, 50% { opacity: 0; } } } ``` Form controls rely on `--field-*` theme variables. Hover, focus, and border variants are defined under **Calculated Colors** in `variables.css` and mapped to Tailwind in `theme.css` (e.g. `--color-field-hover: var(--field-hover)`). Override `--field-background`, `--field-hover`, and related tokens in your theme to restyle inputs, checkboxes, radios, and OTP slots without affecting surfaces like buttons or cards. ## Scrollbars HeroUI applies a shared scrollbar style to component scroll areas (tables, popovers, drawers, and similar). Scrollbars use standard CSS properties (`scrollbar-width`, `scrollbar-color`, `scrollbar-gutter`) — no `::-webkit-scrollbar` overrides. **Modes** — set `data-scrollbar` on ``, a component root, or a scroll slot: | Mode | `data-scrollbar` | Behavior | | ------------ | ------------------- | ---------------------------------------------- | | HeroUI thin | *(unset)* or `thin` | Thin thumb from theme tokens | | OS / browser | `default` | Native scrollbars (`auto`) | | Hidden | `none` | No visible scrollbar (`scrollbar-width: none`) | ```html
...
...
``` **Theme variables** — defined in light and dark theme blocks in [`variables.css`](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css): | Variable | Description | | -------------------- | --------------------------------------------------------- | | `--scrollbar-thumb` | Thumb color (default: 15% `--foreground` via `color-mix`) | | `--scrollbar-track` | Track color (default: `transparent`) | | `--scrollbar-gutter` | Gutter (default: `auto`) | | `--scrollbar-width` | `scrollbar-width` (default: `thin`) | | `--scrollbar-color` | `scrollbar-color` (default: thumb + track) | | `--scrollbar` | Legacy alias of `--scrollbar-thumb` | **Customize globally:** ```css /* app/globals.css */ :root { --scrollbar-thumb: color-mix(in oklch, var(--accent) 30%, transparent); --scrollbar-gutter: auto; } ``` **Per scroll slot** — pass `data-scrollbar` on a component or override tokens on a wrapper: ```tsx ...
``` **Custom overflow areas** — use the `scrollbar`, `scrollbar-thin`, `scrollbar-default`, or `scrollbar-none` utilities from `@heroui/styles` on your own elements. See [Styling](/docs/handbook/styling) for class-based overrides. > **Note**: Some components hide scrollbars by default (date picker popovers, color picker, secondary tabs). Nested scroll slots (e.g. the calendar year picker inside a date picker) keep HeroUI scrollbars because `scrollbar-none` only affects the element it is applied to, not descendants using `@apply scrollbar`. ## Vibrant Palette By default, HeroUI uses accessible soft foreground colors that mix the semantic color with the foreground for better contrast. If you prefer more saturated, vibrant soft foreground colors, add the `data-vibrant-palette` attribute to your root element: ```html ``` This switches all `*-soft-foreground` variables (accent, success, warning, danger) to use 92% of the semantic color with only 8% foreground mixed in — closer to the raw color but with a slight contrast boost. | Mode | Accessible (default) | Vibrant | | --------------- | -------------------------------------------- | ------------------------------------- | | Soft foreground | `color-mix(color 70-80%, foreground 30-40%)` | `color-mix(color 92%, foreground 8%)` | The vibrant palette prioritizes visual saturation over contrast. It may not meet WCAG accessibility guidelines for some color combinations, especially with lighter accent colors. You can also enable vibrant palette in the [Theme Builder](/themes) via the "Vibrant palette" toggle in the theme popover. ## Resources * [Colors Documentation](/docs/handbook/colors) * [Styling Guide](/docs/handbook/styling) * [Tailwind CSS v4 Theming](https://tailwindcss.com/docs/theme) * [BEM Methodology](https://getbem.com/) * [OKLCH Color Tool](https://oklch.com)
# CLI **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/cli **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(overview)/cli.mdx > Use the CLI to manage HeroUI dependencies and initialize projects. The CLI offers a comprehensive suite of commands to initialize, manage, and improve your HeroUI projects. It enables you to `install`, `uninstall`, or `upgrade` individual components, assess the health of your project, download documentation for AI coding agents, and more. ## Installation Requirements: * [Node.js version 22.22.0 or later](https://nodejs.org/en/) ### Global Installation To install `heroui-cli` globally, execute one of the following commands in your terminal: npm pnpm yarn bun ```bash npm install heroui-cli@latest -g ``` ```bash pnpm add heroui-cli@latest -g ``` ```bash yarn global add heroui-cli@latest ``` ```bash bun add heroui-cli@latest --global ``` ### Without Installation Alternatively, you can use `heroui-cli` without a global installation by running one of the following: ```bash pnpm dlx heroui-cli@latest ``` ```bash npx heroui-cli@latest ``` ```bash yarn dlx heroui-cli@latest ``` ```bash bunx heroui-cli@latest ``` ## Quick Start Once `heroui-cli` is installed, run the following command to display available commands: ```bash heroui ``` This will produce the following help output: ```bash Usage: heroui [command] Options: -v, --version Output the current version --no-cache Disable cache, by default data will be cached for 30m after the first request -d, --debug Debug mode will not install dependencies -h --help Display help information for commands Commands: init [options] [projectName] Initializes a new project install [options] Installs @heroui/react and @heroui/styles to your project upgrade [options] Upgrades @heroui/react and @heroui/styles to the latest versions uninstall [options] Uninstall @heroui/react and @heroui/styles from the project list [options] Lists installed HeroUI packages (@heroui/react, @heroui/styles) env [options] Displays debugging information for the local environment doctor [options] Checks for issues in the project agents-md [options] Downloads HeroUI documentation for AI coding agents help [command] Display help for command ``` ### init Initialize a new HeroUI project using the `init` command. This sets up your project with the necessary configurations. ```bash heroui init [options] ``` **Options:** * `-t --template [string]` The template to use for the new project e.g. app, pages, vite, react-router * `-p --package [string]` The package manager to use for the new project output: ```bash HeroUI CLI ┌ Create a new project │ ◇ Select a template (Enter to select) │ ● App (A Next.js 16 with app directory template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ○ Pages (A Next.js 16 with pages directory template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ○ Vite (A Vite template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ○ React Router (A React Router template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ◇ New project name (Enter to skip with default name) │ my-heroui-app │ ◇ Select a package manager (Enter to select) │ ● npm │ ○ yarn │ ○ pnpm │ ○ bun │ ◇ Template created successfully! │ ◇ Next steps ───────╮ │ │ │ cd my-heroui-app │ │ npm install │ │ │ ├────────────────────╯ │ └ 🚀 Get started with npm run dev ``` Install the dependencies to start the local server: ```bash cd my-heroui-app && npm install ``` ```bash cd my-heroui-app && pnpm install ``` ```bash cd my-heroui-app && yarn install ``` ```bash cd my-heroui-app && bun install ``` Start the local server: npm pnpm yarn bun ```bash npm run dev ``` ```bash pnpm run dev ``` ```bash yarn dev ``` ```bash bun run dev ``` ### Install Install `@heroui/react` and `@heroui/styles` to your project, along with their peer dependencies. If they are already installed, the command does nothing. ```bash heroui install [options] ``` **Options:** * `-p --packagePath` \[string] The path to the package.json file **Output:** ```bash HeroUI CLI 📦 Packages to be installed: ╭─────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │─────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 │ stable │ https://heroui.com │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭─────────────── PeerDependencies ────────────────╮ │ react@18.3.1 latest │ │ react-dom@18.3.1 latest │ │ tailwindcss@4.2.2 latest │ ╰─────────────────────────────────────────────────╯ ? Proceed with installation? › - Use arrow-keys. Return to submit. ❯ Yes No ✅ @heroui/react and @heroui/styles installed successfully ``` ### upgrade Upgrade `@heroui/react` and `@heroui/styles` with their peer dependencies to the latest versions. ```bash heroui upgrade [options] ``` **Options:** * `-p --packagePath` \[string] The path to the package.json file **Output:** ```bash HeroUI CLI ╭──────────────────────────── Upgrade ────────────────────────────╮ │ @heroui/react ^3.0.0 -> ^3.1.0 │ │ @heroui/styles ^3.0.0 -> ^3.1.0 │ ╰─────────────────────────────────────────────────────────────────╯ ? Would you like to proceed with the upgrade? › - Use arrow-keys. Return to submit. ❯ Yes No ✅ Upgrade complete. All packages are up to date. ``` ### uninstall Uninstall `@heroui/react` and `@heroui/styles` from your project. Peer dependencies will not be uninstalled. ```bash heroui uninstall [options] ``` **Options:** * `-p --packagePath` \[string] The path to the package.json file **Output:** ```bash HeroUI CLI ❗️ Packages slated for uninstallation: ╭──────────────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │──────────────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 │ stable │ https://heroui.com │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ? Confirm uninstallation of these packages: › - Use arrow-keys. Return to submit. ❯ Yes No ✅ Successfully uninstalled: @heroui/react, @heroui/styles ``` ### list List the installed HeroUI packages (`@heroui/react`, `@heroui/styles`). ```bash heroui list [options] ``` **Options:** * `-p --packagePath` \[string] The path to the package.json file **Output:** ```bash HeroUI CLI Current installed packages: ╭──────────────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │──────────────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 🚀latest │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 🚀latest │ stable │ https://heroui.com │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ``` ### doctor Check for issues in your project. * Check whether `@heroui/react` and `@heroui/styles` are installed * Check whether `required peer dependencies` are installed and matched minimal requirements in the project ```bash heroui doctor [options] ``` **Options:** * `-p --packagePath` \[string] The path to the package.json file **Output:** If there is a problem in your project, the `doctor` command will display the problem information. ```bash HeroUI CLI HeroUI CLI: ❌ Your project has 1 issue that require attention ❗️Issue 1: missingHeroUIPackages The following HeroUI packages are not installed: - @heroui/styles Run `heroui install` to install them. ``` Otherwise, the `doctor` command will display the following message. ```bash HeroUI CLI ✅ Your project has no detected issues. ``` ### env Display debug information about the local environment. ```bash heroui env [options] ``` **Options:** * `-p --packagePath` \[string] The path to the package.json file **Output:** ```bash HeroUI CLI Current installed packages: ╭──────────────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │──────────────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 🚀latest │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 🚀latest │ stable │ https://heroui.com │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ Environment Info: System: OS: darwin CPU: arm64 Binaries: Node: v25.8.1 ``` ### agents-md Download HeroUI documentation for AI coding agents (Claude, Cursor, etc.). The command clones the latest docs from the HeroUI repository and injects a compact index into `AGENTS.md` or `CLAUDE.md` so assistants can reference your project's HeroUI setup. ```bash heroui agents-md [options] ``` **Options:** * `--react` \[boolean] Include React docs only (one library at a time) * `--native` \[boolean] Include Native docs only * `--migration` \[boolean] Include HeroUI v2 to v3 migration docs only * `--output ` \[string] Target file path (e.g., `AGENTS.md`, `CLAUDE.md`) * `--ssh` \[boolean] Use SSH instead of HTTPS for git clone **Examples:** Run without flags to enter interactive mode: ```bash heroui agents-md ``` Download React docs to a specific file: ```bash heroui agents-md --react --output AGENTS.md ``` Download Native or migration docs: ```bash heroui agents-md --native --output CLAUDE.md heroui agents-md --migration --output AGENTS.md ``` **How it works:** 1. Clones documentation from the `v3` branch using git sparse-checkout 2. Generates a compact index of doc and demo files 3. Injects the index into your markdown file between markers (`` / ``, and similar for Native and Migration) 4. Adds `.heroui-docs/` to `.gitignore` Only one of `--react`, `--native`, or `--migration` can be selected at a time. For more details, see [AGENTS.md](/docs/react/getting-started/agents-md). The `agents-md` command collects anonymous usage data (selection, output file names, duration, success or error). Set `HEROUI_ANALYTICS_DISABLED=1` to opt out. ## Reporting issues If you found a bug, please report it in [heroui-cli Issues](https://github.com/heroui-inc/heroui-cli/issues). # Design Principles **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/design-principles **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(overview)/design-principles.mdx > Core principles that guide HeroUI v3's design and development HeroUI v3 follows 10 core principles that prioritize clarity, accessibility, customization, and developer experience. ## Core Principles ### 1. Semantic Intent Over Visual Style Use semantic naming (primary, secondary, tertiary) instead of visual descriptions (solid, flat, bordered). Inspired by [Uber's Base design system](https://base.uber.com/6d2425e9f/p/756216-button), variants follow a clear hierarchy: ```tsx // ✅ Semantic variants communicate hierarchy ``` | Variant | Purpose | Usage | | ------------- | --------------------------------- | ---------------- | | **Primary** | Main action to move forward | 1 per context | | **Secondary** | Alternative actions | Multiple allowed | | **Tertiary** | Dismissive actions (cancel, skip) | Sparingly | | **Danger** | Destructive actions | When needed | ### 2. Accessibility as Foundation Built on [React Aria Components](https://react-spectrum.adobe.com/react-aria/) for WCAG 2.1 AA compliance. Automatic ARIA attributes, keyboard navigation, and screen reader support included. ```tsx import { Tabs, TabList, Tab, TabPanel } from '@heroui/react'; Profile Security Content Content ``` ### 3. Composition Over Configuration Compound components let you rearrange, customize, or omit parts as needed. Use dot notation, named exports, or mix both. ```tsx // Compose parts to build exactly what you need import { Accordion, AccordionItem, AccordionHeading, AccordionTrigger, AccordionIndicator, AccordionPanel, AccordionBody } from '@heroui/react'; Question Text Answer content ``` ### 4. Progressive Disclosure Start simple, add complexity only when needed. Components work with minimal props and scale up as requirements grow. ```tsx // Level 1: Minimal // Level 2: Enhanced // Level 3: Advanced ``` ### 5. Predictable Behavior Consistent patterns across all components: sizes (`sm`, `md`, `lg`), variants, className support, and data attributes. Same API, same behavior. ```tsx // All components follow the same patterns ``` or with React: ```tsx // Apply styles to any component import { buttonVariants } from '@heroui/styles'; Home ``` ### 8. Developer Experience Excellence Clear APIs, descriptive errors, IntelliSense, AI-friendly markdown docs, and Storybook for visual testing. ### 9. Complete Customization Beautiful defaults out-of-the-box. Transform the entire look with CSS variables or [BEM](https://getbem.com/) classes. Every slot is customizable. ```css /* 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. Open and Extensible Wrap, extend, and customize components to match your needs. Use variant functions, direct BEM class application, or create custom wrappers. **Apply styles with variant functions:** ```tsx 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" }); About Page ``` **Apply BEM classes directly:** ```tsx import Link from 'next/link'; // Apply HeroUI's BEM classes directly to any element Dashboard ``` **Create custom wrapper components:** ```tsx // Custom wrapper component const CTAButton = ({ intent = 'primary-cta', children, ref, ...props }: CTAButtonProps) => { const variantMap = { 'primary-cta': 'primary', 'secondary-cta': 'secondary', 'minimal': 'ghost' }; return ( ); }; ``` **Extend with Tailwind Variants:** ```tsx 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 ); } ``` Example: `pages/index.tsx` ```tsx import {Button} from "@heroui/react"; export default function HomePage() { return (
); } ```
HeroUI v3 does not require a provider. Components work directly after installation and style import. ### 3 Locale Setup (Optional) To integrate with Next.js, ensure the locale on the server matches the client. In your root layout, determine the user's preferred language and set the `lang` and `dir` attributes on the `` element. ```tsx // app/layout.tsx import {headers} from 'next/headers'; import {isRTL} from '@heroui/react'; import {ClientProviders} from './provider'; export default async function RootLayout({children}) { // Get the user's preferred language from the Accept-Language header. // You could also get this from a database, URL param, etc. const acceptLanguage = (await headers()).get('accept-language'); const lang = acceptLanguage?.split(/[,;]/)[0] || 'en-US'; return ( {children} ); } ``` Create `app/provider.tsx`. This should render an `I18nProvider` to set the locale used by React Aria. ```tsx // app/provider.tsx "use client"; import {I18nProvider} from '@heroui/react'; export function ClientProviders({lang, children}) { return ( {children} ); } ``` If you are using a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) (CSP) with a nonce, add a `` tag to your document head, setting the content attribute to the generated nonce value. React Aria automatically reads the nonce from this tag. ## Vite ### 1. Create a Vite project ```bash npx heroui-cli@latest init ``` When prompted, select the **Vite** template. Then open your new folder and install dependencies (for example `pnpm install`). ### 2. Use your first HeroUI component Example: `src/App.tsx` ```tsx import {Button} from "@heroui/react"; function App() { return (
); } export default App; ``` HeroUI v3 does not require a provider. Components work directly after installation and style import. ## Next steps * [Quick Start](/docs/react/getting-started/quick-start) for the fastest setup path * [Themes](/docs/react/getting-started/theming) to customize colors and tokens * [Components](/docs/react/components) to explore all available components
# Quick Start **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/quick-start **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(overview)/quick-start.mdx > Get started with HeroUI v3 in minutes ## Requirements * [React 19+](https://reactjs.org/) * [Tailwind CSS v4](https://tailwindcss.com/docs/installation/framework-guides) ## Quick Install \` from \`@heroui/react\` somewhere visible to confirm styles are applied. When done, summarize the changes you made and tell me how to start the dev server.`} > **Prefer to let your AI assistant do it?** Install the [HeroUI MCP Server](/docs/react/getting-started/mcp-server) in your editor, then paste the prompt into your AI assistant — it will analyze your project and handle the entire setup for you. Install HeroUI and required dependencies: ```bash npm i @heroui/styles @heroui/react ``` ```bash pnpm add @heroui/styles @heroui/react ``` ```bash yarn add @heroui/styles @heroui/react ``` ```bash bun add @heroui/styles @heroui/react ``` ## Import Styles Add to your main CSS file `globals.css`: ```css @import "tailwindcss"; @import "@heroui/styles"; /* [!code highlight]*/ ``` Import order matters. Always import `tailwindcss` first. ## Use Components ```tsx import { Button } from '@heroui/react'; function App() { return ( ); } ``` ## What's Next? * [Themes](/themes) - Create and share your own themes * [Browse Components](/docs/react/components) - See all available components * [Learn Styling](/docs/handbook/styling) - Customize with Tailwind CSS * [Explore Patterns](/docs/handbook/composition) - Master compound components # Agent Skills **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/agent-skills **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(ui-for-agents)/agent-skills.mdx > Enable AI assistants to build UIs with HeroUI v3 components HeroUI Skills give your AI assistant comprehensive knowledge of HeroUI v3 components, patterns, and best practices. ### Installation ```bash curl -fsSL https://heroui.com/install | bash -s heroui-react ``` Or using the skills package: ```bash npx skills add heroui-inc/heroui ``` Support Claude Code, Cursor, OpenCode and more. ### Usage Skills are **automatically discovered** by your AI assistant, or call it directly using `/heroui-react` command. Simply ask your AI assistant to: * Build components using HeroUI v3 * Create pages with HeroUI components * Customize themes and styles * Access component documentation For more complex use cases, use the [MCP Server](/docs/react/getting-started/mcp-server) which provides real-time access to component documentation and source code. ### What's Included * HeroUI v3 installation guide * All HeroUI v3 components with props, examples, and usage patterns * Theming and styling guidelines * Design principles and composition patterns ### Structure ``` skills/heroui-react/ ├── SKILL.md # Main skill documentation ├── LICENSE.txt # Apache License 2.0 └── scripts/ # Utility scripts ├── list_components.mjs ├── get_component_docs.mjs ├── get_source.mjs ├── get_styles.mjs ├── get_theme.mjs └── get_docs.mjs ``` ### Related Documentation * [Agent Skills Specification](https://agentskills.io/home) - Learn about the Agent Skills format * [Claude Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) - Claude's Skills documentation * [Cursor Skills](https://cursor.com/docs/context/skills) - Using Skills in Cursor * [OpenCode Skills](https://opencode.ai/docs/skills) - Using Skills in OpenCode # AGENTS.md **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/agents-md **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(ui-for-agents)/agents-md.mdx > Download HeroUI v3 React documentation for AI coding agents Download HeroUI v3 React documentation directly into your project for AI assistants to reference. **Note:** The `agents-md` command is specifically for HeroUI React v3. Other CLI commands (like `add`, `init`, `upgrade`, etc.) are for HeroUI v2 (for now). ### Usage ```bash npx heroui-cli@latest agents-md --react ``` Or specify output file: ```bash npx heroui-cli@latest agents-md --react --output AGENTS.md ``` ### What It Does * Downloads latest HeroUI v3 React docs to `.heroui-docs/react/` * Generates an index in `AGENTS.md` or `CLAUDE.md` * Includes demo files for code examples * Adds `.heroui-docs/` to `.gitignore` automatically ### Options * `--react` - Download React docs only * `--output ` - Target file(s) (e.g., `AGENTS.md` or `AGENTS.md CLAUDE.md`) * `--ssh` - Use SSH for git clone ### Requirements * Tailwind CSS >= v4 * React >= 19.0.0 * `@heroui/react >= 3.0.0` or `@latest` ### Related Documentation * [AGENTS.md](https://agents.md/) - Learn about the AGENTS.md format for coding agents * [CLAUDE.md](https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md) - Claude equivalent of AGENTS.md * [AGENTS.md vs Skills](https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals) - AGENTS.md performance # LLMs.txt **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/llms-txt **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(ui-for-agents)/llms-txt.mdx > Enable AI assistants like Claude, Cursor, and Windsurf to understand HeroUI v3 We provide [LLMs.txt](https://llmstxt.org/) files to make HeroUI v3 documentation accessible to AI coding assistants. ## Available Files **Core documentation:** * [/react/llms.txt](/react/llms.txt) — Quick reference index for React documentation * [/react/llms-full.txt](/react/llms-full.txt) — Complete HeroUI React documentation **For limited context windows:** * [/react/llms-components.txt](/react/llms-components.txt) — Component documentation only * [/react/llms-patterns.txt](/react/llms-patterns.txt) — Common patterns and recipes **All platforms:** * [/llms.txt](/llms.txt) — Quick reference index (React + Native) * [/llms-full.txt](/llms-full.txt) — Complete documentation (React + Native) * [/llms-components.txt](/llms-components.txt) — All component documentation * [/llms-patterns.txt](/llms-patterns.txt) — All patterns and recipes ## Integration **Claude Code:** Tell Claude to reference the documentation: ``` Use HeroUI React documentation from https://heroui.com/react/llms.txt ``` Or add to your project's `.claude` file for automatic loading. **Cursor:** Use the `@Docs` feature: ``` @Docs https://heroui.com/react/llms-full.txt ``` [Learn more](https://docs.cursor.com/context/@-symbols/@-docs) **Windsurf:** Add to your `.windsurfrules` file: ``` #docs https://heroui.com/react/llms-full.txt ``` [Learn more](https://docs.codeium.com/windsurf/memories#memories-and-rules) **Other AI tools:** Most AI assistants can reference documentation by URL. Simply provide: ``` https://heroui.com/react/llms.txt ``` **For component-specific documentation:** ``` https://heroui.com/react/llms-components.txt ``` **For patterns and best practices:** ``` https://heroui.com/react/llms-patterns.txt ``` ## Contributing Found an issue with AI-generated code? Help us improve our LLMs.txt files on [GitHub](https://github.com/heroui-inc/heroui). # MCP Server **Category**: react **URL**: https://heroui.com/en/docs/react/getting-started/mcp-server **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/getting-started/(ui-for-agents)/mcp-server.mdx > Access HeroUI v3 documentation directly in your AI assistant The HeroUI MCP Server gives AI assistants direct access to HeroUI v3 component documentation, making it easier to build with HeroUI in AI-powered development environments. The MCP server currently supports **@heroui/react v3** only and [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio). Published at `@heroui/react-mcp` on npm. View the source code on [GitHub](https://github.com/heroui-inc/heroui-mcp). As we add more components to HeroUI v3, they'll be available in the MCP server too. ## Quick Setup ### Cursor
Install in Cursor
Or manually add to **Cursor Settings** → **Tools** → **MCP Servers**: ```json title=".cursor/mcp.json" { "mcpServers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` Alternatively, add the following to your `~/.cursor/mcp.json` file. To learn more, see the [Cursor documentation](https://cursor.com/docs/context/mcp). ### Claude Code Run this command in your terminal: ```bash claude mcp add heroui-react -- npx -y @heroui/react-mcp@latest ``` Or manually add to your project's `.mcp.json` file: ```json title=".mcp.json" { "mcpServers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` After adding the configuration, restart Claude Code and run `/mcp` to see the HeroUI MCP server in the list. If you see **Connected**, you're ready to use it. See the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp) for more details. ### Windsurf Add the HeroUI server to your project's `.windsurf/mcp.json` configuration file: ```json title=".windsurf/mcp.json" { "mcpServers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` After adding the configuration, restart Windsurf to activate the MCP server. See the [Windsurf MCP documentation](https://docs.windsurf.com/windsurf/cascade/mcp) for more details. ### Zed Add the HeroUI server to your `settings.json` configuration file. Open settings via Command Palette (`zed: open settings`) or use `Cmd-,` (Mac) / `Ctrl-,` (Linux): ```json title="settings.json" { "context_servers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"], "env": {} } } } ``` After adding the configuration, restart Zed and open the Agent Panel settings view. Check that the indicator dot next to the heroui server is green with "Server is active" tooltip. See the [Zed MCP documentation](https://zed.dev/docs/ai/mcp) for more details. ### VS Code To configure MCP in VS Code with GitHub Copilot, add the HeroUI server to your project's `.vscode/mcp.json` configuration file: ```json title=".vscode/mcp.json" { "servers": { "heroui-react": { "type": "stdio", "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` After adding the configuration, open `.vscode/mcp.json` and click **Start** next to the heroui-react server. See the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) for more details. ### Codex Add the HeroUI server to your `~/.codex/config.toml` (or a project-scoped `.codex/config.toml`): ```toml title="config.toml" [mcp_servers.heroui-react] command = "npx" args = ["-y", "@heroui/react-mcp@latest"] ``` After adding the configuration, restart Codex and run `/mcp` in the TUI to verify the server is active. See the [Codex MCP documentation](https://developers.openai.com/codex/mcp) for more details. ### OpenCode Add the HeroUI server to your project's `opencode.json` configuration file: ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", "mcp": { "heroui-react": { "type": "local", "command": ["npx", "-y", "@heroui/react-mcp@latest"] } } } ``` After adding the configuration, restart OpenCode to activate the MCP server. See the [OpenCode MCP documentation](https://open-code.ai/docs/en/mcp-servers) for more details. ## Usage Once configured, ask your AI assistant questions like: * "Help me install HeroUI v3 in my Next.js/Vite/Astro app" * "Show me all HeroUI components" * "What props does the Button component have?" * "Give me an example of using the Card component" * "Get the source code for the Button component" * "Show me the CSS styles for Card" * "What are the theme variables for dark mode?" ### Automatic Updates The MCP server can help you upgrade to the latest HeroUI version: ```bash "Hey Cursor, update HeroUI to the latest version" ``` Your AI assistant will automatically: * Compare your current version with the latest release * Review the changelog for breaking changes * Apply the necessary code updates to your project This works for any version upgrade, whether you're updating to the latest stable or pre-release version. ## Available Tools The MCP server provides these tools to AI assistants: | Tool | Description | | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `list_components` | List all available HeroUI v3 components | | `get_component_docs` | Get complete component documentation including anatomy, props, examples, and usage patterns for one or more components | | `get_component_source_code` | Access the React/TypeScript source code (.tsx files) for components | | `get_component_source_styles` | View the CSS styles (.css files) for components | | `get_theme_variables` | Access theme variables for colors, typography, spacing with light/dark mode support | | `get_docs` | Browse the full HeroUI v3 documentation including guides and principles (use path `/docs/react/getting-started/quick-start` for installation instructions) | ## Troubleshooting **Requirements:** Node.js 22 or higher. The package will be automatically downloaded when using `npx`. **Need help?** [GitHub Issues](https://github.com/heroui-inc/heroui-mcp/issues) | [Discord Community](https://discord.gg/heroui) ## Links * [npm Package](https://www.npmjs.com/package/@heroui/react-mcp) * [GitHub Repository](https://github.com/heroui-inc/heroui-mcp) * [Contributing Guide](https://github.com/heroui-inc/heroui-mcp/blob/main/CONTRIBUTING.md) # 动画 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/animation **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(handbook)/animation.mdx > 为 HeroUI v3 组件添加流畅的动画和过渡 HeroUI 组件支持多种动画方法:内置 CSS 过渡、自定义 CSS 动画以及 Framer Motion 等 JavaScript 库。 ## 内置动画 HeroUI 组件使用数据属性来公开其动画状态: ```css /* Popover entrance/exit */ .popover[data-entering] { @apply animate-in zoom-in-90 fade-in-0 duration-200; } .popover[data-exiting] { @apply animate-out zoom-out-95 fade-out duration-150; } /* Button press effect */ .button:active, .button[data-pressed="true"] { transform: scale(0.97); } /* Accordion expansion */ .accordion__panel[aria-hidden="false"] { @apply h-[var(--panel-height)] opacity-100; } ``` **状态样式属性:** * `[data-hovered="true"]`- 悬停状态 * `[data-pressed="true"]`- 活动/按下状态 * `[data-focus-visible="true"]`- 键盘焦点 * `[data-disabled="true"]`- 禁用状态 * `[data-entering]` / `[data-exiting]`- 过渡状态 * `[aria-expanded="true"]`- 展开状态 ## CSS 动画 **使用 Tailwind 实用程序:** ```tsx // Pulse on hover // Fade in entrance Welcome message // Staggered list
Item 1 Item 2
``` **自定义过渡:** ```css /* Slower accordion */ .accordion__panel { @apply transition-all duration-500; } /* Bouncy button */ .button:active { animation: bounce 0.3s; } @keyframes bounce { 50% { transform: scale(0.95); } } ``` ## Framer Motion HeroUI 组件与 Framer Motion 无缝协作,实现高级动画。 **基本用法:** ```tsx import { motion } from 'framer-motion'; import { Button } from '@heroui/react'; const MotionButton = motion(Button); Animated Button ``` **入口动画:** ```tsx Welcome! ``` **布局动画:** ```tsx import { AnimatePresence, motion } from 'framer-motion'; function Tabs({ items, selected }) { return (
{items.map((item, i) => ( ))}
); } ``` ## 渲染属性 根据组件状态应用动态动画: ```tsx ``` ## 无障碍 **尊重动态偏好:** HeroUI 使用 Tailwind 的 motion-reduce 工具自动尊重用户动态效果偏好。当用户在系统设置中启用“减少动态效果”时,所有内置的过渡和动画效果都将被禁用。 HeroUI 扩展了 Tailwind 的 motion-reduce: 变体,以同时支持原生 `prefers-reduced-motion` 媒体查询和 `data-reduce-motion` 属性。 ```css /* HeroUI pattern - uses Tailwind's motion-reduce: */ .button { @apply transition-colors motion-reduce:transition-none; } /* Expands to support both approaches: */ @media (prefers-reduced-motion: reduce) { .button { transition: none; } } [data-reduce-motion="true"] .button { transition: none; } ``` 使用Framer Motion: ```tsx import { useReducedMotion } from 'framer-motion'; function AnimatedCard() { const shouldReduceMotion = useReducedMotion(); return ( Content ); } ``` **全局禁用动画:** 添加`data-reduce-motion="true"`到``或者``标签: ```html ``` HeroUI自动检测用户的`prefers-reduced-motion: reduce`相应地设置并禁用动画。 ## 性能技巧 **使用 GPU 加速属性**: 首选`transform`和`opacity`对于流畅的动画: ```css /* Good - GPU accelerated */ .slide-in { transform: translateX(-100%); transition: transform 0.3s; } /* Avoid - Triggers layout */ .slide-in { left: -100%; transition: left 0.3s; } ``` **`will-change`优化**: 使用`will-change`优化动画,但在不设置动画时将其删除: ```css .button { will-change: transform; } .button:not(:hover) { will-change: auto; } ``` ## 下一步 * 了解[样式](/docs/handbook/styling)方法 * 探索[组件](/docs/react/components)示例 * 查看[主题](/docs/handbook/theming)文档
# 颜色 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/colors **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(handbook)/colors.mdx > HeroUI v3 的调色板与主题系统 import {ColorSectionSideBySide, ColorSectionStacked, ColorSectionFormField, ColorSectionPrimitive} from "@/components/color-section"; HeroUI 的颜色体系围绕语义意图构建,而非堆砌视觉色板。系统不会暴露庞大的原始色表,而是定义一小套有意义的色彩角色,覆盖绝大多数界面需求。 系统中的多数颜色会由少量基础值自动派生。这样 HeroUI 能在保持对比度、层级与主题行为一致的同时,让整套体系易于理解与修改。 颜色应首先传达用途与状态;视觉变化来自尺度、强调与上下文。 **想要创建你自己的主题?** 试试 [主题构建器](/themes),以可视化方式自定义颜色、圆角、字体等,然后导出 CSS 用于你的项目。 ## 强调色 强调色代表品牌或产品的主识别色,用于吸引对关键操作、高亮与重点时刻的注意。 强调色应有意识地节制使用。滥用会削弱其冲击力,并破坏视觉层级。多数情况下,组件会从基础强调色自动派生悬停、柔和背景与聚焦等相关取值。 ## 默认(中性色) 默认色构成系统的中性骨架,用于大多数非强调的界面元素。 ## 成功 成功色传达积极结果、确认与完成状态,常见于反馈组件、状态指示与校验通过等场景。 ## 警告 警告色表示需谨慎、存在风险,或需要留意但非破坏性的操作,常用于提示、消息以及用户应暂停或复核信息的过渡状态。 ## 危险 危险色表示破坏性、不可逆或关键的操作与状态,应一眼可辨,并稳定用于错误、危险按钮与严重告警。 ## 前景色 前景色用于正文级内容,如文字与图标。这些颜色针对可读性与无障碍优化,并会随背景与表面上下文自动适配。请勿在组件内硬编码前景色。 ## 背景色 背景色定义界面的基底画布,在保持视觉克制的前提下建立整体对比与氛围。 ## 表面色 表面色叠在背景之上,用于卡片、面板、模态与下拉等容器。表面通过抬升、对比与分层形成区隔与层级,而非依赖强烈的色相跳跃。 ## 表单字段 表单字段色是面向输入、控件与可交互字段的专用令牌,覆盖默认、聚焦与悬停等多种状态。将其独立出来,可让表单元素在视觉上与按钮及界面其余部分保持清晰区分。 ## 分隔线 分隔线色用于分割线、描边与轻量边界,用来组织内容、引导视线而不增加噪点。分隔线色应保持低对比、不抢眼。 ## 其他 其他颜色在界面中承担特定工具性角色,用于组织内容、引导视线而不增加噪点。 ## 基础色 基础色是与模式无关的底层取值,作为语义色令牌的根基,在明暗主题之间不会改变。 ## 如何使用颜色 **在组件中:** ```jsx
``` **在 CSS 文件中:** ```css title="global.css" /* 直接使用 CSS 变量 */ .my-component { background: var(--accent); color: var(--accent-foreground); border: 1px solid var(--border); } /* 配合 @apply 与 @layer */ @layer components { .button { @apply bg-accent text-accent-foreground; &:hover, &[data-hovered="true"] { @apply bg-accent-hover; } &:active, &[data-pressed="true"] { @apply bg-accent-hover; transform: scale(0.97); } } } ``` ## 默认主题 完整主题定义见仓库中的 [variables.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css)。该主题会根据 `class="dark"` 或 `data-theme="dark"` 属性在明暗模式间自动切换。 ```css @layer base { /* HeroUI 默认主题 */ :root { color-scheme: light; /* == 通用变量 == */ /* 基础色(在明暗模式下勿改动) */ --white: oklch(100% 0 0); --black: oklch(0% 0 0); --snow: oklch(0.9911 0 0); --eclipse: oklch(0.2103 0.0059 285.89); /* 间距刻度 */ --spacing: 0.25rem; /* 边框 */ --border-width: 1px; --field-border-width: 0px; --disabled-opacity: 0.5; /* 聚焦环偏移,用于聚焦环 */ --ring-offset-width: 2px; /* 光标 */ --cursor-interactive: pointer; --cursor-disabled: not-allowed; /* 圆角 */ --radius: 0.5rem; --field-radius: calc(var(--radius) * 1.5); /* == 浅色主题变量 == */ /* 基础颜色 */ --background: oklch(0.9702 0 0); --foreground: var(--eclipse); /* 表面:用于非浮层组件(卡片、手风琴、折叠组等) */ --surface: var(--white); --surface-foreground: var(--foreground); /* 遮罩层:用于悬浮/浮层组件(工具提示、气泡、模态框、菜单) */ --overlay: var(--white); --overlay-foreground: var(--foreground); --muted: oklch(0.5517 0.0138 285.94); --scrollbar: oklch(87.1% 0.006 286.286); --default: oklch(94% 0.001 286.375); --default-foreground: var(--eclipse); --accent: oklch(0.6204 0.195 253.83); --accent-foreground: var(--snow); /* 表单字段默认值 - 颜色 */ --field-background: var(--white); --field-foreground: oklch(0.2103 0.0059 285.89); --field-placeholder: var(--muted); --field-border: transparent; /* 表单字段默认无边框 */ /* 状态色 */ --success: oklch(0.7329 0.1935 150.81); --success-foreground: var(--eclipse); --warning: oklch(0.7819 0.1585 72.33); --warning-foreground: var(--eclipse); --danger: oklch(0.6532 0.2328 25.74); --danger-foreground: var(--snow); /* 组件颜色 */ --segment: var(--white); --segment-foreground: var(--eclipse); /* 杂项颜色 */ --border: oklch(92% 0.004 286.32); --separator: oklch(92% 0.004 286.32); --focus: var(--accent); --link: var(--foreground); /* 背衬 */ --backdrop: rgba(0, 0, 0, 0.5); /* 阴影 */ --surface-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); /* 遮罩层阴影 */ --overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09); --field-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); /* 骨架屏全局默认动画 */ --skeleton-animation: shimmer; /* shimmer, pulse, none */ /* Tooltip 默认延迟 */ --tooltip-delay: 1500ms; --tooltip-close-delay: 500ms; } .dark, [data-theme="dark"] { color-scheme: dark; /* == 深色主题变量 == */ /* 基础颜色 */ --background: oklch(12% 0.005 285.823); --foreground: var(--snow); /* 表面:用于非浮层组件(卡片、手风琴、折叠组等) */ --surface: oklch(0.2103 0.0059 285.89); --surface-foreground: var(--foreground); /* 遮罩层:用于悬浮/浮层组件(工具提示、气泡、模态框、菜单)——略浅于表面以提高对比度 */ --overlay: oklch(0.22 0.0059 285.89); /* 比表面色略浅,便于在深色模式下辨识 */ --overlay-foreground: var(--foreground); --muted: oklch(70.5% 0.015 286.067); --scrollbar: oklch(70.5% 0.015 286.067); --default: oklch(27.4% 0.006 286.033); --default-foreground: var(--snow); /* 表单字段默认值 - 颜色(仅列出与浅色主题不同的项) */ --field-background: var(--default); --field-foreground: var(--foreground); /* 状态色 */ --warning: oklch(0.8203 0.1388 76.34); --warning-foreground: var(--eclipse); --danger: oklch(0.594 0.1967 24.63); --danger-foreground: var(--snow); /* 组件颜色 */ --segment: oklch(0.3964 0.01 285.93); --segment-foreground: var(--foreground); /* 杂项颜色 */ --border: oklch(22% 0.006 286.033); --separator: oklch(22% 0.006 286.033); --focus: var(--accent); --link: var(--foreground); /* 背衬 */ --backdrop: rgba(0, 0, 0, 0.6); /* 阴影 */ --surface-shadow: 0 0 0 0 transparent inset; /* 深色模式下无阴影 */ --overlay-shadow: 0 0 0 0 transparent inset; /* 深色模式下无阴影 */ --field-shadow: 0 0 0 0 transparent inset; /* 透明阴影,以便环形工具类生效 */ } } ``` ## 自定义颜色 **覆盖已有颜色:** ```css :root { /* 覆盖默认颜色 */ --accent: oklch(0.7 0.15 250); --success: oklch(0.65 0.15 155); } [data-theme="dark"] { /* 覆盖深色主题颜色 */ --accent: oklch(0.8 0.12 250); --success: oklch(0.75 0.12 155); } ``` **提示:** 可在 [oklch.com](https://oklch.com) 转换颜色。 **添加自定义颜色:** ```css :root, [data-theme="light"] { --info: oklch(0.6 0.15 210); --info-foreground: oklch(0.98 0 0); } .dark, [data-theme="dark"] { --info: oklch(0.7 0.12 210); --info-foreground: oklch(0.15 0 0); } /* 将颜色暴露给 Tailwind */ @theme inline { --color-info: var(--info); --color-info-foreground: var(--info-foreground); } ``` 随后即可使用: ```tsx
提示信息
``` > **注意:** 若要进一步了解主题变量及其在 Tailwind CSS v4 中的行为,请参阅 [Tailwind CSS 主题文档](https://tailwindcss.com/docs/theme)。
# 组合 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/composition **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(handbook)/composition.mdx > 使用组件组合模式构建灵活的 UI HeroUI 使用组合模式来创建灵活、可定制的组件。你可以更换渲染的元素、把组件组合在一起,并完全掌控最终的标记结构。 ## 与框架无关的样式 HeroUI 的变体函数位于 `@heroui/styles` 包中,可以独立于 React 使用。这使得 Vue、Svelte 等其他框架也能使用 HeroUI 的设计系统: ```tsx // Import directly from @heroui/styles (framework-agnostic) import { buttonVariants } from '@heroui/styles'; // Or import from @heroui/react (re-exports the same functions) import { buttonVariants } from '@heroui/react'; ``` 两种导入方式的工作原理完全相同。在为非 React 框架构建,或希望避免引入 React 依赖时,请使用 `@heroui/styles`。 ## 多态样式 使用变体函数或 BEM 类,将 HeroUI 样式应用到任何元素上。可以把组件样式扩展到框架组件、原生 HTML 元素或自定义组件,并保持完整的类型安全。 **示例:将 Link 设置为按钮样式** 你可以使用 `buttonVariants` 为 Link 组件应用按钮样式: ```tsx import { buttonVariants } from '@heroui/styles'; import Link from 'next/link'; // Style a Next.js Link as a primary button About // Style a native anchor as a secondary button with custom size External Link ``` **直接使用 BEM 类:** ```tsx import Link from 'next/link'; // Apply button styles directly using BEM classes About ``` **配合复合组件使用** 当使用自定义根元素而非 HeroUI 的 Root 组件时,子组件无法访问 context slot。你可以使用变体函数或 BEM 类,手动将 `className` 传递给子组件: ```tsx import { Link } from '@heroui/react'; import { linkVariants } from '@heroui/styles'; import NextLink from 'next/link'; // With custom root - pass className manually const slots = linkVariants(); About Page About Page ``` 这种方法之所以可行,是因为 HeroUI 的变体函数和 BEM 类可以应用到任何元素上,让你能够灵活地用 HeroUI 的设计系统为框架组件、原生元素或自定义组件设置样式。 ## 直接应用类名 为链接或其他元素设置样式最简单的方法,就是直接使用 HeroUI 的 [BEM](https://getbem.com/) 类。这种方法简单直接,适用于任何框架或纯 HTML。 **配合 Next.js Link 使用:** ```tsx import Link from 'next/link'; Return Home ``` **配合原生 anchor 使用:** ```tsx Go to Dashboard ``` **可用的按钮类名:** * `.button` — 基础按钮样式 * `.button--primary`、`.button--secondary`、`.button--tertiary`、`.button--danger`、`.button--ghost` — 变体 * `.button--sm`、`.button--md`、`.button--lg` — 尺寸 * `.button--icon-only` — 仅图标按钮 这种方法之所以可行,是因为 HeroUI 使用了 [BEM](https://getbem.com/) 类,可以应用到任何元素上。当你不需要组件的交互功能(例如 `onPress` 事件处理器)、只想要视觉样式时,这种方式非常合适。 ## 使用变体函数 如需更多控制和类型安全,可以使用变体函数将 HeroUI 样式应用到特定框架的组件或自定义元素上。`@heroui/styles`(与框架无关)和 `@heroui/react`(重新导出)都提供了变体函数。 **配合 Next.js Link 使用:** ```tsx import { Link } from '@heroui/react'; import { linkVariants } from '@heroui/styles'; import NextLink from 'next/link'; const slots = linkVariants(); About Page ``` **配合 Button 样式:** ```tsx import { buttonVariants } from '@heroui/styles'; import Link from 'next/link'; Dashboard ``` **可用的变体函数:** 每个组件都从 `@heroui/styles` 导出其变体函数(`buttonVariants`、`chipVariants`、`linkVariants`、`spinnerVariants` 等)。使用它们可以在保持类型安全的同时,将 HeroUI 的设计系统应用到任何元素上。 ## 复合组件 HeroUI 组件以复合组件的方式构建 —— 它们会导出多个协同工作的子部件。你可以通过三种灵活的方式来使用它们: **选项 1:复合模式(推荐)** — 直接使用主组件,无需 `.Root` 后缀: ```tsx import { Alert } from '@heroui/react'; Success Your changes have been saved. ``` **选项 2:使用 .Root 的复合模式** — 如果你喜欢显式命名,可以添加 `.Root` 后缀: ```tsx import { Alert } from '@heroui/react'; Success Your changes have been saved. ``` **选项 3:命名导出** — 单独导入每个部分: ```tsx import { AlertRoot, AlertIcon, AlertContent, AlertTitle, AlertDescription, AlertClose } from '@heroui/react'; Success Your changes have been saved. ``` **混合语法:** 在同一组件中混合复合和命名导出: ```tsx import { Alert, AlertTitle, AlertDescription } from '@heroui/react'; Success Your changes have been saved. ``` **简单组件:** 像 `Button` 这样的简单组件以同样的方式工作 —— 无需 `.Root`: ```tsx import { Button } from '@heroui/react'; // Recommended - no .Root needed // Or with .Root Click me // Or named export import { ButtonRoot } from '@heroui/react'; Click me ``` **优点:** 这三种模式都能提供灵活性、可定制性、可控性和一致性。选择最适合你代码库的那一种即可。 ## 混合使用变体函数 你可以组合来自不同组件的变体函数,以创建独特的样式: ```tsx import { Link } from '@heroui/react'; import { linkVariants, buttonVariants } from '@heroui/styles'; // Link styled with button variants const buttonStyles = buttonVariants({ variant: "tertiary", size: "md" }); HeroUI ``` ## 自定义组件 通过组合 HeroUI 原语,创建你自己的组件: ```tsx import { Button, Tooltip } from '@heroui/react'; import { buttonVariants } from '@heroui/styles'; // Link button component using variant functions function LinkButton({ href, children, variant = "primary", ...props }) { return ( {children} ); } // Icon button with tooltip function IconButton({ icon, label, ...props }) { return ( {label} ); } ``` ## 自定义变体 通过扩展组件的变体函数来创建自定义变体: ```tsx import type { ButtonRootProps } from "@heroui/react"; import type { VariantProps } from "tailwind-variants"; import { Button } from "@heroui/react"; import { buttonVariants, tv } from "@heroui/styles"; const myButtonVariants = tv({ extend: buttonVariants, base: "text-md text-shadow-lg font-semibold shadow-md data-[pending=true]:opacity-40", variants: { radius: { lg: "rounded-lg", md: "rounded-md", sm: "rounded-sm", full: "rounded-full", }, size: { sm: "h-10 px-4", md: "h-11 px-6", lg: "h-12 px-8", xl: "h-13 px-10", }, variant: { primary: "text-white dark:bg-white/10 dark:text-white dark:hover:bg-white/15", }, }, defaultVariants: { radius: "full", variant: "primary", }, }); type MyButtonVariants = VariantProps; export type MyButtonProps = Omit & MyButtonVariants & { className?: string }; function CustomButton({ className, radius, variant, ...props }: MyButtonProps) { return ``` `render` prop 对于从客户端路由库渲染链接组件,或复用已有的展示型组件也很有用。 ```tsx import {Link} from '@heroui/react'; import NextLink from 'next/link'; ( } href="/privacy-policy" /> )} > Privacy Policy ``` 请遵循以下规则,以免破坏组件的行为和无障碍能力: * 始终渲染期望的元素类型(例如,如果期望的是 ` ); } ``` ### Pages Router 如果使用 `pages/`,请在 `pages/_app.tsx` 中包裹你的应用。 ```tsx // pages/_app.tsx import "@/styles/globals.css"; import type {AppProps} from "next/app"; import {ThemeProvider as NextThemesProvider} from "next-themes"; export default function App({Component, pageProps}: AppProps) { return ( ); } ``` ## 使用自定义主题名称 `attribute="class"` 这套配置非常适合内置的 `light` 和 `dark` 主题。如果你的自定义主题 CSS 是基于 `data-theme` 选择器编写的,请改为让 `next-themes` 写入 `data-theme`。 ```tsx {children} ``` 当你传入自定义的 `themes` 列表时,如果仍然希望保留内置主题,请将 `"light"` 和 `"dark"` 一并包含进去。 ## 在 React 中使用 useTheme 当你正在构建一个普通的 React 应用(例如 Vite 或 Create React App),并且不需要 `next-themes` 时,可以使用 HeroUI 提供的 `useTheme` 钩子。 该钩子从 `@heroui/react` 中导出。它会将当前选择的主题保存到 `localStorage`,根据用户的操作系统偏好解析 `"system"`,并同时把对应的类与 `data-theme` 属性应用到 `` 上。 ```tsx // src/components/theme-switcher.tsx import {Button, useTheme} from "@heroui/react"; export function ThemeSwitcher() { const {resolvedTheme, setTheme, theme} = useTheme("system"); return (
); } ``` 每个应用只应使用一个主题控制器。在 Next.js 中,推荐使用 `next-themes` 及其 `useTheme` 钩子;在普通的 React 应用中,请使用 `@heroui/react` 提供的 `useTheme`。 ## 同时为两种主题设置样式 主题相关的工具类会自动生效,因为它们读取的是 CSS 变量: ```tsx
Theme-aware content
``` 对于仅在深色模式下生效的一次性样式调整,请使用 `dark:` 变体: ```tsx
Custom dark-mode adjustment
```
# 样式 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/styling **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(handbook)/styling.mdx > 使用 CSS、Tailwind 或 CSS-in-JS 为 HeroUI 组件设置样式 HeroUI 组件提供灵活的样式方案:Tailwind CSS 工具类、配合 [BEM](https://getbem.com/) 类名或数据属性的 CSS、CSS-in-JS 库,以及用于动态样式的渲染属性。 ## 基础样式 **使用 className:** 所有 HeroUI 组件都接受 `className` 属性: ```tsx {/* content */} ``` **使用 style:** 组件也接受内联样式: ```tsx ``` ## 滚动条 HeroUI 的滚动插槽在组件 CSS 中使用 `@apply scrollbar`。对于你自己的溢出容器,可使用 `@heroui/styles` 提供的工具类: ```tsx
{/* 长内容 */}
``` | 工具类 | 效果 | | ------------------- | -------------------------------------- | | `scrollbar` | HeroUI 滚动条滑块(读取主题的 `--scrollbar-*` 变量) | | `scrollbar-thin` | HeroUI 主题化纤细滚动条 | | `scrollbar-default` | 操作系统 / 浏览器默认滚动条 | | `scrollbar-none` | 隐藏滚动条 | 全局及子树级别的控制可通过在祖先元素上使用 `data-scrollbar` 实现。有关令牌(tokens)和模式的更多信息,请参阅 [主题](/docs/handbook/theming#scrollbars)。 ## 基于状态的样式 HeroUI 组件通过数据属性公开其状态,类似于 CSS 伪类: ```css /* Target different states */ .button[data-hovered="true"], .button:hover { background: var(--accent-hover); } .button[data-pressed="true"], .button:active { transform: scale(0.97); } .button[data-focus-visible="true"], .button:focus-visible { outline: 2px solid var(--focus); } ``` ## 渲染属性 根据组件状态动态应用样式: ```tsx // Dynamic classes // Dynamic content ``` ## BEM 类名 HeroUI 使用 [BEM 方法论](https://getbem.com/) 来保持类名命名的一致性: ```css /* Block */ .button { } .accordion { } /* Element */ .accordion__trigger { } .accordion__panel { } /* Modifier */ .button--primary { } .button--lg { } .accordion--outline { } ``` **全局自定义组件:** ```css /* global.css */ @layer components { /* Override button styles */ .button { @apply font-semibold uppercase; } .button--primary { @apply bg-indigo-600 hover:bg-indigo-700; } /* Add custom variant */ .button--gradient { @apply bg-gradient-to-r from-purple-500 to-pink-500; } } ``` ## 创建包装组件 使用 [tailwind-variants](https://tailwind-variants.org/) 创建可复用的自定义组件 —— 它是 Tailwind CSS 的一等公民变体 API: ```tsx import { Button as HeroButton, type ButtonProps } from '@heroui/react'; import { buttonVariants, tv, type VariantProps } from '@heroui/styles'; const customButtonVariants = tv({ extend: buttonVariants, base: 'font-medium transition-all', variants: { intent: { primary: 'bg-blue-500 hover:bg-blue-600 text-white', secondary: 'bg-gray-200 hover:bg-gray-300', danger: 'bg-red-500 hover:bg-red-600 text-white', }, size: { small: 'text-sm px-2 py-1', medium: 'text-base px-4 py-2', large: 'text-lg px-6 py-3', }, }, defaultVariants: { intent: 'primary', size: 'medium', }, }); type CustomButtonVariants = VariantProps; interface CustomButtonProps extends Omit, CustomButtonVariants { className?: string; } export function CustomButton({ intent, size, className, ...props }: CustomButtonProps) { return ( ); } ``` ## CSS-in-JS 集成 **Styled Components:** ```tsx import styled from 'styled-components'; import { Button } from '@heroui/react'; const StyledButton = styled(Button)` background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%); border-radius: 8px; color: white; padding: 12px 24px; &:hover { box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3); } `; ``` **Emotion:** ```tsx import { css } from '@emotion/css'; import { Button } from '@heroui/react'; const buttonStyles = css` background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%); border-radius: 8px; color: white; padding: 12px 24px; &:hover { box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3); } `; ``` ## 响应式设计 **使用 Tailwind 工具类:** ```tsx ``` **或者使用 CSS:** ```css .button { font-size: 0.875rem; padding: 0.5rem 1rem; } @media (min-width: 768px) { .button { font-size: 1rem; padding: 0.75rem 1.5rem; } } ``` ## CSS 模块 如需作用域化的样式,可以使用 CSS 模块: ```css /* Button.module.css */ .button { background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 12px 24px; border-radius: 8px; } .button:hover { transform: translateY(-2px); } .button--primary { background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 12px 24px; border-radius: 8px; } ``` ```tsx import styles from './Button.module.css'; import { Button } from '@heroui/react'; ``` ## 组件类名参考 **Button:** `.button`、`.button--{variant}`、`.button--{size}`、`.button--icon-only` **Accordion:** `.accordion`、`.accordion__item`、`.accordion__trigger`、`.accordion__panel`、`.accordion--outline` > **注意:** 完整的类名参考请查看各组件文档:[Button](/docs/components/button#css-classes)、[Accordion](/docs/components/accordion#css-classes) 所有组件的类名请查看 [@heroui/styles/components](https://github.com/heroui-inc/heroui/tree/main/packages/styles/components)。 ## 下一步 * 了解 [动画](/docs/handbook/animation) 相关技巧 * 探索 [主题](/docs/handbook/theming) 系统 * 浏览 [组件](/docs/react/components) 示例
# 主题 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/theming **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(handbook)/theming.mdx > 使用 CSS 变量和全局样式自定义 HeroUI 的设计系统 HeroUI 使用 CSS 变量和 [BEM](https://getbem.com/) 类来实现主题化。你可以使用标准 CSS 自定义从颜色到组件样式的所有内容。 **想要创建你自己的主题?** 试试 [主题构建器](/themes),以可视化方式自定义颜色、圆角、字体等,然后导出 CSS 用于你的项目。 ## 工作原理 HeroUI 的主题系统构建于 [Tailwind CSS v4](https://tailwindcss.com/docs/theme) 的主题之上。当你导入 `@heroui/styles` 时,它会使用 Tailwind 的内置调色板,将其映射到语义化变量,自动在浅色和深色主题之间切换,并使用 CSS 层和 `@theme` 指令进行组织。 **命名规则:** * 不带后缀的颜色用作背景(例如 `--accent`) * 带 `-foreground` 后缀的颜色用于该背景上的文本(例如 `--accent-foreground`) ## 快速开始 **应用主题:** 将主题类添加到 HTML 并将颜色应用到 body 上: ```html ``` **切换主题:** ```html ``` **使用 [next-themes](https://github.com/pacocoursey/next-themes) 以编程方式切换主题(适用于 Next.js):** 首先,用 `ThemeProvider` 包装你的应用: ```tsx // app/providers.tsx "use client"; import { ThemeProvider } from "next-themes"; export function Providers({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` ```tsx // app/layout.tsx import { Providers } from "./providers"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` 然后使用 `useTheme` 在主题之间切换: ```tsx "use client"; import { useTheme } from "next-themes"; export function ThemeSwitch() { const { theme, setTheme } = useTheme(); return ( ); } ``` **覆盖颜色:** ```css /* app/globals.css */ @import "tailwindcss"; @import "@heroui/styles"; :root { /* Override any color variable */ --accent: oklch(0.7 0.25 260); --success: oklch(0.65 0.15 155); } ``` > **注意**:完整的调色板和视觉参考请参见 [颜色](/docs/handbook/colors)。 > **深色模式**:如需基于 `next-themes` 与 HeroUI `useTheme` 钩子的完整配置指南,请参见 [深色模式](/docs/handbook/dark-mode)。 **创建你自己的主题:** ```css /* src/themes/ocean.css */ @layer base { /* Ocean Light */ [data-theme="ocean"] { color-scheme: light; /* Primitive Colors (Do not change between light and dark) */ --white: oklch(100% 0 0); --black: oklch(0% 0 0); --snow: oklch(0.9911 0 0); --eclipse: oklch(0.2103 0.0059 285.89); /* Spacing & Layout */ --spacing: 0.25rem; --border-width: 1px; --field-border-width: 0px; --disabled-opacity: 0.5; --ring-offset-width: 2px; --cursor-interactive: pointer; --cursor-disabled: not-allowed; /* Radius */ --radius: 0.75rem; --field-radius: calc(var(--radius) * 1.5); /* Base Colors */ --background: oklch(0.985 0.015 225); --foreground: var(--eclipse); /* Surface: Used for non-overlay components */ --surface: var(--white); --surface-foreground: var(--foreground); /* Overlay: Used for floating/overlay components */ --overlay: var(--white); --overlay-foreground: var(--foreground); --muted: oklch(0.5517 0.0138 285.94); --scrollbar-thumb: color-mix(in oklch, var(--foreground) 15%, transparent); --scrollbar-track: transparent; --scrollbar-gutter: auto; --scrollbar-width: thin; --scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); --scrollbar: var(--scrollbar-thumb); --default: oklch(94% 0.001 286.375); --default-foreground: var(--eclipse); /* Ocean accent */ --accent: oklch(0.450 0.150 230); --accent-foreground: var(--snow); /* Form Field Defaults */ --field-background: var(--white); --field-foreground: oklch(0.2103 0.0059 285.89); --field-placeholder: var(--muted); --field-border: transparent; /* Status (kept compatible) */ --success: oklch(0.7329 0.1935 150.81); --success-foreground: var(--eclipse); --warning: oklch(0.7819 0.1585 72.33); --warning-foreground: var(--eclipse); --danger: oklch(0.6532 0.2328 25.74); --danger-foreground: var(--snow); /* Component Colors */ --segment: var(--white); --segment-foreground: var(--foreground); /* Misc */ --border: oklch(0.50 0.060 230 / 22%); --separator: oklch(92% 0.004 286.32); --focus: var(--accent); --link: var(--accent); /* Shadows */ --surface-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); --overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09); --field-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); /* Skeleton Default Global Animation */ --skeleton-animation: shimmer; /* Possible values: shimmer, pulse, none */ /* Tooltip Default Delays */ --tooltip-delay: 1500ms; --tooltip-close-delay: 500ms; } /* Ocean Dark */ [data-theme="ocean-dark"] { color-scheme: dark; /* Base Colors */ --background: oklch(0.140 0.020 230); --foreground: var(--snow); /* Surface: Used for non-overlay components */ --surface: oklch(0.2103 0.0059 285.89); --surface-foreground: var(--foreground); /* Overlay: Used for floating/overlay components */ --overlay: oklch(0.22 0.0059 285.89); --overlay-foreground: var(--foreground); --muted: oklch(70.5% 0.015 286.067); --scrollbar-thumb: color-mix(in oklch, var(--foreground) 15%, transparent); --scrollbar-track: transparent; --scrollbar-gutter: auto; --scrollbar-width: thin; --scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); --scrollbar: var(--scrollbar-thumb); --default: oklch(27.4% 0.006 286.033); --default-foreground: var(--snow); /* Form Field Defaults */ --field-background: var(--default); --field-foreground: var(--foreground); /* Ocean accent */ --accent: oklch(0.860 0.080 230); --accent-foreground: var(--eclipse); /* Status */ --success: oklch(0.7329 0.1935 150.81); --success-foreground: var(--eclipse); --warning: oklch(0.8203 0.1388 76.34); --warning-foreground: var(--eclipse); --danger: oklch(0.594 0.1967 24.63); --danger-foreground: var(--snow); /* Component Colors */ --segment: oklch(0.3964 0.01 285.93); --segment-foreground: var(--foreground); /* Misc */ --border: oklch(22% 0.006 286.033); --separator: oklch(22% 0.006 286.033); --focus: var(--accent); --link: var(--accent); /* Shadows */ --surface-shadow: 0 0 0 0 transparent inset; --overlay-shadow: 0 0 0 0 transparent inset; --field-shadow: 0 0 0 0 transparent inset; } } ``` 使用你的主题: ```css /* app/globals.css */ @layer theme, base, components, utilities; @import "tailwindcss"; @import "@heroui/styles"; @import "./src/themes/ocean.css" layer(theme); /* [!code highlight]*/ ``` 应用你的主题: ```html ``` ## 自定义组件 **全局组件样式:** 使用 BEM 类覆盖任何组件: ```css @layer components { /* Customize buttons */ .button { @apply font-semibold tracking-wide; } .button--primary { @apply bg-blue-600 hover:bg-blue-700; } /* Customize accordions */ .accordion__trigger { @apply text-lg font-bold; } } ``` > **注意**:完整的样式参考请参见 [样式](/docs/handbook/styling)。 **查找组件类名:** 每个组件文档页面都会列出所有可用的类名(基类、修饰符、元素、状态)。示例:[Button 类名](/docs/components/button#css-classes) ## 导入策略 **完整导入(推荐):** 两行代码即可获得全部内容: ```css @import "tailwindcss"; @import "@heroui/styles"; ``` **按需导入:** 只导入你需要的内容: ```css /* Define layers */ @layer theme, base, components, utilities; /* Base requirements */ @import "tailwindcss"; @import "@heroui/styles/base" layer(base); /* OR specific base file */ @import "@heroui/styles/base/base.css" layer(base); /* Theme variables */ @import "@heroui/styles/themes/shared/theme.css" layer(theme); @import "@heroui/styles/themes/default" layer(theme); /* OR specific theme files */ @import "@heroui/styles/themes/default/index.css" layer(theme); @import "@heroui/styles/themes/default/variables.css" layer(theme); /* Components (all components) */ @import "@heroui/styles/components" layer(components); /* OR specific component files */ @import "@heroui/styles/components/index.css" layer(components); @import "@heroui/styles/components/button.css" layer(components); @import "@heroui/styles/components/accordion.css" layer(components); /* Utilities (optional) */ @import "@heroui/styles/utilities" layer(utilities); /* Variants (optional) */ @import "@heroui/styles/variants" layer(utilities); ``` > **注意**:目录导入(例如 `@heroui/styles/components`)会自动解析为其对应的 `index.css` 文件。使用显式文件路径(例如 `@heroui/styles/components/button.css`)来导入单个组件的样式。 **Headless 模式:** 从头开始构建你自己的样式: ```css @import "tailwindcss"; @import "@heroui/styles/base/base.css"; /* Your custom styles */ .button { /* Your button styles */ } ``` ## 添加自定义颜色 将你自己的语义化颜色添加到主题中: ```css /* Define in both light and dark themes */ :root, [data-theme="light"] { --info: oklch(0.6 0.15 210); --info-foreground: oklch(0.98 0 0); } .dark, [data-theme="dark"] { --info: oklch(0.7 0.12 210); --info-foreground: oklch(0.15 0 0); } /* Make the color available to Tailwind */ @theme inline { --color-info: var(--info); --color-info-foreground: var(--info-foreground); } ``` 现在你可以在组件中使用它: ```tsx
Info message
``` ## 变量参考 HeroUI 在 [`variables.css`](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css) 中定义了三种类型的变量: 1. **基础变量(Base Variables)** — 不会变化的值,例如 `--white`、`--black`、间距以及排版 2. **主题变量(Theme Variables)** — 在浅色 / 深色主题之间切换的颜色,以及滚动条令牌(`--scrollbar-thumb`、`--scrollbar-width` 等) 3. **计算变量(Calculated Variables)** — 悬停状态、柔和(soft)变体以及边框 / 分隔线层级(每个浅色 / 深色主题中的 **Calculated Colors** 区块,使用 `color-mix()` 计算) 如需完整参考,请查阅:[颜色文档](/docs/handbook/colors)、[默认主题变量](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css)、[共享主题工具](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/shared/theme.css) **Tailwind 主题桥接(`@theme inline`):** [`themes/shared/theme.css`](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/shared/theme.css) 将语义化变量映射为 Tailwind 令牌(`--color-*`、`--radius-*`、`--ease-*`)。计算颜色引用的是 `variables.css` 中的底层变量(例如 `--surface-hover`、`--accent-soft`)—— 它们并不会在该文件中通过 `color-mix()` 内联展开: ```css @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-surface: var(--surface); --color-surface-foreground: var(--surface-foreground); --color-surface-hover: var(--surface-hover); --color-surface-secondary: var(--surface-secondary); --color-surface-secondary-foreground: var(--surface-secondary-foreground); --color-surface-tertiary: var(--surface-tertiary); --color-surface-tertiary-foreground: var(--surface-tertiary-foreground); --color-overlay: var(--overlay); --color-overlay-foreground: var(--overlay-foreground); --color-muted: var(--muted); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-segment: var(--segment); --color-segment-foreground: var(--segment-foreground); --color-border: var(--border); --color-separator: var(--separator); --color-focus: var(--focus); --color-link: var(--link); --color-default: var(--default); --color-default-foreground: var(--default-foreground); --color-success: var(--success); --color-success-foreground: var(--success-foreground); --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); --color-danger: var(--danger); --color-danger-foreground: var(--danger-foreground); --color-backdrop: var(--backdrop); --shadow-surface: var(--surface-shadow); --shadow-overlay: var(--overlay-shadow); --shadow-field: var(--field-shadow); /* 表单字段令牌 */ --color-field: var(--field-background, var(--default)); --color-field-hover: var(--field-hover); --color-field-foreground: var(--field-foreground, var(--foreground)); --color-field-placeholder: var(--field-placeholder, var(--muted)); --color-field-border: var(--field-border, var(--border)); --radius-field: var(--field-radius, calc(var(--radius) * 1.5)); --border-width-field: var(--field-border-width, var(--border-width)); /* 颜色令牌 */ --color-background-secondary: var(--background-secondary); --color-background-tertiary: var(--background-tertiary); --color-background-inverse: var(--background-inverse); --color-default-hover: var(--default-hover); --color-accent-hover: var(--accent-hover); --color-success-hover: var(--success-hover); --color-warning-hover: var(--warning-hover); --color-danger-hover: var(--danger-hover); /* 表单字段颜色 */ --color-field-focus: var(--field-focus); --color-field-border-hover: var(--field-border-hover); --color-field-border-focus: var(--field-border-focus); /* 柔和(Soft)颜色 */ --color-default-soft: var(--default-soft); --color-default-soft-foreground: var(--default-soft-foreground); --color-default-soft-hover: var(--default-soft-hover); --color-accent-soft: var(--accent-soft); --color-accent-soft-foreground: var(--accent-soft-foreground); --color-accent-soft-hover: var(--accent-soft-hover); --color-danger-soft: var(--danger-soft); --color-danger-soft-foreground: var(--danger-soft-foreground); --color-danger-soft-hover: var(--danger-soft-hover); --color-warning-soft: var(--warning-soft); --color-warning-soft-foreground: var(--warning-soft-foreground); --color-warning-soft-hover: var(--warning-soft-hover); --color-success-soft: var(--success-soft); --color-success-soft-foreground: var(--success-soft-foreground); --color-success-soft-hover: var(--success-soft-hover); /* 分隔线颜色 - 层级 */ --color-separator-secondary: var(--separator-secondary); --color-separator-tertiary: var(--separator-tertiary); /* 边框颜色 - 层级 */ --color-border-secondary: var(--border-secondary); --color-border-tertiary: var(--border-tertiary); /* 圆角与默认尺寸 - 只需更改 --radius 即可调整默认值 */ --radius-xs: calc(var(--radius) * 0.25); /* 0.125rem (2px) */ --radius-sm: calc(var(--radius) * 0.5); /* 0.25rem (4px) */ --radius-md: calc(var(--radius) * 0.75); /* 0.375rem (6px) */ --radius-lg: calc(var(--radius) * 1); /* 0.5rem (8px) */ --radius-xl: calc(var(--radius) * 1.5); /* 0.75rem (12px) */ --radius-2xl: calc(var(--radius) * 2); /* 1rem (16px) */ --radius-3xl: calc(var(--radius) * 3); /* 1.5rem (24px) */ --radius-4xl: calc(var(--radius) * 4); /* 2rem (32px) */ /* 过渡缓动函数 */ --ease-smooth: ease; /* 等同于 transition: ease; */ /* 这些自定义曲线由 https://twitter.com/bdc 制作 */ /* 由平缓到快速 */ --ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53); --ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19); --ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22); --ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06); --ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035); --ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335); /* 由慢到快 */ --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94); --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1); --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1); --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1); --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1); --ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1); /* 自定义的平滑收尾曲线:快速启动、平滑结束 —— Apple 风格 */ --ease-out-fluid: cubic-bezier(0.32, 0.72, 0, 1); /* 由慢到快 */ --ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955); --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1); --ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1); --ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1); --ease-in-out-expo: cubic-bezier(1, 0, 0, 1); --ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86); /* 线性 */ --ease-linear: linear; /* 动画 */ --animate-spin-fast: spin 0.75s linear infinite; --animate-skeleton: skeleton 2s linear infinite; --animate-caret-blink: caret-blink 1.2s ease-out infinite; @keyframes skeleton { 100% { transform: translateX(200%); } } @keyframes caret-blink { 0%, 70%, 100% { opacity: 1; } 20%, 50% { opacity: 0; } } } ``` 表单控件依赖 `--field-*` 主题变量。悬停、聚焦及边框变体定义于 `variables.css` 的 **Calculated Colors** 区块中,并在 `theme.css` 中映射到 Tailwind 令牌(例如 `--color-field-hover: var(--field-hover)`)。在你的主题中覆盖 `--field-background`、`--field-hover` 及相关令牌,即可重新设计输入框、复选框、单选框和 OTP 输入槽的样式,而不会影响按钮或卡片等表面(surface)。 ## 滚动条 HeroUI 为组件中的滚动区域(表格、弹出框、抽屉等)应用统一的滚动条样式。滚动条使用标准 CSS 属性(`scrollbar-width`、`scrollbar-color`、`scrollbar-gutter`),不再依赖 `::-webkit-scrollbar` 覆盖。 **模式** — 在 ``、组件根元素或滚动插槽上设置 `data-scrollbar`: | 模式 | `data-scrollbar` | 行为 | | ---------- | ---------------- | ------------------------------- | | HeroUI 纤细 | *(未设置)* 或 `thin` | 使用主题令牌呈现的纤细滑块 | | 操作系统 / 浏览器 | `default` | 原生滚动条(`auto`) | | 隐藏 | `none` | 不显示滚动条(`scrollbar-width: none`) | ```html
...
...
``` **主题变量** — 在 [`variables.css`](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css) 的浅色与深色主题区块中定义: | 变量 | 描述 | | -------------------- | ---------------------------------------------- | | `--scrollbar-thumb` | 滑块颜色(默认通过 `color-mix` 混入 15% 的 `--foreground`) | | `--scrollbar-track` | 轨道颜色(默认 `transparent`) | | `--scrollbar-gutter` | 滚动条间隙(默认 `auto`) | | `--scrollbar-width` | `scrollbar-width` 属性(默认 `thin`) | | `--scrollbar-color` | `scrollbar-color` 属性(默认为滑块颜色 + 轨道颜色) | | `--scrollbar` | `--scrollbar-thumb` 的旧版别名 | **全局自定义:** ```css /* app/globals.css */ :root { --scrollbar-thumb: color-mix(in oklch, var(--accent) 30%, transparent); --scrollbar-gutter: auto; } ``` **按滚动插槽** — 在组件上传入 `data-scrollbar`,或在外层包裹元素上覆盖相关令牌: ```tsx ...
``` **自定义溢出区域** — 在自己的元素上使用 `@heroui/styles` 提供的 `scrollbar`、`scrollbar-thin`、`scrollbar-default` 或 `scrollbar-none` 工具类。基于类的覆盖方式详见 [样式](/docs/handbook/styling)。 > **注意**:部分组件默认隐藏滚动条(日期选择器弹出框、颜色选择器、次级标签页)。嵌套的滚动插槽(例如日期选择器内部的日历年份选择器)会保留 HeroUI 滚动条,因为 `scrollbar-none` 只作用于其所在的元素本身,不会影响使用 `@apply scrollbar` 的后代元素。 ## 资源 * [颜色文档](/docs/handbook/colors) * [样式指南](/docs/handbook/styling) * [Tailwind CSS v4 主题](https://tailwindcss.com/docs/theme) * [BEM 方法论](https://getbem.com/) * [OKLCH 颜色工具](https://oklch.com)
# 命令行 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/cli **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(overview)/cli.mdx > 使用命令行管理 HeroUI 依赖并初始化项目。 `heroui-cli`是官方命令行工具,提供了一整套命令,用于初始化、管理和优化你的 HeroUI 项目。你可以 `install`、`uninstall` 或 `upgrade` 单个组件,检查项目健康状况,下载用于 AI 编程助手的文档,等等。 ## 安装 环境要求: * [Node.js 22.22.0 或更高版本](https://nodejs.org/en/) ### 全局安装 要全局安装 `heroui-cli`,请在终端中执行以下命令之一: npm pnpm yarn bun ```bash npm install heroui-cli@latest -g ``` ```bash pnpm add heroui-cli@latest -g ``` ```bash yarn global add heroui-cli@latest ``` ```bash bun add heroui-cli@latest --global ``` ### 无需安装直接使用 或者,你也可以在不进行全局安装的情况下使用 `heroui-cli`,运行以下命令之一即可: ```bash pnpm dlx heroui-cli@latest ``` ```bash npx heroui-cli@latest ``` ```bash yarn dlx heroui-cli@latest ``` ```bash bunx heroui-cli@latest ``` ## 快速开始 安装 `heroui-cli` 后,运行以下命令以查看可用命令: ```bash heroui ``` 将会输出如下帮助信息: ```bash Usage: heroui [command] Options: -v, --version Output the current version --no-cache Disable cache, by default data will be cached for 30m after the first request -d, --debug Debug mode will not install dependencies -h --help Display help information for commands Commands: init [options] [projectName] Initializes a new project install [options] Installs @heroui/react and @heroui/styles to your project upgrade [options] Upgrades @heroui/react and @heroui/styles to the latest versions uninstall [options] Uninstall @heroui/react and @heroui/styles from the project list [options] Lists installed HeroUI packages (@heroui/react, @heroui/styles) env [options] Displays debugging information for the local environment doctor [options] Checks for issues in the project agents-md [options] Downloads HeroUI documentation for AI coding agents help [command] Display help for command ``` ### init 使用 `init` 命令初始化一个新的 HeroUI 项目。该命令会为你的项目完成必要的配置。 ```bash heroui init [options] ``` **选项:** * `-t --template [string]` 新项目使用的模板,例如 app、pages、vite、react-router * `-p --package [string]` 新项目使用的包管理器 输出: ```bash HeroUI CLI ┌ Create a new project │ ◇ Select a template (Enter to select) │ ● App (A Next.js 16 with app directory template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ○ Pages (A Next.js 16 with pages directory template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ○ Vite (A Vite template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ○ React Router (A React Router template pre-configured with HeroUI (v3) and Tailwind CSS.) │ ◇ New project name (Enter to skip with default name) │ my-heroui-app │ ◇ Select a package manager (Enter to select) │ ● npm │ ○ yarn │ ○ pnpm │ ○ bun │ ◇ Template created successfully! │ ◇ Next steps ───────╮ │ │ │ cd my-heroui-app │ │ npm install │ │ │ ├────────────────────╯ │ └ 🚀 Get started with npm run dev ``` 安装依赖以启动本地服务器: ```bash cd my-heroui-app && npm install ``` ```bash cd my-heroui-app && pnpm install ``` ```bash cd my-heroui-app && yarn install ``` ```bash cd my-heroui-app && bun install ``` 启动本地服务器: npm pnpm yarn bun ```bash npm run dev ``` ```bash pnpm run dev ``` ```bash yarn dev ``` ```bash bun run dev ``` ### Install 将 `@heroui/react` 和 `@heroui/styles` 及其对等依赖安装到你的项目中。若它们已安装,则该命令不会执行任何操作。 ```bash heroui install [options] ``` **选项:** * `-p --packagePath` \[string] package.json 文件的路径 **输出:** ```bash HeroUI CLI 📦 Packages to be installed: ╭─────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │─────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 │ stable │ https://heroui.com │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭─────────────── PeerDependencies ────────────────╮ │ react@18.3.1 latest │ │ react-dom@18.3.1 latest │ │ tailwindcss@4.2.2 latest │ ╰─────────────────────────────────────────────────╯ ? Proceed with installation? › - Use arrow-keys. Return to submit. ❯ Yes No ✅ @heroui/react and @heroui/styles installed successfully ``` ### upgrade 将 `@heroui/react` 和 `@heroui/styles` 及其对等依赖升级到最新版本。 ```bash heroui upgrade [options] ``` **选项:** * `-p --packagePath` \[string] package.json 文件的路径 **输出:** ```bash HeroUI CLI ╭──────────────────────────── Upgrade ────────────────────────────╮ │ @heroui/react ^3.0.0 -> ^3.1.0 │ │ @heroui/styles ^3.0.0 -> ^3.1.0 │ ╰─────────────────────────────────────────────────────────────────╯ ? Would you like to proceed with the upgrade? › - Use arrow-keys. Return to submit. ❯ Yes No ✅ Upgrade complete. All packages are up to date. ``` ### uninstall 从你的项目中卸载 `@heroui/react` 和 `@heroui/styles`。对等依赖不会被卸载。 ```bash heroui uninstall [options] ``` **选项:** * `-p --packagePath` \[string] package.json 文件的路径 **输出:** ```bash HeroUI CLI ❗️ Packages slated for uninstallation: ╭──────────────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │──────────────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 │ stable │ https://heroui.com │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ? Confirm uninstallation of these packages: › - Use arrow-keys. Return to submit. ❯ Yes No ✅ Successfully uninstalled: @heroui/react, @heroui/styles ``` ### list 列出已安装的 HeroUI 包(`@heroui/react`、`@heroui/styles`)。 ```bash heroui list [options] ``` **选项:** * `-p --packagePath` \[string] package.json 文件的路径 **输出:** ```bash HeroUI CLI Current installed packages: ╭──────────────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │──────────────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 🚀latest │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 🚀latest │ stable │ https://heroui.com │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ``` ### doctor 检查项目中存在的问题。 * 检查 `@heroui/react` 和 `@heroui/styles` 是否已安装 * 检查项目中是否安装了所需的 `对等依赖` 并满足最低版本要求 ```bash heroui doctor [options] ``` **选项:** * `-p --packagePath` \[string] package.json 文件的路径 **输出:** 如果项目中存在问题,`doctor` 命令将显示问题信息。 ```bash HeroUI CLI HeroUI CLI: ❌ Your project has 1 issue that require attention ❗️Issue 1: missingHeroUIPackages The following HeroUI packages are not installed: - @heroui/styles Run `heroui install` to install them. ``` 否则,`doctor` 命令将显示以下消息。 ```bash HeroUI CLI ✅ Your project has no detected issues. ``` ### env 显示本地环境的调试信息。 ```bash heroui env [options] ``` **选项:** * `-p --packagePath` \[string] package.json 文件的路径 **输出:** ```bash HeroUI CLI Current installed packages: ╭──────────────────────────────────────────────────────────────────────────────────────╮ │ Package │ Version │ Status │ Docs │ │──────────────────────────────────────────────────────────────────────────────────────│ │ @heroui/react │ 3.0.0 🚀latest │ stable │ https://heroui.com │ │ @heroui/styles │ 3.0.0 🚀latest │ stable │ https://heroui.com │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ Environment Info: System: OS: darwin CPU: arm64 Binaries: Node: v25.8.1 ``` ### agents-md 下载用于 AI 编程助手(Claude、Cursor 等)的 HeroUI 文档。该命令会从 HeroUI 仓库克隆最新文档,并将一份精简索引注入到 `AGENTS.md` 或 `CLAUDE.md` 中,方便助手参考你项目中的 HeroUI 配置。 ```bash heroui agents-md [options] ``` **选项:** * `--react` \[boolean] 仅包含 React 文档(一次只能选择一个文档库) * `--native` \[boolean] 仅包含 Native 文档 * `--migration` \[boolean] 仅包含 HeroUI v2 到 v3 的迁移文档 * `--output ` \[string] 目标文件路径(例如 `AGENTS.md`、`CLAUDE.md`) * `--ssh` \[boolean] 使用 SSH 而非 HTTPS 进行 git clone **示例:** 不带任何标志运行以进入交互模式: ```bash heroui agents-md ``` 将 React 文档下载到指定文件: ```bash heroui agents-md --react --output AGENTS.md ``` 下载 Native 或迁移文档: ```bash heroui agents-md --native --output CLAUDE.md heroui agents-md --migration --output AGENTS.md ``` **工作原理:** 1. 使用 git sparse-checkout 从 `v3` 分支克隆文档 2. 生成文档和示例文件的精简索引 3. 将该索引注入到你的 markdown 文件中,置于标记之间(`` / ``,Native 和 Migration 也有类似的标记) 4. 将 `.heroui-docs/` 添加到 `.gitignore` `--react`、`--native` 和 `--migration` 一次只能选择其中一个。 更多详情请参阅 [AGENTS.md](/docs/react/getting-started/agents-md)。 `agents-md` 命令会收集匿名使用数据(所选项、输出文件名、耗时、成功或错误)。设置 `HEROUI_ANALYTICS_DISABLED=1` 可以选择不参与。 ## 问题反馈 如果你发现了 bug,请在 [heroui-cli Issues](https://github.com/heroui-inc/heroui-cli/issues) 中报告。 # 设计原则 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/design-principles **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(overview)/design-principles.mdx > 指导 HeroUI v3 设计和开发的核心原则 HeroUI v3 遵循 10 项核心原则,注重清晰度、无障碍、可定制性以及开发者体验。 ## 核心原则 ### 1. 语义意图优于视觉风格 使用语义命名(primary、secondary、tertiary),而非视觉描述(solid、flat、bordered)。灵感来自 [Uber 的 Base 设计系统](https://base.uber.com/6d2425e9f/p/756216-button),变体遵循清晰的层次结构: ```tsx // ✅ Semantic variants communicate hierarchy ``` | 变体 | 用途 | 使用方式 | | ------------- | ----------- | -------- | | **Primary** | 推进流程的主要操作 | 每种场景 1 个 | | **Secondary** | 备选操作 | 可使用多个 | | **Tertiary** | 次要操作(取消、跳过) | 谨慎使用 | | **Danger** | 破坏性操作 | 需要时使用 | ### 2. 无障碍是基础 基于 [React Aria Components](https://react-spectrum.adobe.com/react-aria/) 构建,符合 WCAG 2.1 AA 标准。内置自动 ARIA 属性、键盘导航与屏幕阅读器支持。 ```tsx import { Tabs, TabList, Tab, TabPanel } from '@heroui/react'; Profile Security Content Content ``` ### 3. 组合优于配置 复合组件允许你按需重新组合、自定义或省略其中的各个部分。可以使用点号语法、命名导出,或两者混合使用。 ```tsx // Compose parts to build exactly what you need import { Accordion, AccordionItem, AccordionHeading, AccordionTrigger, AccordionIndicator, AccordionPanel, AccordionBody } from '@heroui/react'; Question Text Answer content ``` ### 4. 渐进式呈现 从简单开始,仅在需要时才增加复杂度。组件只需最少的 props 即可工作,并能随需求增长而扩展。 ```tsx // Level 1: Minimal // Level 2: Enhanced // Level 3: Advanced ``` ### 5. 可预测的行为 所有组件遵循一致的模式:尺寸(`sm`、`md`、`lg`)、变体、`className` 支持以及 data 属性。相同的 API,相同的行为。 ```tsx // All components follow the same patterns ``` 或与 React 一同使用: ```tsx // Apply styles to any component import { buttonVariants } from '@heroui/styles'; Home ``` ### 8. 卓越的开发者体验 清晰的 API、富含信息的错误提示、IntelliSense、对 AI 友好的 Markdown 文档,以及用于可视化测试的 Storybook。 ### 9. 完全可定制 开箱即用的精美默认样式。使用 CSS 变量或 [BEM](https://getbem.com/) 类即可彻底改变整体外观。每一个插槽都可定制。 ```css /* 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 类,或创建自定义的包装组件。 **使用变体函数应用样式:** ```tsx 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" }); About Page ``` **直接应用 BEM 类:** ```tsx import Link from 'next/link'; // Apply HeroUI's BEM classes directly to any element Dashboard ``` **创建自定义包装组件:** ```tsx // Custom wrapper component const CTAButton = ({ intent = 'primary-cta', children, ref, ...props }: CTAButtonProps) => { const variantMap = { 'primary-cta': 'primary', 'secondary-cta': 'secondary', 'minimal': 'ghost' }; return ( ); }; ``` **使用 Tailwind Variants 扩展:** ```tsx 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 ); } ``` 示例:`pages/index.tsx` ```tsx import {Button} from "@heroui/react"; export default function HomePage() { return (
); } ```
HeroUI v3 无需 Provider。安装并导入样式后,组件即可直接使用。 ### 3. 区域设置(可选) 为了与 Next.js 集成,请确保服务端的区域设置与客户端一致。 在根布局中,确定用户的首选语言,并在 `` 元素上设置 `lang` 和 `dir` 属性。 ```tsx // app/layout.tsx import {headers} from 'next/headers'; import {isRTL} from '@heroui/react'; import {ClientProviders} from './provider'; export default async function RootLayout({children}) { // Get the user's preferred language from the Accept-Language header. // You could also get this from a database, URL param, etc. const acceptLanguage = (await headers()).get('accept-language'); const lang = acceptLanguage?.split(/[,;]/)[0] || 'en-US'; return ( {children} ); } ``` 创建 `app/provider.tsx`,其中应渲染一个 `I18nProvider`,用于设置 React Aria 所使用的区域设置。 ```tsx // app/provider.tsx "use client"; import {I18nProvider} from '@heroui/react'; export function ClientProviders({lang, children}) { return ( {children} ); } ``` 如果你使用了带 nonce 的 [内容安全策略](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP)(CSP),请在文档的 head 中添加 `` 标签,并将其 content 属性设置为生成的 nonce 值。React Aria 会自动从该标签读取 nonce。 ## Vite ### 1. 创建 Vite 项目 ```bash npx heroui-cli@latest init ``` 当出现提示时,选择 **Vite** 模板。然后进入新创建的文件夹并安装依赖(例如 `pnpm install`)。 ### 2. 使用你的第一个 HeroUI 组件 示例:`src/App.tsx` ```tsx import {Button} from "@heroui/react"; function App() { return (
); } export default App; ``` HeroUI v3 无需 Provider。安装并导入样式后,组件即可直接使用。 ## 下一步 * [快速入门](/docs/react/getting-started/quick-start) — 最快上手的方式 * [主题](/docs/react/getting-started/theming) — 自定义颜色和设计令牌 * [组件](/docs/react/components) — 探索所有可用的组件
# 快速入门 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/quick-start **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(overview)/quick-start.mdx > 只需几分钟即可开始使用 HeroUI v3 ## 环境要求 * [React 19+](https://reactjs.org/) * [Tailwind CSS v4](https://tailwindcss.com/docs/installation/framework-guides) ## 快速安装 \` 作为最小冒烟测试,确认样式已正确生效。 完成后,请总结你做出的变更,并告诉我如何启动开发服务器。`} > **想让 AI 助手代劳?** 在你的编辑器中安装 [HeroUI MCP Server](/docs/react/getting-started/mcp-server),然后把上面的提示词粘贴给 AI 助手——它会分析你的项目并自动完成全部配置。 安装 HeroUI 及其所需依赖: ```bash npm i @heroui/styles @heroui/react ``` ```bash pnpm add @heroui/styles @heroui/react ``` ```bash yarn add @heroui/styles @heroui/react ``` ```bash bun add @heroui/styles @heroui/react ``` ## 导入样式 将以下内容添加到你的主 CSS 文件 `globals.css`: ```css @import "tailwindcss"; @import "@heroui/styles"; /* [!code highlight]*/ ``` 导入顺序很重要。请务必先导入 `tailwindcss`。 ## 使用组件 ```tsx import { Button } from '@heroui/react'; function App() { return ( ); } ``` ## 下一步 * [主题](/themes) — 创建并分享你自己的主题 * [浏览组件](/docs/react/components) — 查看所有可用的组件 * [学习样式](/docs/handbook/styling) — 使用 Tailwind CSS 进行自定义 * [探索组合模式](/docs/handbook/composition) — 掌握复合组件 # Agent Skills **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/agent-skills **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(ui-for-agents)/agent-skills.mdx > 让 AI 助手能够使用 HeroUI v3 组件来构建 UI HeroUI Skills 为你的 AI 助手提供关于 HeroUI v3 组件、模式与最佳实践的全面知识。 ### 安装 ```bash curl -fsSL https://heroui.com/install | bash -s heroui-react ``` 或者使用 skills 包: ```bash npx skills add heroui-inc/heroui ``` 支持 Claude Code、Cursor、OpenCode 等。 ### 使用方法 Skills 会被你的 AI 助手 **自动发现**,你也可以通过 `/heroui-react` 命令直接调用。 只需让你的 AI 助手: * 使用 HeroUI v3 构建组件 * 使用 HeroUI 组件创建页面 * 自定义主题和样式 * 查阅组件文档 对于更复杂的使用场景,请使用 [MCP 服务器](/docs/react/getting-started/mcp-server),它提供对组件文档与源代码的实时访问。 ### 包含的内容 * HeroUI v3 安装指南 * 所有 HeroUI v3 组件,包含 props、示例与使用模式 * 主题与样式指南 * 设计原则与组合模式 ### 结构 ``` skills/heroui-react/ ├── SKILL.md # Main skill documentation ├── LICENSE.txt # Apache License 2.0 └── scripts/ # Utility scripts ├── list_components.mjs ├── get_component_docs.mjs ├── get_source.mjs ├── get_styles.mjs ├── get_theme.mjs └── get_docs.mjs ``` ### 相关文档 * [Agent Skills 规范](https://agentskills.io/home) — 了解 Agent Skills 的格式 * [Claude Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) — Claude 的 Skills 文档 * [Cursor Skills](https://cursor.com/docs/context/skills) — 在 Cursor 中使用 Skills * [OpenCode Skills](https://opencode.ai/docs/skills) — 在 OpenCode 中使用 Skills # AGENTS.md **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/agents-md **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(ui-for-agents)/agents-md.mdx > 为 AI 编码代理下载 HeroUI v3 React 文档 将 HeroUI v3 React 文档直接下载到你的项目中,供 AI 助手参考。 **注意:** `agents-md` 命令专门用于 HeroUI React v3。其他 CLI 命令(如 `add`、`init`、`upgrade` 等)目前仍用于 HeroUI v2。 ### 用法 ```bash npx heroui-cli@latest agents-md --react ``` 或者指定输出文件: ```bash npx heroui-cli@latest agents-md --react --output AGENTS.md ``` ### 功能说明 * 将最新的 HeroUI v3 React 文档下载到 `.heroui-docs/react/` * 在 `AGENTS.md` 或 `CLAUDE.md` 中生成索引 * 包含用于代码示例的 demo 文件 * 自动将 `.heroui-docs/` 添加到 `.gitignore` ### 选项 * `--react` — 仅下载 React 文档 * `--output ` — 目标文件(例如 `AGENTS.md`,或 `AGENTS.md CLAUDE.md`) * `--ssh` — 使用 SSH 进行 git clone ### 环境要求 * Tailwind CSS >= v4 * React >= 19.0.0 * `@heroui/react >= 3.0.0` 或 `@latest` ### 相关文档 * [AGENTS.md](https://agents.md/) — 了解面向编码代理的 AGENTS.md 格式 * [CLAUDE.md](https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md) — Claude 对应版本的 AGENTS.md * [AGENTS.md vs Skills](https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals) — AGENTS.md 的性能表现 # LLMs.txt **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/llms-txt **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(ui-for-agents)/llms-txt.mdx > 让 Claude、Cursor、Windsurf 等 AI 助手理解 HeroUI v3 我们提供 [LLMs.txt](https://llmstxt.org/) 文件,让 AI 编码助手可以访问 HeroUI v3 文档。 ## 可用文件 **核心文档:** * [/react/llms.txt](/react/llms.txt) — React 文档的快速参考索引 * [/react/llms-full.txt](/react/llms-full.txt) — 完整的 HeroUI React 文档 **适用于上下文窗口有限的场景:** * [/react/llms-components.txt](/react/llms-components.txt) — 仅包含组件文档 * [/react/llms-patterns.txt](/react/llms-patterns.txt) — 常见模式与代码片段 **全平台:** * [/llms.txt](/llms.txt) — 快速参考索引(React + Native) * [/llms-full.txt](/llms-full.txt) — 完整文档(React + Native) * [/llms-components.txt](/llms-components.txt) — 全部组件文档 * [/llms-patterns.txt](/llms-patterns.txt) — 全部模式与代码片段 ## 集成 **Claude Code:** 让 Claude 参考文档: ``` Use HeroUI React documentation from https://heroui.com/react/llms.txt ``` 或者添加到你项目中的 `.claude` 文件以自动加载。 **Cursor:** 使用 `@Docs` 功能: ``` @Docs https://heroui.com/react/llms-full.txt ``` [了解更多](https://docs.cursor.com/context/@-symbols/@-docs) **Windsurf:** 添加到你的 `.windsurfrules` 文件: ``` #docs https://heroui.com/react/llms-full.txt ``` [了解更多](https://docs.codeium.com/windsurf/memories#memories-and-rules) **其他 AI 工具:** 大多数 AI 助手都可以通过 URL 引用文档。只需提供: ``` https://heroui.com/react/llms.txt ``` **针对特定组件的文档:** ``` https://heroui.com/react/llms-components.txt ``` **针对模式与最佳实践:** ``` https://heroui.com/react/llms-patterns.txt ``` ## 参与贡献 发现 AI 生成的代码有问题?欢迎在 [GitHub](https://github.com/heroui-inc/heroui) 上帮助我们改进 LLMs.txt 文件。 # MCP 服务器 **Category**: react **URL**: https://heroui.com/cn/docs/react/getting-started/mcp-server **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/react/getting-started/(ui-for-agents)/mcp-server.mdx > 直接在你的 AI 助手中访问 HeroUI v3 文档 HeroUI MCP 服务器让 AI 助手可以直接访问 HeroUI v3 组件文档,从而更轻松地在 AI 驱动的开发环境中使用 HeroUI 进行构建。 MCP 服务器目前仅支持 **@heroui/react v3**,并使用 [stdio 传输](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio)。已在 npm 上以 `@heroui/react-mcp` 发布。源代码请查看 [GitHub](https://github.com/heroui-inc/heroui-mcp)。 随着我们向 HeroUI v3 添加更多组件,它们也将在 MCP 服务器中可用。 ## 快速设置 ### Cursor
Install in Cursor
或者手动添加到 **Cursor Settings** → **Tools** → **MCP Servers**: ```json title=".cursor/mcp.json" { "mcpServers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` 或者,将以下内容添加到你的 `~/.cursor/mcp.json` 文件。更多信息请参阅 [Cursor 文档](https://cursor.com/docs/context/mcp)。 ### Claude Code 在终端中运行此命令: ```bash claude mcp add heroui-react -- npx -y @heroui/react-mcp@latest ``` 或者手动添加到你项目的 `.mcp.json` 文件: ```json title=".mcp.json" { "mcpServers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` 添加配置后,重启 Claude Code 并运行 `/mcp`,即可在列表中看到 HeroUI MCP 服务器。如果你看到 **Connected**,就可以开始使用了。 更多详情请参阅 [Claude Code MCP 文档](https://docs.claude.com/en/docs/claude-code/mcp)。 ### Windsurf 将 HeroUI 服务器添加到你项目的 `.windsurf/mcp.json` 配置文件: ```json title=".windsurf/mcp.json" { "mcpServers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` 添加配置后,重新启动 Windsurf 以激活 MCP 服务器。 更多详情请参阅 [Windsurf MCP 文档](https://docs.windsurf.com/windsurf/cascade/mcp)。 ### Zed 将 HeroUI 服务器添加到你的 `settings.json` 配置文件。通过命令面板打开设置(`zed: open settings`),或使用 `Cmd-,`(Mac)/ `Ctrl-,`(Linux): ```json title="settings.json" { "context_servers": { "heroui-react": { "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"], "env": {} } } } ``` 添加配置后,重新启动 Zed 并打开 Agent Panel 设置视图。检查 heroui 服务器旁边的指示点是否为绿色,且 tooltip 显示为 "Server is active"。 更多详情请参阅 [Zed MCP 文档](https://zed.dev/docs/ai/mcp)。 ### VS Code 要在 VS Code 中通过 GitHub Copilot 配置 MCP,请将 HeroUI 服务器添加到项目的 `.vscode/mcp.json` 配置文件: ```json title=".vscode/mcp.json" { "servers": { "heroui-react": { "type": "stdio", "command": "npx", "args": ["-y", "@heroui/react-mcp@latest"] } } } ``` 添加配置后,打开 `.vscode/mcp.json`,然后点击 heroui-react 服务器旁边的 **Start**。 更多详情请参阅 [VS Code MCP 文档](https://code.visualstudio.com/docs/copilot/customization/mcp-servers)。 ### Codex 将 HeroUI 服务器添加到你的 `~/.codex/config.toml`(或项目级的 `.codex/config.toml`): ```toml title="config.toml" [mcp_servers.heroui-react] command = "npx" args = ["-y", "@heroui/react-mcp@latest"] ``` 添加配置后,重启 Codex 并在 TUI 中运行 `/mcp`,以验证服务器是否处于活动状态。 更多详情请参阅 [Codex MCP 文档](https://developers.openai.com/codex/mcp)。 ### OpenCode 将 HeroUI 服务器添加到你项目的 `opencode.json` 配置文件: ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", "mcp": { "heroui-react": { "type": "local", "command": ["npx", "-y", "@heroui/react-mcp@latest"] } } } ``` 添加配置后,重新启动 OpenCode 以激活 MCP 服务器。 更多详情请参阅 [OpenCode MCP 文档](https://open-code.ai/docs/en/mcp-servers)。 ## 用法 配置完成后,可以这样询问你的 AI 助手: * “帮我在 Next.js / Vite / Astro 应用中安装 HeroUI v3” * “显示所有 HeroUI 组件” * “Button 组件有哪些 props?” * “给我一个使用 Card 组件的示例” * “获取 Button 组件的源代码” * “显示 Card 组件的 CSS 样式” * “深色模式下有哪些主题变量?” ### 自动更新 MCP 服务器可以帮助你升级到最新的 HeroUI 版本: ```bash "Hey Cursor, update HeroUI to the latest version" ``` 你的 AI 助手会自动完成以下事项: * 将你当前的版本与最新发布的版本进行比较 * 查看变更日志,了解破坏性变更 * 将必要的代码更新应用到你的项目中 无论是更新到最新的稳定版还是预发布版,这一流程都适用于任何版本升级。 ## 可用工具 MCP 服务器为 AI 助手提供以下工具: | 工具 | 描述 | | ----------------------------- | ------------------------------------------------------------------------------------ | | `list_components` | 列出所有可用的 HeroUI v3 组件 | | `get_component_docs` | 获取一个或多个组件的完整文档,包括组件结构、props、示例和使用模式 | | `get_component_source_code` | 获取组件的 React/TypeScript 源代码(.tsx 文件) | | `get_component_source_styles` | 查看组件的 CSS 样式(.css 文件) | | `get_theme_variables` | 获取颜色、排版、间距相关的主题变量,支持浅色/深色模式 | | `get_docs` | 浏览完整的 HeroUI v3 文档,包括指南和设计原则(如需安装说明,请使用路径 `/docs/react/getting-started/quick-start`) | ## 故障排查 **环境要求:** Node.js 22 或更高版本。使用 `npx` 时会自动下载该包。 **需要帮助?** [GitHub Issues](https://github.com/heroui-inc/heroui-mcp/issues) | [Discord 社区](https://discord.gg/heroui) ## 链接 * [npm 包](https://www.npmjs.com/package/@heroui/react-mcp) * [GitHub 仓库](https://github.com/heroui-inc/heroui-mcp) * [贡献指南](https://github.com/heroui-inc/heroui-mcp/blob/main/CONTRIBUTING.md)