Token导航 LogoToken导航TokenDH.com
前端设计只读github未标认证来源可访问许可证需确认审计通过

build-ui构建用户界面

Agent Skill

用于辅助界面设计、视觉规范、排版、配色、布局和交互体验优化。它适合让 Agent 根据产品场景整理页面结构、生成 UI 方案、检查视觉一致性或改进组件层级。使用时需要结合现有品牌、设计系统和用户任务,不应只堆装饰元素;涉及真实页面改动时,应通过截图或浏览器预览检查文本溢出、对齐和响应式表现。

总安装

494

周安装

21

GitHub Stars

13

下载量

173
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:build-ui(构建用户界面)
来源仓库:https://github.com/dcl-regenesislabs/opendcl
仓库路径:skills/build-ui
安装命令:
npx skills add https://github.com/dcl-regenesislabs/opendcl --skill build-ui
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/dcl-regenesislabs/opendcl --skill build-ui

简介

用于辅助界面设计、视觉规范和交互体验优化。

  • 适合生成 UI 方案、检查视觉一致性和改进组件层级。
  • 需结合品牌和设计系统,避免只堆装饰元素。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。
  • 涉及页面改动时应通过截图或预览检查文本溢出和对齐。
  • build-ui 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Building UI with React-ECS

Decentraland SDK7 uses a React-like JSX system for 2D UI overlays.

When to Use Which UI Approach

NeedApproachComponent
Screen-space HUD, menus, buttonsReact-ECS (this skill)UiEntity, Label, Button, Input, Dropdown
3D text floating in the worldTextShape + BillboardSee advanced-rendering skill
Open a web pageopenExternalUrlSee scene-runtime skill
Clickable objects in 3D spacePointer eventsSee add-interactivity skill

Use React-ECS for any 2D overlay: scoreboards, health bars, dialogs, inventories, settings menus. Use TextShape for labels above NPCs or objects in the 3D world.

Setup

File: src/ui.tsx

import ReactEcs, { ReactEcsRenderer, UiEntity, Label, Button } from '@dcl/sdk/react-ecs'

const MyUI = () => (
  <UiEntity
    uiTransform={{
      width: '100%',
      height: '100%',
      justifyContent: 'center',
      alignItems: 'center'
    }}
  >
    <Label value="Hello Decentraland!" fontSize={24} />
  </UiEntity>
)

export function setupUi() {
  ReactEcsRenderer.setUiRenderer(MyUI)
}

File: src/index.ts

import { setupUi } from './ui'

export function main() {
  setupUi()
}

tsconfig.json (already configured by /init)

The SDK template already includes the required JSX settings — do NOT modify tsconfig.json:

  • "jsx": "react-jsx"
  • "jsxImportSource": "@dcl/sdk/react-ecs-lib"

Core Components

UiEntity (Container)

import { Color4 } from '@dcl/sdk/math'

<UiEntity
  uiTransform={{
    width: 300,              // Pixels or '50%'
    height: 200,
    positionType: 'absolute', // 'absolute' or 'relative' (default)
    position: { top: 10, right: 10 }, // Only with absolute
    flexDirection: 'column',  // 'row' | 'column'
    justifyContent: 'center', // 'flex-start' | 'center' | 'flex-end' | 'space-between'
    alignItems: 'center',     // 'flex-start' | 'center' | 'flex-end' | 'stretch'
    padding: { top: 10, bottom: 10, left: 10, right: 10 },
    margin: { top: 5 },
    display: 'flex'           // 'flex' | 'none' (hide)
  }}
  uiBackground={{
    color: Color4.create(0, 0, 0, 0.8) // Semi-transparent black
  }}
/>

Label (Text)

import { Color4 } from '@dcl/sdk/math'

<Label
  value="Score: 100"
  fontSize={18}
  color={Color4.White()}
  textAlign="middle-center"
  font="sans-serif"
  uiTransform={{ width: 200, height: 30 }}
/>

Button

<Button
  value="Click Me"
  variant="primary"  // 'primary' | 'secondary'
  fontSize={16}
  uiTransform={{ width: 150, height: 40 }}
  onMouseDown={() => {
    console.log('Button clicked!')
  }}
/>

Input

import { Input } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

<Input
  placeholder="Type here..."
  fontSize={14}
  color={Color4.White()}
  uiTransform={{ width: 250, height: 35 }}
  onChange={(value) => {
    console.log('Value changing:', value)
  }}
  onSubmit={(value) => {
    console.log('Submitted:', value)
  }}
/>

Dropdown

import { Dropdown } from '@dcl/sdk/react-ecs'

<Dropdown
  options={['Option A', 'Option B', 'Option C']}
  selectedIndex={0}
  onChange={(index) => {
    console.log('Selected:', index)
  }}
  uiTransform={{ width: 200, height: 35 }}
  fontSize={14}
/>

State Management

Use module-level variables for UI state (React hooks are NOT available):

import { Color4 } from '@dcl/sdk/math'

let score = 0
let showMenu = false

const GameUI = () => (
  <UiEntity uiTransform={{ width: '100%', height: '100%' }}>
    {/* HUD - always visible */}
    <Label
      value={`Score: ${score}`}
      fontSize={20}
      uiTransform={{
        positionType: 'absolute',
        position: { top: 10, left: 10 }
      }}
    />

    {/* Menu - conditionally shown */}
    {showMenu && (
      <UiEntity
        uiTransform={{
          width: 300,
          height: 400,
          positionType: 'absolute',
          position: { top: '50%', left: '50%' }
        }}
        uiBackground={{ color: Color4.create(0.1, 0.1, 0.1, 0.9) }}
      >
        <Label value="Game Menu" fontSize={24} />
        <Button
          value="Resume"
          variant="primary"
          onMouseDown={() => { showMenu = false }}
          uiTransform={{ width: 200, height: 40 }}
        />
      </UiEntity>
    )}
  </UiEntity>
)

// Update state from game logic
export function addScore(points: number) {
  score += points
}

export function toggleMenu() {
  showMenu = !showMenu
}

Common UI Patterns

Health Bar

import { Color4 } from '@dcl/sdk/math'

let health = 100

const HealthBar = () => (
  <UiEntity
    uiTransform={{
      width: 200, height: 20,
      positionType: 'absolute',
      position: { bottom: 20, left: '50%' }
    }}
    uiBackground={{ color: Color4.create(0.3, 0.3, 0.3, 0.8) }}
  >
    <UiEntity
      uiTransform={{ width: `${health}%`, height: '100%' }}
      uiBackground={{ color: Color4.create(0.2, 0.8, 0.2, 1) }}
    />
  </UiEntity>
)

Image Background

<UiEntity
  uiTransform={{ width: 200, height: 200 }}
  uiBackground={{
    textureMode: 'stretch',
    texture: { src: 'images/logo.png' }
  }}
/>

Screen Dimensions

Read screen size via UiCanvasInformation:

import { UiCanvasInformation } from '@dcl/sdk/ecs'

engine.addSystem(() => {
  const canvas = UiCanvasInformation.getOrNull(engine.RootEntity)
  if (canvas) {
    console.log('Screen:', canvas.width, 'x', canvas.height)
  }
})

Nine-Slice Textures

Use textureSlices for scalable UI backgrounds (buttons, panels) that don't stretch corners:

<UiEntity
  uiTransform={{ width: 200, height: 100 }}
  uiBackground={{
    textureMode: 'nine-slices',
    texture: { src: 'images/panel.png' },
    textureSlices: { top: 0.1, bottom: 0.1, left: 0.1, right: 0.1 }
  }}
/>

Hover Events

Respond to mouse enter/leave for hover effects:

<UiEntity
  uiTransform={{ width: 100, height: 40 }}
  onMouseEnter={() => { isHovered = true }}
  onMouseLeave={() => { isHovered = false }}
  uiBackground={{ color: isHovered ? Color4.White() : Color4.Gray() }}
/>

Flex Wrap

Allow UI children to wrap to the next line:

<UiEntity uiTransform={{ flexWrap: 'wrap', width: 300 }}>
  {items.map(item => (
    <UiEntity key={item.id} uiTransform={{ width: 80, height: 80, margin: 4 }} />
  ))}
</UiEntity>

Dropdown Extras

The Dropdown component supports additional props:

<Dropdown
  options={['Option A', 'Option B', 'Option C']}
  selectedIndex={selectedIdx}
  onChange={(idx) => { selectedIdx = idx }}
  fontSize={14}
  color={Color4.White()}
  disabled={false}
/>

Troubleshooting

ProblemCauseSolution
UI not appearing at allMissing ReactEcsRenderer.setUiRenderer() callAdd ReactEcsRenderer.setUiRenderer(MyUI) in main() or setupUi()
UI elements overlappingMissing flexDirection or wrong layoutSet flexDirection: 'column' on the parent container
Button clicks not registeringMissing onMouseDown handlerAdd onMouseDown={() => {...}} to the Button or UiEntity
JSX errors at compile timeFile extension is .ts instead of .tsxRename the file to .tsx
Multiple UIs fightingMore than one setUiRenderer callOnly call setUiRenderer once — combine all UI into a single root component
Text not visibleText color matches backgroundSet contrasting color on Label or uiText
World interactions instead of screen UI? See the add-interactivity skill for click handlers and pointer events on 3D objects.

Important Notes

  • React hooks (useState, useEffect, etc.) are NOT available — use module-level variables
  • The UI renderer re-renders every frame, so state changes are reflected immediately
  • UI is rendered as a 2D overlay on top of the 3D scene
  • Use display: 'none' in uiTransform to hide elements without removing them
  • File extension must be .tsx for JSX support
  • Only one ReactEcsRenderer.setUiRenderer() call per scene — combine all UI into one root component

For full component props (UiEntity, Label, Button, Input, Dropdown), layout patterns, and responsive design, see {baseDir}/references/ui-components.md.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.23%
按下载量换算61

Claude

29.59%
按下载量换算51

Cursor

19.29%
按下载量换算33

Gemini CLI

8.06%
按下载量换算14

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills