벨트 CLI 스킬 설치:
npx skills add belt-sh/cli
위젯 렌더러
JSON을 통한 선언적 UI - ui.inference.sh

빠른 시작
npx shadcn@latest add https://ui.inference.sh/r/widgets.json
기본 사용법
import { WidgetRenderer } from "@/registry/blocks/widgets/widget-renderer"
import type { Widget, WidgetAction } from "@/registry/blocks/widgets/types"
const widget: Widget = {
type: 'ui',
title: '내 위젯',
children: [
{ type: 'text', value: '안녕하세요, 세계!' },
{ type: 'button', label: '클릭하세요', onClickAction: { type: 'click' } },
],
}
<WidgetRenderer
widget={widget}
onAction={(action, formData) => console.log(action, formData)}
/>
위젯 유형
레이아웃
{ "type": "row", "gap": 2, "children": [...] }
{ "type": "col", "gap": 2, "children": [...] }
{ "type": "box", "background": "gradient-ocean", "padding": 4, "radius": "lg", "children": [...] }
타이포그래피
{ "type": "title", "value": "제목", "size": "2xl", "weight": "bold" }
{ "type": "text", "value": "본문 텍스트", "variant": "bold" }
{ "type": "caption", "value": "작은 텍스트" }
{ "type": "label", "value": "필드 레이블", "fieldName": "email" }
인터랙티브
{ "type": "button", "label": "제출", "variant": "default", "onClickAction": { "type": "submit" } }
{ "type": "input", "name": "email", "placeholder": "이메일 입력" }
{ "type": "textarea", "name": "message", "placeholder": "메시지 입력" }
{ "type": "select", "name": "plan", "options": [{ "value": "pro", "label": "프로" }] }
{ "type": "checkbox", "name": "agree", "label": "동의합니다", "defaultChecked": false }
표시
{ "type": "badge", "label": "새로운", "variant": "secondary" }
{ "type": "icon", "iconName": "check", "size": "lg" }
{ "type": "image", "src": "https://...", "alt": "이미지", "width": 100, "height": 100 }
{ "type": "divider" }
예시: 항공권 카드
const flightWidget: Widget = {
type: 'ui',
children: [
{
type: 'box', background: 'gradient-ocean', padding: 4, radius: 'lg', children: [
{
type: 'row', justify: 'between', children: [
{
type: 'col', gap: 1, children: [
{ type: 'caption', value: '출발' },
{ type: 'title', value: 'SFO', size: '2xl', weight: 'bold' },
]
},
{ type: 'icon', iconName: 'plane', size: 'lg' },
{
type: 'col', gap: 1, align: 'end', children: [
{ type: 'caption', value: '도착' },
{ type: 'title', value: 'JFK', size: '2xl', weight: 'bold' },
]
},
]
},
]
},
],
}
예시: 폼
const formWidget: Widget = {
type: 'ui',
title: '연락처 폼',
asForm: true,
children: [
{
type: 'col', gap: 3, children: [
{ type: 'input', name: 'name', placeholder: '이름' },
{ type: 'input', name: 'email', placeholder: '이메일 주소' },
{ type: 'textarea', name: 'message', placeholder: '메시지' },
{ type: 'button', label: '보내기', variant: 'default', onClickAction: { type: 'submit' } },
]
},
],
}
그라데이션
| 이름 | 설명 |
|---|---|
gradient-ocean | 파란 청록 그라데이션 |
gradient-sunset | 주황 분홍 그라데이션 |
gradient-purple | 보라색 그라데이션 |
gradient-cool | 시원한 파란색 그라데이션 |
gradient-midnight | 어두운 파란색 그라데이션 |
액션 처리
const handleAction = (action: WidgetAction, formData?: WidgetFormData) => {
switch (action.type) {
case 'submit':
console.log('폼 데이터:', formData)
break
case 'click':
console.log('버튼이 클릭되었습니다')
break
}
}
관련 스킬
# 전체 에이전트 컴포넌트
npx skills add inference-sh/skills@agent-ui
# 채팅 UI 블록
npx skills add inference-sh/skills@chat-ui
# 도구 UI
npx skills add inference-sh/skills@tools-ui
문서
- 위젯 개요 - 위젯 이해하기
- 위젯 스키마 - 위젯 JSON 구조
- UI를 생성하는 에이전트 - 생성형 UI 구축하기
컴포넌트 문서: ui.inference.sh/blocks/widgets