Constela : 타이머, 폼, 포털 등으로 React/Next.js 수준의 표현력 달성
I’m sorry, but I can’t access external websites to retrieve the article’s text. If you paste the content you’d like translated here, I’ll be happy to translate it into Korean while preserving the original formatting and markdown.
Constela란?
Constela는 AI‑생성 인터페이스에 최적화된 컴파일러‑우선 UI 언어입니다. JavaScript를 작성하는 대신, 제한된 JSON DSL로 UI 동작을 기술하고, 이를 검증·분석·컴파일하여 최소한의 런타임 코드로 변환합니다. 최신 릴리스에서는 대부분의 일반적인 사용 사례에 대해 React/Next.js와 기능적 동등성을 달성했습니다.
타이머 동작
delay
지정된 지연 후에 단계들을 실행합니다.
{
"name": "showNotification",
"steps": [
{
"do": "set",
"target": "notification",
"value": { "expr": "lit", "value": "Saved!" }
},
{
"do": "delay",
"ms": { "expr": "lit", "value": 3000 },
"then": [
{
"do": "set",
"target": "notification",
"value": { "expr": "lit", "value": "" }
}
]
}
]
}
interval
지정된 간격으로 동작을 반복 실행합니다. 타이머 ID는 result에 저장됩니다.
{
"name": "startPolling",
"steps": [
{
"do": "interval",
"ms": { "expr": "lit", "value": 5000 },
"action": "fetchLatestData",
"result": "pollingTimerId"
}
]
}
clearTimer
ID를 사용해 실행 중인 타이머를 중지합니다.
{
"name": "stopPolling",
"steps": [
{
"do": "clearTimer",
"target": { "expr": "state", "name": "pollingTimerId" }
}
]
}
확장 이벤트 데이터
이벤트 핸들러가 풍부한 이벤트 데이터에 접근할 수 있습니다.
| 이벤트 유형 | 사용 가능한 변수 |
|---|---|
| 입력 | value, checked |
| 키보드 | key, code, ctrlKey, shiftKey, altKey, metaKey |
| 마우스 | clientX, clientY, pageX, pageY, button |
| 터치 | touches (array of clientX, clientY, pageX, pageY) |
| 스크롤 | scrollTop, scrollLeft |
| 파일 입력 | files (array of name, size, type) |
키보드 단축키 예시
{
"onKeyDown": {
"event": "keydown",
"action": "handleShortcut",
"payload": {
"key": { "expr": "var", "name": "key" },
"isCtrl": { "expr": "var", "name": "ctrlKey" }
}
}
}
파일 입력 예시
{
"kind": "element",
"tag": "input",
"props": {
"type": { "expr": "lit", "value": "file" },
"multiple": { "expr": "lit", "value": true },
"onChange": {
"event": "change",
"action": "handleFiles",
"payload": { "expr": "var", "name": "files" }
}
}
}
폼 기능
프로그래밍 방식 포커스 제어
// Focus an element
{ "do": "focus", "target": { "expr": "ref", "name": "emailInput" }, "operation": "focus" }
// Select text
{ "do": "focus", "target": { "expr": "ref", "name": "codeInput" }, "operation": "select" }
// Blur (unfocus)
{ "do": "focus", "target": { "expr": "ref", "name": "searchInput" }, "operation": "blur" }
유효성 상태 (HTML5 제약 유효성 검사 API)
{
"kind": "element",
"tag": "input",
"ref": "emailInput",
"props": {
"type": { "expr": "lit", "value": "email" },
"required": { "expr": "lit", "value": true }
}
}
유효성 오류 표시:
{
"kind": "if",
"condition": {
"expr": "not",
"operand": {
"expr": "validity",
"ref": "emailInput",
"property": "valid"
}
},
"then": {
"kind": "text",
"value": {
"expr": "validity",
"ref": "emailInput",
"property": "message"
}
}
}
사용 가능한 유효성 속성
valid– 전체 유효성valueMissing– 필수 필드가 비어 있음typeMismatch– 타입이 일치하지 않음 (email, url 등)patternMismatch– 패턴이 일치하지 않음tooLong/tooShort– 길이 제약 위반rangeUnderflow/rangeOverflow– 범위 제약 위반message– 브라우저의 유효성 검사 메시지
포털 및 옵저버
포털
DOM의 다른 위치에 콘텐츠를 렌더링합니다 (예: 모달, 툴팁).
{
"kind": "portal",
"target": "body",
"children": [
{
"kind": "element",
"tag": "div",
"props": { "className": { "expr": "lit", "value": "modal-overlay" } },
"children": [
{
"kind": "element",
"tag": "div",
"props": { "className": { "expr": "lit", "value": "modal-content" } },
"children": [ /* modal content */ ]
}
]
}
]
}
대상 옵션
"body"–document.body"head"–document.head- CSS 선택자(예:
"#modal-root")
IntersectionObserver (무한 스크롤)
{
"kind": "element",
"tag": "div",
"ref": "sentinel",
"props": {
"onIntersect": {
"event": "intersect",
"action": "loadMoreItems",
"options": {
"threshold": 0.5,
"rootMargin": "100px"
}
}
}
}
디바운스 & 스로틀
이벤트 핸들러가 실행되는 빈도를 제어합니다.
디바운스 (마지막 이벤트 후 300 ms에 실행)
{
"onInput": {
"event": "input",
"action": "search",
"debounce": 300
}
}
스로틀 (최대 100 ms마다 한 번 실행)
{
"onScroll": {
"event": "scroll",
"action": "trackScroll",
"throttle": 100
}
}
일반 UI 패턴
| Pattern | Constela Feature |
|---|---|
| 자동 숨김 알림 | delay step |
| 실시간 데이터 폴링 | interval + clearTimer |
| 키보드 단축키 | Extended keyboard event data |
| 파일 업로드 UI | files event data |
| 폼 검증 | validity expression |
| 모달 대화창 | portal node |
| 무한 스크롤 | intersect event |
| 입력 즉시 검색 | debounce option |
시작하기
npm install @constela/start
mkdir -p src/routes
echo '{"version":"1.0","state":{},"actions":[],"view":{"kind":"element","tag":"div","children":[{"kind":"text","value":{"expr":"lit","value":"Hello Constela!"}}]}}' > src/routes/index.json
npx constela dev
리소스
- GitHub Repository: https://github.com/constela/constela
- Official Website: https://constela.dev