@ tiva- app/ ui
Estiva的设计标志, 和一小组原始的建在它们上,为 每一个Estiva应用——皮克,船,以及接下来的一切.
托肯斯是合同。 组件是一种便利.
里面有什么东西
tailwind-preset.js- 标志 名称,作为尾风预设: 颜色, 类型坡道,光线,阴影,骨架动画. 皮克的,逐字记录.tokens.css- 标志 数值,每个主题一个块:signal(怎样) 皮克让,ship(船舶制造)和light编号 :dark基础. 每个街区的名字都一样.- 初等——一次一出(见"故事手册"). 每个人的故事 不需要应用数据; 如果一个故事需要固定, 组件不是 原始的,不属于这里.
- 行为来自 基础UI (单位:千美元)
@base-ui/react页:1 用包安装的依赖性:键盘,焦点,角色,形式. 每一个有基础UI对应的组件都在上面被构建. 没什么 改变组件的外观.
用这个
// tailwind.config.js
import estiva from '@estiva-app/ui/tailwind-preset'
export default {
presets: [estiva],
content: ['./index.html', './src/**/*.{ts,tsx}'],
theme: { extend: { /* your app's own tokens, if any */ } },
}
/* your entry CSS, before anything that uses a token */
@import '@estiva-app/ui/tokens.css';
<html data-theme="ship"> <!-- or "signal" / "dark"; nothing = light. Peek uses the classes: <html class="dark signal">. -->
安装它 :
npm install @estiva-app/ui
展开 estivaContent 进入您的 content。 。 。 . 尾风不合并
content 从预设到计量,参见注释 tailwind-preset.js —— 说
所以没有这个,每个类别 仅使用这些组件, 清洗
结果是一个组件以错误的大小渲染而成功的构建 :
import estiva, { estivaContent } from '@estiva-app/ui/tailwind-preset'
export default {
presets: [estiva],
content: [...estivaContent, './index.html', './src/**/*.{ts,tsx}'],
}
规则是.. @estiva-app/ui/eslint
UI Guardrails 的 规则船 与软件包, 作为 ESLint 插件, 所以是一个应用 获得一个新规则,带有一个版本的凸起。 每个规则都指定要使用的组件 换句话说 有七个——六个街区,一个警告:
estiva/no-raw-element拒绝原始交互元素( e)<a>, (中文(简体) ),<input>, (中文(简体) ),<form>, (中文(简体) ),<dialog>...),并指定要使用的部分,或者说包还没有.estiva/no-rebuilt-behaviour拒绝已经拥有的部分的行为, 由 : 手: Base UI 导入,createPortal,单击或按键的听众 页面,手写箭头键比较role(单位:千美元)option, (中文(简体) ),menu, (中文(简体) ),dialog, (中文(简体) ),alert...tabIndex0或更多在一个盒子,和一个卷轴盒 (单位:千美元)overflow-auto,任何变体背后).OWNED_BEHAVIOURS列出每一种行为, 基本UI组件 和拥有它的组件。 它找不到一个 框中应滚动而不滚动的框:该框没有可读的类.estiva/no-restyled-part拒绝通过一个部分className或内框的类道具——颜色,文本大小,边框,a 角落,一个阴影——并命名该部分的外观道具(cPART_LOOK_PROPS) (中文(简体) ). 仅 安置经过(PLACEMENT),以及EmptyState没有补丁. A 类Form没有自己的布局, 坐在没有空格的盒子里 事物:在它的地盘进入它之前,它会发生什么.estiva/no-handmade-header拒绝用手绘制的列头栏: a 在一列中以第一行排列,并带有自己的侧贴和标题,其中一列 填充其高度或行有栏高或发线. 它读到 形状,而不是类名称,和名称ContainerHeader。 。 。 .estiva/no-handmade-empty-state拒绝用手绘制的空状态: a 显示列表行的位置, 当列表是 空无相. 它读到线条的位置,而不是它所说的,和名字EmptyState。它也拒绝page- 瞄准镜EmptyState内置 aScrollArea它的内涵和里面的东西一样高,它坐在那里 上面而不是中间, 跟着应用程序自己的组件进入它们 要找到一个文件.estiva/no-native-title拒绝title属性, 浏览器本身 工具提示和名称WithTooltip它燃烧在平地元素和部分 那个手title内容<Button title>- 其部分title属于它自己的标题( a) :PARTS_WITH_A_TITLE和一个<svg>是因为<title>元素通过.estiva/no-copied-look警告,永远不要挡道: 类列表为 部分的外观再次被打出——四个或更多外观字(颜色,文本,边框, 角; 阴影; 从不放置) 覆盖了80%的短列表. 在应用程序中 它比较了包裹的零件, 他们的外观走进registry.json,且该应用本身的导出组件; 修补是使用 这个角色。 在软件包中,修补是将外观写入src/looks.ts。 。 。 . 一次被写成导出…_CLASSES常数为一相也.estiva/no-field-outside-a-form拒绝Field, (中文(简体) ),TextInput或者说Textarea没有Form在它的文件中围绕它(调色板的)CommandPaletteForm一个,而且FormDialog名称Form:没有它什么也没有 发送球场。 在对话中DialogShell带有Form从来没有 内字段ConfirmDialog。 。 。 .EditableText财务报告和审定财务报表SearchInput过; a 用来绘制其呼叫者表格的字段的组件以逃生方式说出.
// eslint.config.js — alongside your own rules
import estiva from '@estiva-app/ui/eslint'
export default [
// …your config, with a parser that reads TSX
{ files: ['src/**/*.{ts,tsx}'], ignores: ['**/*.test.{ts,tsx}'], ...estiva.configs.recommended },
]
一个有目的的地方说,为什么,在以上线上:
// @estiva-escape: the reason, at least ten characters
<button …>
或者,作为一个JSX孩子, {/* @estiva-escape: the reason */}选择 eslint-disable数字 :
它在不说原因的情况下取消了规则 大门就算作一个
失败. countGates(results) 计数出错和出错
.gates-count.json; 线用 settings: { estiva: { reportEscapes: true } }
以计出逃者. estiva-gates count 这两件事都是为你们而做的.
门的碎片—— @estiva-app/ui/gates
所有其它的应用程序都需要有门 船在这里,一次,所以一个应用程序永远不会
携带副本( :docs/GATES.md 第23条。 这需要 eslint, (中文(简体) ), typescript-eslint 财务报告和审定财务报表
eslint-plugin-better-tailwindcss 安装在它旁边.
tokenLint()财务报告和审定财务报表tokenValues()- 象征性合同为: 预设名称,没有手写值,没有内在样式的颜色.gateConfig()——自来自去的大门(eslint.gates.config.js: 插件的规则, 标记插件已注册, 因此其禁用的评论 仍然有决心.estiva-gates count --repo <name>——用闸口配置并写出.gates-count.json; 如果出现错误或未写理由, 则失败.estiva-gates hook克劳德写档案前的拒绝 代码PreToolUse钩入.claude/settings.json。 。 。 .estiva-gates status—— 说gates:status,从代码读取.appChecks(h)检查每个应用程序运行在它的scripts/gates-checks.mjs。 。 。 .npm run gates:compare检查一下皮克和飞船.
一个新的应用 - create-estiva-app
npx -p @estiva-app/ui create-estiva-app leaf --title Leaf
它制作一个文件夹,用 Estiva ID 来构建,运行和签名,每个门
从它的首次承诺开始:指针规则和指针以0为单位的指针,计数
文件、 编辑器钩子、 CI 任务 gate,以及 gates:status。它不读
但这个包裹。 这个框架是 AppShell 带有 Sidebar,一个主题
(单位:千美元)--theme默认值 light设置一次 index.html它的读取器说
由Estiva ID注册应用程序,并保护 main。 。 。 .
目录—— estiva-ui
"我们已经有了这个吗?"有一个答案: estiva-ui find <what it does>。 。 。 .
npx estiva-ui find a floating panel # the package's parts, and this app's own
npx estiva-ui check # every part says what it is for (CI's job gate)
- 包裹的目录 实值
registry.json从代码中生成, 已承诺和已发运:每次出口一次,目的一次,每次道具一次 宣布,它拥有什么,它的页面在哪里. - 应用程序的目录 由应用程序的代码构建 每次读取,
从来没有承诺过 每一部分a
.tsx文件导出随其 目的(单行)/** … */上面,应用程序使用它的地方,以及它的类型: 包件部分的通过,在一个地方使用,在几个地方使用,一个候选人到 移动到包里,或者无处使用.estiva-ui check部分失败 没有描述.--also [name=]<folder>加上一个坐在这个旁边的应用程序. @estiva-app/ui/registry输出构建者和搜索工具 自己读.
规则
允许伪造
在您的应用程序中添加组件是允许的, 而不是失败 。 狦 叉子一,你什么都不欠回来。 托肯斯是你唯一不能拥有的东西 与众不同.
如果一个原始的几乎适合但不完全, 复制到您的应用程序中并更改 这个 在包裹的票上这么说——叉子是接缝的信息—— 你不要视而不见,不要等待 允许。 图书馆里的人害怕偏离 成为税.
托肯斯,从不生六指
如果您需要的颜色没有符号, 则缺少符号: 在此添加, in 而不是在应用程序中达到六分法.
透明颜色也是一种标志。 洗个澡 轮廓 发光或发光
住在这里 tokens.css,而不是在另一个符号上的不透明修饰符中:
bg-bg-inset/40 编译为一无所有, 因为符号是简单的 var()
数值.
尾风所形成的陷阱——为 cn() 用户
库存 tailwind-merge 静静地下降 自定义文本大小类
(单位:千美元)text-btn-small, (中文(简体) ), text-caption, (中文(简体) ), text-h2当一个 text-{colour} 类
坐在同一个合并列表中——它不能将大小分类,文件为
颜色,然后让真正的颜色打倒它。 从2026-09-01起
软件包 cn() 教授预设型号的斜坡( p)src/cn.ts· ; cn.test.ts
将列表插入到预设中, 因此 符号大小类安全合并
列表 这是新代码应该写。 任何人的陷阱都还存在
与自己的非扩展配置合并 cn, (中文(简体) ),
所以别 旧组件仍拼写大小为任意值
使物同被触动,并移入物证.
菜单和流行音乐——五项规则
* 关闭鼠标休假(用于打开的菜单) * 守护
=============================================================================================================================================================================================================================================================== 每个都是
孤独地忘却了 失败了的流行音乐 让人觉得没有
有人能说出原因 点击打开的菜单( 选择, a) … 菜单)
最后两个,一个悬浮开口 一个欠所有五个.
只提供能够成功的行动
行动只在起作用的地方出现。 无法成功的控制
现在已禁用 及其原因,而控制 某人可能永远不会使用是
没有,没有残疾. Button 财务报告和审定财务报表 IconButton 把它当作
disabledReason="Sign in first": 已禁用, 仍可通过 Tab 访问
理由显示为工具提示。 一行菜单也: MenuItem是因为
disabledReason,关闭,被箭键所接通, 徘徊的原因.
从来没有一个按钮失败.
主题
| 主题 | 选中的 | 谁 |
|---|---|---|
signal | data-theme="signal" 或者说 .dark.signal | 皮克,它意味着什么 |
ship | data-theme="ship" | 船舶——它使 |
dark | data-theme="dark" 或者说 .dark | 皮克的基地在信号下 |
light | 无 | 页:1 :root 碱; Estiva ID |
皮克的只信号外加(洗涤,发光,摘要亮度,和声)
登记簿、字签、单堆)是产品,而不是合同,以及
留在皮克身边 .signal 块.
处理中
npm install
npm test # tokens (every theme defines every token the preset names, and no other), cn(), and each component's page claims
npm run lint # the token contract: no class Tailwind does not generate, no ramp, no raw colour
npm run typecheck
npm run storybook # http://localhost:6008 — Design Tokens, and each primitive, in signal and ship
更改不能改变应用程序的制作方式:
之后,无论是这里的主题,还是应用程序自己的"故事书". CLAUDE.md 实值
指数。 是什么组件,一个故事,一个页面和一个发布在
.claude/rules/; 如何进行端口和证明更改是 port 财务报告和审定财务报表
verify 技术 .claude/skills/。 。 。 .