主题化组件系统 · 新资源

HeroUI 设计系统.

HeroUI v3 参考,包含实际的语义化 CSS 变量、复合 React 控件、明暗界面表面,以及可用的图像导出方法。

OpenDesign 指南9 个章节30 个参考条目原始应用指南
01

HeroUI 设计系统界面预览

使用原生滑块调整质量、切换元数据、切换外观并应用本地配方。不模拟编码器或上传操作。

图像导出工作室打开完整示例
使用原生 @heroui/react 3.2.6 和 @heroui/styles 3.2.6 编译后的 CSS;采用自定义插画和布局。· 实现参考
02

HeroUI 设计系统设计参考

HeroUI 3.2.6 默认主题,已依据 @heroui/styles/dist/themes/default/variables.css 验证。以下 OKLCH 值均为软件包中的原始值。插画颜色和字体排印是应用自身的选择,并非 HeroUI 品牌令牌。

语义化界面表面与对比度

来源
名称 / 规则值 / 配置用途
--backgroundoklch(0.9702 0 0)浅色页面画布;深色模式下为 oklch(12% 0.005 285.823)。
--foregroundvar(--eclipse)浅色阅读文字颜色;深色模式下解析为 --snow。
--surfacevar(--white)浅色卡片背景;深色模式下为 oklch(0.2103 0.0059 285.89)。
--overlayvar(--white)浮动层背景。即使浅色模式下的值相同,其用途也与界面表面不同。
--accentoklch(0.6204 0.195 253.83)选中状态的开关、滑块填充色和主要按钮。
--accent-foregroundvar(--snow)纯色强调色上的文字。
--mutedoklch(0.5517 0.0138 285.94)次要文字;深色模式下为 oklch(70.5% 0.015 286.067)。
--borderoklch(90% 0.004 286.32)浅色模式下的边界;深色模式下为 oklch(28% 0.006 286.033)。
--focusvar(--accent)键盘焦点指示。
--field-backgroundvar(--white)浅色模式下的输入框表面;深色模式下跟随 eclipse 值。

形状、间距与状态

来源
名称 / 规则值 / 配置用途
--spacing0.25rem基础间距单位;根字号为 16px 时对应 4px。
--radius0.5rem默认圆角基元;根字号为 16px 时对应 8px。
--field-radiuscalc(var(--radius) * 1.5)默认字段圆角为 12px。
--border-width1px默认边界粗细。
--field-border-width0px默认字段不依赖轮廓边框。
--disabled-opacity0.5禁用状态的视觉样式;仍须使用组件的 isDisabled。
--ring-offset-width2px控件与焦点环之间的间距。
--tooltip-delay1500ms默认软件包中的初始工具提示延迟。
--tooltip-close-delay500ms工具提示关闭延迟。

应用的字体排印与布局

来源
名称 / 规则值 / 配置用途
body16px / 1.5, Arial, Helvetica, sans-serif明确指定的预览字体;并非强制要求的 HeroUI 字体。
h132px / 1.15; 28px below 700px自定义页面标题字号层级。
h224px / 1.25导出设置标题。
helper text13px / inherited 1.5质量说明和本地结果。
desktop gap24px双列插画/设置网格。
mobile breakpoint700px自定义响应式规则,并非 HeroUI 断点令牌。
card radiuscalc(var(--radius) * 3)使用官方基元构建的 24px 应用布局。

原生控件配置

来源
名称 / 规则值 / 配置用途
quality rangeminValue=10; maxValue=100; step=5应用编码器配方范围,并非 HeroUI 默认值。
Slidervalue + onChange受控数字值会更新输出和配方。
SwitchisSelected + onChange受控布尔值确保只有一个真实数据源。
ButtononPressReact Aria 按压事件支持指针和键盘激活。
03

HeroUI 设计系统完整指南

实用指南,介绍如何为真实界面选择、应用和评审此系统。

DESIGN-heroui.md

完整指导、实现起点和源代码链接。

下载指南

HeroUI 设计系统 v3 与 Export Studio

React 组件与语义样式表

此示例面向 HeroUI 3.2.6。其控件是由 React Aria 行为支持的 React 组件,视觉样式则来自 @heroui/styles。官方快速入门要求使用 React 19 和 Tailwind CSS v4。v3 配置不会像旧版 HeroUIProvider 模式那样,用提供程序包裹此应用。将 v2 教程与此复合组件 API 混用,容易导致控件缺失或样式不正确。

摘自本 OpenDesign 指南

此示例是一个导出配置编辑器:左侧为图稿,右侧为质量和元数据控件。插图由原创 CSS 绘制,并非经该库处理的图像。应用配置方案时,会将所选设置保存为本地 React 状态;示例不会虚构文件大小或下载结果。

阅读配套规范

HeroUI 设计系统语义色彩与外观

区分画布、界面表面与浮层

使用 --background 设置外围画布背景,使用 --surface 设置图稿和设置卡片的背景,使用 --overlay 设置未来弹出层或对话框的背景。这些都是语义角色,即使在浅色模式下其中两个角色最终都显示为白色。深色模式下,画布和浮层表面的颜色则有所区别。此示例会在 document.documentElement 上切换 dark 类,让所有后代元素共用同一主题范围。

滑块填充部分和选中的开关使用强调色角色。纯色强调控件搭配 --accent-foreground。次要文本使用 --muted,而不是降低整张卡片的不透明度。两种外观下,图稿都保留独立的暖色调,因为它属于内容,而非交互界面元素。

阅读配套规范

HeroUI 设计系统字体排印与间距

明确说明应用的尺寸比例

HeroUI 样式可与 Tailwind 工具类配合使用,但此页面不会擅自指定一个必需的 HeroUI 字体。原创 CSS 选择 Arial/Helvetica,正文为 16px,行高为 1.5。窄屏布局中,32px 的标题缩小为 28px;设置标题为 24px。参考表会将这些应用层取值与包变量区分开来。

官方 --spacing 基础单位为 0.25rem。此布局在配置方案内部使用 16px 间距,在列之间以及桌面卡片周围使用 24px 间距,在桌面画布周围使用 32px 间距。字段圆角基于官方 8px 圆角基础单位。卡片圆角特意设为该基础单位的三倍,因此 24px 是应用层的衍生值,并非声称 Card 的默认值。

阅读配套规范

HeroUI 设计系统:构建完整的滑块

让组件结构与数值状态保持一致

Slider 根组件负责管理 value、onChange、minValue、maxValue 和 step。Label 用于提供无障碍名称。Slider.Output 读取同一数值,Slider.Track 则包含 Slider.Fill 和 Slider.Thumb。省略这些可见部分,可能会导致控件虽能交互,却缺少预期的轨道或滑块。此示例使用单个数值,而非范围数组。

质量范围限制为 10–100,步长为 5。这些限制是本地产品决策。HeroUI 本身的默认范围为 0–100,步长为 1。质量数值与文件大小之间没有普遍可靠的对应关系,因此辅助说明解释了其中的权衡,但不会虚构文件大小估算。要支持多个滑块,请使用数值数组,并为每个滑块指定正确的索引。

  1. 聚焦质量滑块,然后按方向键逐步调整数值。
  2. 确认可见的输出与当前配置方案会同步变化。
  3. 应用配置方案后,再移动滑块,以区分当前草稿和已应用的快照。

阅读配套规范

HeroUI 设计系统:组合布尔设置

开关包含控件部分和内容部分

元数据设置通过 Switch 上的 isSelected 和 onChange 管理。在已安装的 3.2.6 实现中,Switch.Content 包裹 Switch.Control 和 Label;Switch.Control 内含 Switch.Thumb。Description 位于 Switch.Content 旁边,作为字段级说明。此结构遵循已安装版本的源码;其中 SwitchField/SwitchButton 的组件结构与部分早期 v3 文档示例不同。说明会解释布尔值的含义,而不是依赖蓝色的选中轨道来传达信息。单一元数据状态同时驱动原生控件和文本配置方案。

将此布尔值与应用操作分开处理。切换元数据会立即编辑当前草稿;按下“应用并预览”后才会记录快照。重置会将质量恢复为 80、移除元数据并清除该快照。不会将已保存状态指示器挪作其他草稿用途。如果此示例接入了编码器,应将已应用的对象传递给该处理流程,而不是读取含义不明确的表单文本。

阅读配套规范

HeroUI 设计系统:以响应式方式组合界面表面

图稿属于内容,不是控件背后的装饰

桌面布局采用 1.05fr/1fr 网格,让图稿略宽一些,同时确保设置内容易于阅读。在原有的 700px 断点处,网格变为单列,页眉改为纵向排列,图稿纵横比也从 4:5 调整为 4:3。说明文字置于图稿之外,以保持阅读区域稳定。

所有交互控件都位于纯色语义表面上。空间不足时,按钮会换行。预览高度由内容决定,而非设置视口最小高度;当文档嵌入自动调整尺寸的 iframe 时,这一点尤为重要。页面没有固定高度的滚动框,因此表单或结果不会被隐藏。

阅读配套规范

HeroUI 设计系统:交互、焦点与真实结果

使用原生状态,而非绘制出来的替代效果

Button 使用 onPress,而非仅支持指针操作的自定义事件。Slider 提供键盘操作并播报数值。Switch 通过原生无障碍实现提供布尔状态。自定义布局 CSS 不会移除焦点样式。组件禁用时应使用 isDisabled,而不应仅靠不透明度实现;--disabled-opacity 只定义外观。

状态段落使用 role=status,因此应用快照后可以播报状态,而无需移动键盘焦点。深色外观按钮会更新标签,说明下一步操作。图稿带有描述性区域标签,其形状则标记为装饰元素。此演示不会承诺重新加载后仍保留数据。

  • 质量是一个有明确范围且显示当前值的数值选项。
  • 元数据为布尔值,同时包含标签和说明文字。
  • 应用会保存本地快照;重置会清除快照并恢复初始草稿。

阅读配套规范

HeroUI 设计系统:安装并复现示例

选择一种样式表构建流程

在 Vite React 应用中,安装固定版本的 HeroUI 软件包和带有 Vite 插件的 Tailwind CSS v4。在主样式表中先导入 tailwindcss,再导入 @heroui/styles,然后加入原始布局 CSS。使用 React createRoot 渲染 App;此组合无需 v2 provider。配置代码块包含入口文件和 Vite 配置,完整的 App 和 CSS 如上所示。

可下载的独立示例使用软件包预编译的 heroui.min.css 和 esbuild React 打包,并将两者内嵌。这让预览无需依赖 CDN。示例展示了相同的原生控件,但并非建议在同一个生产应用中同时导入编译后的样式和 Tailwind 生成的 HeroUI 样式。请选择一种构建流程,以免重复应用规则。

阅读配套规范

HeroUI 设计系统:扩展配方,但不要虚构编码器

明确呈现能力边界

若要添加真正的图像转换功能,请加入文件输入控件和实际的浏览器或服务器端编码器,并将待处理、失败和完成状态与处理流程关联起来。Slider 只能选择数值,并不具备压缩功能。在实际生成输出 blob 之前,不应将 Apply 按钮改为 Download 按钮。请单独保留原始图像,避免反复更改配方时叠加有损编码。

为应用设置主题时,应成对覆盖语义变量,并测试浅色和深色外观。只更改 --accent,却保留不合适的前景色,可能会降低按钮对比度。若要进行更复杂的自定义,请针对文档中说明的组件类和 data 状态进行设置,而不要用外观相似的 div 替换组件中具备无障碍功能的 input。

阅读配套规范

HeroUI 设计系统组件示例

完整的导出配方应用

复合 Slider 和 Switch 部件会继承官方样式。单独保存已应用的快照,可明确区分草稿与已应用状态。

jsx
import React,{useState,useEffect} from 'react';
import {Button,Switch,Label,Description,Slider} from '@heroui/react';
import './style.css';
export default function App(){
const[quality,setQuality]=useState(80),[metadata,setMetadata]=useState(false),[dark,setDark]=useState(false),[saved,setSaved]=useState(null);
useEffect(()=>{document.documentElement.classList.toggle('dark',dark)},[dark]);
return <main className='export-app'><header><div><p className='eyebrow'>HeroUI · Export studio</p><h1>Make room for the image.</h1><p className='muted'>Inspect a local export recipe before handing it to an encoder.</p></div><Button variant='secondary' onPress={()=>setDark(!dark)}>{dark?'Light appearance':'Dark appearance'}</Button></header><div className='export-grid'><section className='art-panel' aria-label='Original CSS artwork preview'><div className='art'><div className='sun'/><div className='hill one'/><div className='hill two'/><span>FIELD NOTES<br/>COLLECTION 07</span></div><div className='art-caption'><strong>Morning in the dunes</strong><span>1600 × 1200 · sample composition</span></div></section><section className='settings'><p className='eyebrow'>WEBP PRESET</p><h2>Export settings</h2><p className='muted'>The controls update a recipe. They do not encode or upload an image.</p><Slider value={quality} onChange={setQuality} minValue={10} maxValue={100} step={5}><div className='slider-heading'><Label>Image quality</Label><Slider.Output/></div><Slider.Track><Slider.Fill/><Slider.Thumb/></Slider.Track></Slider><p className='helper'>Higher quality may preserve fine texture. File size depends on the source image and encoder.</p><Switch isSelected={metadata} onChange={setMetadata}><Switch.Content><Switch.Control><Switch.Thumb/></Switch.Control><Label>Keep metadata</Label></Switch.Content><Description>Include source metadata in the recipe.</Description></Switch><div className='recipe'><p className='eyebrow'>CURRENT RECIPE</p><code>format: webp<br/>quality: {quality}<br/>metadata: {metadata?'keep':'strip'}</code></div><div className='actions'><Button onPress={()=>setSaved({quality,metadata})}>Apply to preview</Button><Button variant='tertiary' onPress={()=>{setQuality(80);setMetadata(false);setSaved(null)}}>Reset</Button></div><p role='status' className='status'>{saved?`Preview recipe applied: quality ${saved.quality}, metadata ${saved.metadata?'kept':'stripped'}. No file was generated.`:'Adjust quality with the arrow keys, then apply the recipe.'}</p></section></div><footer>Native HeroUI 3.2.6 controls and official compiled styles. Artwork and page layout are original CSS.</footer></main>;
}

代码参考

  • Slider.Output 会反映受控数值。
  • Switch.Control 和 Switch.Thumb 是必需的可见结构。
  • onPress 会应用配方,但不表示图像已完成编码。

原始布局 CSS

表面和圆角参考使用 HeroUI 变量;插画颜色、字体比例和断点均为明确的应用设计选择。

css
*{box-sizing:border-box}body{margin:0;background:var(--background);color:var(--foreground);font-family:Arial,Helvetica,sans-serif;font-size:16px;line-height:1.5}.export-app{max-width:1120px;padding:32px;margin:auto}header{display:flex;justify-content:space-between;align-items:start;gap:24px;margin-bottom:28px}h1{font-size:32px;font-weight:700;letter-spacing:-.035em;line-height:1.15;margin:8px 0 12px}h2{font-size:24px;font-weight:650;line-height:1.25;margin:8px 0 12px}.eyebrow{font-size:11px;letter-spacing:.12em;font-weight:700}.muted,.helper,footer{color:var(--muted)}.muted{margin:0 0 24px}.export-grid{display:grid;grid-template-columns:1.05fr 1fr;gap:24px}.art-panel,.settings{background:var(--surface);border-radius:calc(var(--radius)*3);padding:24px;box-shadow:var(--surface-shadow)}.art{position:relative;aspect-ratio:4/5;background:#f0d8b8;border-radius:calc(var(--radius)*2);overflow:hidden}.sun{width:40%;aspect-ratio:1;background:#bf532f;position:absolute;top:13%;left:30%;border-radius:50%}.hill{position:absolute;width:180%;height:70%;border-radius:50%;transform:rotate(-24deg)}.one{top:50%;left:-60%;background:#c59162}.two{top:66%;left:-10%;background:#69402e}.art span{position:absolute;top:6%;left:8%;font-size:11px;letter-spacing:.2em;color:#563324}.art-caption{display:flex;flex-direction:column;gap:4px;margin-top:16px}.art-caption span{color:var(--muted);font-size:12px}.settings{display:flex;flex-direction:column;gap:16px}.settings .muted{margin-bottom:0}.slider-heading{display:flex;justify-content:space-between;gap:16px}.helper{font-size:13px;margin:0}.recipe{border:var(--border-width) solid var(--border);padding:16px;border-radius:var(--field-radius)}.recipe .eyebrow{margin-top:0}code{font-size:14px}.actions{display:flex;flex-wrap:wrap;gap:8px}.status{font-size:13px;margin:0}footer{font-size:12px;margin-top:20px}@media(max-width:700px){.export-app{padding:16px}header{flex-direction:column}h1{font-size:28px}.export-grid{grid-template-columns:1fr}.art{aspect-ratio:4/3}.art-panel,.settings{padding:20px}}

代码参考

  • 在官方样式表之后加载此 CSS。
  • html 上的 dark 类会更改整个文档的语义值。
04

HeroUI 设计系统 Agent 配置

实现起点

已使用 React 19 和 HeroUI 3.2.6 验证原生预览。提供的 App 和布局 CSS 已完整就绪。此 Vite 配置使用文档说明的 Tailwind v4 导入流程;离线示例则内嵌了官方预编译样式表。

jsx
// In a Vite React 19 project:
// npm install @heroui/[email protected] @heroui/[email protected] tailwindcss@^4 @tailwindcss/vite@^4
// vite.config.js
import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({plugins:[react(),tailwindcss()]});

// globals.css: keep this import order
// @import "tailwindcss";
// @import "@heroui/styles";
// Paste the Original layout CSS after these imports.

// main.jsx
import React from 'react';
import {createRoot} from 'react-dom/client';
import './globals.css';
import App from './App.jsx';
createRoot(document.getElementById('root')).render(<App/>);
// App.jsx is the complete application above. Remove its './style.css'
// import when the same CSS is included in globals.css.

适用于你项目的提示词

Agent 提示词
使用提供的 HeroUI 3.2.6 App.jsx、样式表和 Tailwind 集成来构建图像导出工作室。将 Slider 的质量状态和 Switch 的元数据状态关联到导出摘要;保留 Switch.Content、Control 和 Thumb,并为它们提供对应标签。更改质量或元数据后,必须使已保存的快照失效。深色外观控件应更改样式表所用的同一文档类。保存明确标注为本地的导出配方;不要暗示图像文件已处理或下载。
05

HeroUI 设计系统的来源与范围

HeroUI 3.2.6 参考。官方变量与原创字体排印、插画和布局明确区分。原生预览只会更改保存在内存中的设置,不会进行图像编码。