@ctrl-ui/反应
每个控制UI组件,块和原始有中性默认. 包内没有皮肤预设,不需要提供者或皮肤配置. 使用 登记 当您想要拥有和编辑组件源时.
安装
bun add @ctrl-ui/react
需要反应19和Tailwind CSS v4. 在您的全球 CSS 中连接样式一次 :
@import "tailwindcss";
@import "@ctrl-ui/react/styles/index.css";
@source "../node_modules/@ctrl-ui/react/dist";
使用
import { Button } from "@ctrl-ui/react/ui/button";
<Button>Save</Button>
导入路径映射注册树 。 运送更少的CSS,导入 styles/theme.css 只有配方 和效果 您的组件使用.
文本和类名称
文本为 Text 财务报告和审定财务报表 Heading尺寸、语气和重量是道具; className 只携带布局 :
import { Text } from "@ctrl-ui/react/ui/typography";
<Text size="caption" tone="muted">Saved</Text>
将类名称与软件包合并 cn。一个赤裸的 twMerge 读取 text-micro 作为文本颜色,默默地将其放在旁边 text-muted-foreground。在顶部添加您自己的类型 withControlUiMerge 而不是开始第二次合并:
import { withControlUiMerge } from "@ctrl-ui/react/lib/cn";
import { extendTailwindMerge } from "tailwind-merge";
const twMerge = extendTailwindMerge({ extend: { classGroups: { "font-size": [{ text: ["hero"] }] } } }, withControlUiMerge);
控件大小: 选择控件的 size,或设置其 --cui-*-font-size 在您的主题中按键, 而不是将标签包装为 text-* 间距.
林特规则
这些规则让网站保持诚实。 它们来自一项政策(lint/class-policy.mjs)和飞船为Biome,ESLint,和克克林特,除了样式表规则,它只是Biome:
no-component-style-classes错误当className的组件@ctrl-ui/react(或 a 个)components/control-ui目录)设定组件拥有的:颜色,类型,编目,边框,半径,阴影,过滤器,状态样式等hover:财务报告和审定财务报表data-[…]:涂料的任意属性([background:…]),或!important每一个text-*分类计数,但对齐和包接除外(text-center, (中文(简体) ),text-pretty, (中文(简体) ),text-ellipsis(......) (中文(简体) ). 该规则还读取字符串常数className在同一文件中的引用,以及className转移给该部分的render道具 (英语). 在任何其他要素上,它错误地将类误入一个组件的部分,例如:[&_[data-slot=trigger]]:或者说*:data-[slot=icon]:组合类flex, (中文(简体) ),gap-*,宽度,高度,边距,位置)允许保留. 通过组件的道具或它的--cui-*转而取道把手.no-component-style-props将同一边界适用于style数字 :--cui-*knobs和布局密钥通过,而涂装密钥出错(color, (中文(简体) ),background, (中文(简体) ),font*, (中文(简体) ),padding*, (中文(简体) ),border*, (中文(简体) ),boxShadow, (中文(简体) ),opacity, (中文(简体) ),filter(......) (中文(简体) ). 它还检查同一文件的常数对象和传递给render当涂料是数据时,如用户选取的填充,将其放入自己的平面元素上,让组件继承.no-component-part-css样式表绘制组件部分时出错:其主体为规则[data-slot], (中文(简体) ),[data-control-family],或另一个[data-control…]属性,包括嵌入式&规则和规则@apply设定该部分--cui-*手势和布局是允许的。 预设跳过已安装控制 UI 源components/control-ui。 。 。 .- 无漆组件没有外观,所以两个组件规则都把它们当作平面元素:
RevealScope可以是所绘行或牌本身,通过className, (中文(简体) ),style时,或render键。 部分选择器仍然错误,以及Reveal保持完整的规则,因为它的食谱 拥有不透明. no-raw-type-classes任意文本大小出错className: 类型 rungs, Tailwind'stext-xs.text-9xl和任意性text-[13px]。它超出了控制UI的范围,所以在您迁移时按文件夹通过它.
Biome 规则需要 Biome 2. 5.0 或 后期: 预设范围 : 带有插件的样式表规则 includes。 。 。 .
Biome, 扩展已运出预设, 因此添加的规则随软件包更新而到达 :
{
"extends": ["@ctrl-ui/react/biome"],
"overrides": [{ "includes": ["src/features/**"], "plugins": ["./node_modules/@ctrl-ui/react/lint/no-raw-type-classes.grit"] }]
}
ESLint 平面配置 :
import controlUi from "@ctrl-ui/react/eslint-plugin";
export default [
{
plugins: { "control-ui": controlUi },
rules: { "control-ui/no-component-style-classes": "error", "control-ui/no-component-style-props": "error" },
},
];
校对:Soup
{
"jsPlugins": ["@ctrl-ui/react/eslint-plugin"],
"rules": { "control-ui/no-component-style-classes": "error", "control-ui/no-component-style-props": "error" }
}
当您的应用程序通过自己的包装包或文件夹导入组件时, 声明路径, 规则也遵循这些导入 :
const options = { importSources: ["@acme/ui/components/"] };
rules: { "control-ui/no-component-style-classes": ["error", options], "control-ui/no-component-style-props": ["error", options] }
Biome 的 Grit 插件没有选择, 所以包船 control-ui-grit 写规则与路径。 在安装时运行它, 这样一个软件包更新它们, gitignore .control-ui,并列出生成的 no-component-style-classes.grit, (中文(简体) ), no-component-style-props.grit,以及 no-component-part-css.grit 从 ./.control-ui/ 下级 plugins 替换预设 :
{ "scripts": { "postinstall": "control-ui-grit --import-source=@acme/ui/components/ --out=.control-ui" } }
自定义
您的应用程序拥有它的主题 。 覆盖您的 CSS 中库的中性默认值 :
:root {
--primary: oklch(0.45 0.18 260);
--radius: 4px;
}
.dark {
--primary: oklch(0.78 0.1 260);
}
组件节点自定义一个实例 :
<Button style={{ "--cui-button-radius": "4px" }}>Save</Button>
对于范围化的主题,行为选择,或花饰,通过自己的 ControlUiSkin 给可选提供者。 定义客户端模块中包含渲染函数的配置 :
"use client";
import type { ReactNode } from "react";
import type { ControlUiSkin } from "@ctrl-ui/react/skin";
import { SkinProvider } from "@ctrl-ui/react/skin-provider";
const skin: ControlUiSkin = { id: "acme", indicators: { sidebar: "hover" } };
export function AppTheme({ children }: { children: ReactNode }) {
return <SkinProvider skin={skin}><div data-skin="acme">{children}</div></SkinProvider>;
}
相应的CSS范围为 [data-skin="acme"]. Portalled surfaces 承载了提供者的ID,因此它们得到相同的主题. 由于没有提供者,门户继承了根主题. 每个供应商拥有其子树;没有全球的皮肤单子.
可选同伴
仅在导入需要的组件时安装对等端 .
| 构成部分 | 端点 |
|---|---|
ui/calendar | react-day-picker |
ui/chart | @tanstack/charts |
ui/code, (中文(简体) ), ui/code-diff | @tanstack/react-virtual, (中文(简体) ), diff, (中文(简体) ), shiki |
ui/command | cmdk |
ui/flow | @xyflow/react |
ui/markdown | streamdown |
ui/phone-input | react-phone-number-input, (中文(简体) ), libphonenumber-js, (中文(简体) ), zod |
ui/resizable | react-resizable-panels |
chat-composer | prosemirror-* |
email/email, (中文(简体) ), email/templates | react-email |
ui/flow 还需要在食谱下加载的回放流结构样式表:
@import "@xyflow/react/dist/base.css" layer(base);