ui-sdk

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Build with ui-sdk

使用 ui-sdk 构建

ui-sdk is a library of UI behaviors: keyboard navigation, focus, selection, dismissal, popups, drag and drop and the ARIA they need. Its components are built from those behaviors and render no styles of their own, in React, Vue, Svelte, Solid and web components.
@ui-sdk/core/web.css
gives them an optional default look. When a component is missing, you build it from the same behaviors in
@ui-sdk/core
, and it gets the same keyboard, focus, server rendering and right to left support.
ui-sdk 是一套 UI 行为库:键盘导航、焦点、选择、关闭、弹出层、拖放,以及这些行为所需的 ARIA。其组件基于这些行为构建,本身不渲染任何自带样式,支持 React、Vue、Svelte、Solid 和 Web Components。
@ui-sdk/core/web.css
可为它们提供可选的默认外观。当缺少某个组件时,应使用
@ui-sdk/core
中的同类行为进行构建,使其获得相同的键盘、焦点、服务端渲染和从右到左支持。

Read first

首先阅读

The docs for the installed version ship in each package, as Markdown:
  • node_modules/@ui-sdk/<framework>/docs/llms.txt
    is the index. Read it first.
    <framework>
    is
    react
    ,
    vue
    ,
    svelte
    ,
    solid
    or
    web
    .
  • Then read only the pages your task needs, like
    docs/components/select.md
    . Don't read the whole
    docs/
    folder; it's large.
  • An interface built from our components doesn't need
    docs/core.md
    . Only path 2 below does, and even then you search it by heading: it's over 300 KB.
    docs/rendering.md
    sits next to it in the same
    docs/
    folder.
  • Don't read compiled JavaScript in
    dist/*.js
    , even to debug. The docs and the
    .d.ts
    types are the API; when they don't answer, write a small test that tries it.
The same docs are online at https://ui-sdk.dev/docs. Prefer the installed copy: it matches the version in the project.
A page with no build step, like an Artifact, installs nothing: it loads
https://ui-sdk.dev/web.js
and
web.css
with two tags. Read https://ui-sdk.dev/web.md instead of
llms.txt
. It's the web components docs in one file, for that page, and references/web-components.md has the rest.
Otherwise, if no
@ui-sdk
package is installed yet, install
@ui-sdk/core
and the framework's package with the project's package manager.
已安装版本的文档以 Markdown 形式随每个包提供:
  • node_modules/@ui-sdk/<framework>/docs/llms.txt
    是索引。先读取它。
    <framework>
    为
    react
    、
    vue
    、
    svelte
    、
    solid
    或
    web
    。
  • 然后只读取任务需要的页面,例如
    docs/components/select.md
    。不要读取整个
    docs/
    文件夹,因为它很大。
  • 使用我们的组件构建的界面不需要
    docs/core.md
    。只有下方路径 2 需要它;即使如此,也应按标题搜索,因为该文件超过 300 KB。
    docs/rendering.md
    位于同一
    docs/
    文件夹中。
  • 不要读取
    dist/*.js
    中编译后的 JavaScript,即使只是为了调试。文档和
    .d.ts
    类型才是 API;如果二者无法回答问题,请编写一个尝试该 API 的小型测试。
对于没有构建步骤的页面(例如 Artifact),无需安装任何内容:页面通过两个标签加载
https://ui-sdk.dev/web.js
和
web.css
。此时应阅读 https://ui-sdk.dev/web.md,而不是
llms.txt
。这是集中于一个文件中的 Web Components 文档,专为该页面准备;其余内容见 references/web-components.md。
否则,如果尚未安装任何
@ui-sdk
包,请使用项目的包管理器安装
@ui-sdk/core
和对应框架的包。

Pick your path

选择路径

  1. Build an interface from our components, like a settings page, a form or a command palette: read references/build-interface.md.
  2. Build a component or behavior ui-sdk doesn't ship, or extend one of ours: read references/create-component.md.
Most interfaces only need path 1. When one part of it needs a component we don't have, follow path 2 for that part.
Every path ends the same way:
  1. Make it agent-ready: references/agent-ready.md.
  2. Test it: references/testing.md.
  1. 使用我们的组件构建界面,例如设置页面、表单或命令面板:阅读 references/build-interface.md。
  2. 构建 ui-sdk 未提供的组件或行为,或者扩展我们的某个组件:阅读 references/create-component.md。
大多数界面只需要路径 1。如果其中某一部分需要我们没有的组件,则该部分遵循路径 2。
每条路径最终都以相同方式结束:
  1. 使其支持 Agent:阅读 references/agent-ready.md。
  2. 进行测试:阅读 references/testing.md。

Rules for every path

所有路径通用规则

  • Import from entries. Each component has its own entry, like
    @ui-sdk/react/select
    . There's no root import from a framework package. Never import
    @ui-sdk/core/internal/*
    .
  • One shape everywhere. A root and its parts, nested as the component page's Composition shows. Change a part's element with
    render
    , never an
    as
    prop.
  • Default or controlled.
    defaultValue
    to start, or
    value
    with
    onValueChange(value, details)
    to control it (each framework's idiom:
    v-model
    in Vue,
    bind:value
    in Svelte, properties and events in web components).
    details
    has
    reason
    ,
    source
    and
    cancel()
    .
  • Name every control. Use the component's label part (
    FieldLabel
    ,
    SelectLabel
    ,
    DialogTitle
    ), or
    aria-label
    when there's no visible text. People using screen readers and agents both find controls by name.
  • Style from state. Target
    data-slot
    and state attributes like
    data-open
    or
    data-pressed
    , and the CSS variables each component lists. Never inline styles for state, and never generated ids. When the app uses
    web.css
    , read references/styles.md first: it draws icons and sets sizes you can't see in the markup.
  • Declare the ui-sdk layer. Put
    @layer ui-sdk;
    at the top of the global stylesheet, above
    @import "tailwindcss"
    if there is one.
  • Check color. Text needs 4.5:1 against what's behind it, and control edges, focus rings and state fills 3:1. jsdom can't see color, so check it in a real browser.
  • Key lists by value or id, never by index.
  • Right to left needs no provider. Components read the direction from the page.
  • Comments are rare. Write one only when a reader would get the code wrong without it, like a browser quirk or a trade-off, in one or two lines. Never comment what the code does, what a value is, or which section starts here, and no JSDoc blocks on app code.
  • Don't hand-roll what we ship. Before you write any
    role=
    attribute, look for the component in the table in references/build-interface.md. A
    div
    with
    role="listbox"
    ,
    "menu"
    ,
    "dialog"
    ,
    "tablist"
    ,
    "separator"
    ,
    "switch"
    ,
    "slider"
    ,
    "radiogroup"
    ,
    "toolbar"
    or
    "tree"
    next to an installed ui-sdk package is almost always a bug.
  • 从入口导入。 每个组件都有自己的入口,例如
    @ui-sdk/react/select
    。框架包不支持从根入口导入。绝不导入
    @ui-sdk/core/internal/*
    。
  • 各处保持统一结构。 根组件及其部件应按照组件页面中 Composition 部分所示的方式嵌套。要更改某个部件的元素,请使用
    render
    ,绝不要使用
    as
    prop。
  • 默认或受控。 使用
    defaultValue
    初始化,或使用
    value
    搭配
    onValueChange(value, details)
    进行控制(采用各框架惯用写法:Vue 使用
    v-model
    ,Svelte 使用
    bind:value
    ,Web Components 使用属性和事件)。
    details
    包含
    reason
    、
    source
    和
    cancel()
    。
  • 为每个控件命名。 使用组件的标签部件(
    FieldLabel
    、
    SelectLabel
    、
    DialogTitle
    ),在没有可见文本时使用
    aria-label
    。使用屏幕阅读器的用户和 Agent 都依靠名称查找控件。
  • 根据状态设置样式。 针对
    data-slot
    、
    data-open
    或
    data-pressed
    等状态属性,以及每个组件列出的 CSS 变量编写样式。不要使用内联样式表达状态,也不要使用自动生成的 id。当应用使用
    web.css
    时,先阅读 references/styles.md:它会绘制图标并设置从标记中看不出的尺寸。
  • 声明 ui-sdk 层。 在全局样式表顶部放置
    @layer ui-sdk;
    。如果存在
    @import "tailwindcss"
    ,应将其放在后面。
  • 检查颜色。 文本与其背景的对比度需达到 4.5:1,控件边缘、焦点环和状态填充需达到 3:1。jsdom 无法呈现颜色,因此应在真实浏览器中检查。
  • 列表项的 key 应使用 value 或 id,绝不能使用索引。
  • 从右到左布局无需 Provider。 组件会从页面读取方向。
  • 注释应少写。 只有当缺少注释会让读者误解代码时才写,例如说明浏览器怪癖或权衡取舍,限一至两行。绝不注释代码做了什么、某个值是什么,或某一部分从哪里开始;应用代码中不要添加 JSDoc 块。
  • 不要自行实现我们已经提供的功能。 在编写任何
    role=
    属性前,先在 references/build-interface.md 的表格中查找对应组件。在已安装 ui-sdk 包的项目中,为带有
    role="listbox"
    、
    "menu"
    、
    "dialog"
    、
    "tablist"
    、
    "separator"
    、
    "switch"
    、
    "slider"
    、
    "radiogroup"
    、
    "toolbar"
    或
    "tree"
    的
    div
    几乎总是 bug。

When you're done

完成时

  1. Typecheck. If the root
    tsconfig.json
    has
    "files": []
    and
    references
    ,
    npx tsc --noEmit
    checks nothing: run
    npx tsc -b
    or
    npx tsc --noEmit -p <app config>
    . For Svelte, run
    svelte-check
    ; for Vue,
    vue-tsc
    .
  2. Write and run tests (see testing.md). Every task gets tests, and every interface gets at least the agent test from agent-ready.md. If a test finds a bug in code you were asked only to test, mark it
    test.fails
    (or
    it.fails
    ) with a one-line reason, report the bug, and leave the suite green.
  3. Read every comment in your diff. Delete it unless it names a browser quirk, an APG rule or a trade-off, and cut what's left to two lines. Turn JSDoc on app code into a plain comment or delete it. Never tell the reader to replace something.
  4. Report each command you ran with its exit code, anything you couldn't check, and anything the docs or types got wrong or left out.
  1. 执行类型检查。 如果根
    tsconfig.json
    包含
    "files": []
    和
    references
    ,那么
    npx tsc --noEmit
    不会检查任何内容:应运行
    npx tsc -b
    或
    npx tsc --noEmit -p <app config>
    。对于 Svelte,运行
    svelte-check
    ;对于 Vue,运行
    vue-tsc
    。
  2. 编写并运行测试(见
    testing.md
    )。每个任务都要编写测试,每个界面至少要包含
    agent-ready.md
    中的 Agent 测试。如果测试发现你仅被要求测试的代码中存在 bug,请使用
    test.fails
    (或
    it.fails
    )标记,并附上一行原因;报告该 bug,同时让测试套件保持绿色状态。
  3. 阅读 diff 中的每一条注释。 删除所有注释,除非它说明的是浏览器怪癖、APG 规则或权衡取舍;保留的注释最多两行。将应用代码中的 JSDoc 改为普通注释或删除。绝不要告诉读者需要替换某段内容。
  4. 报告你运行的每条命令及其退出码、无法检查的内容,以及文档或类型定义中错误或遗漏的内容。