실용적인 예제와 라이브 데모.
예제를 선택하면 라이브 미리보기와 소스 코드를 나란히 표시하는 전체 화면이 열립니다.
컴포넌트
4정적·동적 매개변수, 자식, 객체의 참조 동일성으로 연결되는 목록, 중첩 데이터를 사용하는 일반 함수입니다. 각 미리보기에서 마운트 횟수를 확인할 수 있습니다.
정적 및 동적 매개변수
값 매개변수는 컴포넌트를 만들 때 한 번 읽습니다. 함수 매개변수는 update()마다 읽습니다. 두 경우 모두 컴포넌트 자체는 한 번만 실행됩니다. 마운트 횟수로 확인할 수 있습니다.
자식 노드와 수정자
컴포넌트는 전개 구문으로 빌더, 텍스트, 속성 객체, 수정자를 자식으로 전달합니다. 조건부 내용은 when()에 넣으므로 이를 감싸는 컴포넌트를 다시 만들지 않습니다.
목록의 객체의 참조 동일성
list()는 항목이 배열에 있는 동안 해당 행을 유지합니다. 입력이나 포커스를 잃지 않고 정렬, 삽입, 이름 변경이 가능합니다. 스위치를 켜면 매 업데이트마다 객체를 복제해 동일성을 깨뜨리는 비용을 보여줍니다.
중첩 데이터
작업을 가진 구성원들로 이루어진 팀입니다. 계층마다 컴포넌트 하나와 중첩된 list()를 사용하고, 같은 객체를 읽는 함수로 개수를 계산합니다. 깊은 곳의 변경은 해당 노드만 패치합니다.
API
13각 구성 요소를 보여주는 작은 데모입니다. 문서에 포함된 것과 같습니다.
태그 빌더
빌더는 속성, 정적 자식, 동적 텍스트를 받습니다. Rename은 상태를 변경한 다음 update()를 호출합니다.
컴포넌트
컴포넌트는 일반 함수입니다. Counter()를 호출할 때마다 자체 카운트를 유지합니다.
속성
속성 값은 함수일 수 있습니다. 두 번째 버튼은 busy를 전환하고 update()를 호출합니다. Save 버튼의 disabled와 aria-busy가 이에 따라 바뀝니다.
이벤트
onInput과 onKeyDown은 일반 속성입니다. 입력한 다음 Escape를 눌러 지웁니다.
생명주기
onMount가 인터벌을 시작하고 정리 함수를 반환합니다. 마운트 해제 시 정리 함수가 실행되므로 다시 마운트할 때까지 카운트가 멈춥니다.
명시적 업데이트
count++는 변수만 변경합니다. 이 버튼이나 페이지의 다른 동작이 다음 update()를 호출하면 텍스트가 반영됩니다.
동적 값
이름을 수정해 보세요. 정적 텍스트는 요소를 만들 때 고정되며, 동적 텍스트는 update()마다 다시 계산됩니다. forceUpdate()는 트리를 다시 구성하므로 정적 텍스트도 반영됩니다.
update()
update()는 데이터가 바뀌지 않았더라도 모든 동적 값을 실행합니다. 이 페이지의 다른 데모를 사용해도 카운트가 증가합니다.
scope()
두 버튼 모두 항목을 추가하고 사용자 이름을 바꿉니다. update('cart')는 해당 스코프의 패널만 업데이트합니다.
when()
가장 먼저 참이 되는 조건을 사용합니다. 참인 조건이 없으면 .else()를 렌더링합니다. 새 분기는 처음부터 만듭니다.
list()
행은 객체의 참조 동일성으로 연결됩니다. 행의 체크박스를 선택한 다음 Reverse를 눌러 보세요. 체크박스를 포함한 같은 <li>가 이동합니다.
region() 및 into()
메인 영역을 스택 방식으로 구성하고 보조 영역도 둔 레이아웃을 외부에서 채웁니다. Home에 입력한 뒤 대화 상자를 열었다 닫아도 텍스트는 유지됩니다. Article은 into() 한 번으로 두 영역을 채웁니다.
forceUpdate()
update()는 동적인 lang 행만 업데이트합니다. forceUpdate()는 App을 다시 호출해 같은 <h1>을 패치합니다. 명시적인 형식은 페이지 전체가 아닌 이 트리만 다시 구성합니다.
스타일링
3클래스 생성, 클래스 합성, 작은 테마 사용을 살펴봅니다.
폼
3일반 상태에 대한 함수로 검증을 처리합니다. 조작한 필드, 단계, 동적 행을 다룹니다.
필드 검증
일반 상태를 검사하는 함수로 검증 규칙을 정의합니다. 사용자가 조작한 필드에 오류를 표시하고, 디바운스를 적용한 비동기 검사의 진행 상태를 보여주며, 모든 검사가 끝날 때까지 제출을 기다립니다.
다단계 마법사
하나의 데이터 객체를 공유하는 세 단계를 when() 분기로 구성합니다. 다음 버튼은 해당 단계의 필드를 조작한 것으로 표시하고 검증을 통과한 경우에만 다음 단계로 이동합니다. 검토 화면에는 모든 값과 편집 링크가 표시됩니다.
동적 행
청구서 항목 배열을 list()로 렌더링합니다. 각 행은 개별적으로 검증하고 유효한 행만 합계에 반영합니다. 다른 행을 추가하거나 삭제해도 입력값은 유지됩니다.
SVG
27일반 데이터, 포인터 이벤트, update()로 구동하는 SVG 태그 빌더 기반 차트, 애니메이션, 도구, 게임입니다.
막대 차트
배열의 항목마다 사각형을 만듭니다. y와 height는 데이터에 따라 계산되는 함수이므로 update()를 호출하면 막대가 움직입니다.
꺾은선형 차트
점들을 바탕으로 d를 생성하는 경로에 그라데이션 영역과 점마다 원 하나를 표시합니다.
도넛 차트
조각마다 원을 하나씩 만듭니다. stroke-dasharray로 각 조각이 차지하는 비율을, stroke-dashoffset으로 시작 위치를 지정합니다.
SVG 애니메이션
SMIL도 빌더로 구성합니다. animateSvg는 태양이 맥동하게 만들고 animateTransformSvg는 행성을 공전시킵니다. 동적 dur 값으로 속도를 조절합니다.
게이지
stroke-dashoffset으로 채워지는 호와 CSS transform으로 회전하는 바늘입니다. 둘 다 숫자 하나에 따라 계산됩니다.
레이더 차트
5개 축에 5개 값이 있습니다. 모양은 데이터에서 d가 계산되는 하나의 경로이므로 update()는 이를 변형합니다.
히트맵
fill-opacity가 단계 값에 따라 달라지는 사각형 격자입니다. 셀을 클릭하면 값이 올라가며 자식 요소인 titleSvg가 툴팁을 표시합니다.
호버 툴팁
SVG 요소에 대한 포인터 이벤트입니다. onPointerEnter는 활성 포인트를 선택하고 툴팁 그룹이 해당 포인트로 이동합니다.
곡선 편집기
3차 베지어 곡선의 핸들을 드래그해 보세요. onPointerDown으로 점을 선택하고 svg의 onPointerMove로 점을 이동하면 경로가 따라 움직입니다.
시계
시곗바늘은 시간에 따라 transform이 계산되는 선입니다. onMount가 타이머를 시작하고 정리 함수를 반환합니다.
아이콘 토글
CSS 전환으로 X 모양이 되는 메뉴 아이콘과 클릭하면 SMIL 애니메이션으로 통통 튀는 하트입니다.
라이브 스트림
타이머에 따라 두 데이터 계열이 왼쪽으로 흐릅니다. 한 틱과 같은 길이의 CSS 전환으로 부드럽게 이동하며 마우스를 올리면 각 표본의 값을 확인할 수 있습니다.
캔들스틱 차트
40개의 슬롯이 각자의 캔들 데이터를 읽습니다. 시간 범위를 바꾸거나 이동평균을 켜고 끄고, 마우스를 올려 수치를 확인하거나 실시간 캔들이 갱신되는 모습을 지켜보세요.
막대 차트 레이스
막대 10개는 계속 DOM에 남아 있습니다. 순위에 따라 translateY가 정해지므로 값이 바뀔 때마다 전환 효과로 각 막대가 해당 행으로 이동합니다.
누적 영역 차트
영역 4개가 누적, 스트림, 백분율 레이아웃 사이에서 변합니다. 계열을 숨기면 해당 영역의 두께만 0이 되므로 모든 경로의 명령 구조가 그대로 유지됩니다.
트리맵
정사각형에 가깝게 배치한 영역을 클릭해 하위 항목을 탐색합니다. 측정 지표를 바꾸면 각 셀이 새 위치로 이동하고 그룹을 클릭하면 하위 항목이 표시됩니다.
라이브 히스토그램
네 가지 분포에서 표본이 계속 들어옵니다. 변경될 때마다 구간별 빈도를 다시 계산하고, 표본에 맞춰 추정한 종 모양 곡선이 평균을 따라 움직입니다. 슬라이더로 구간 수를 조절합니다.
드로잉 패드
포인터 이벤트는 폴리라인을 그립니다. list()는 스트로크당 하나씩 렌더링하고 그리는 중인 선은 update()마다 길어집니다.
회전식 손잡이
사용자 정의 슬라이더: 포인터의 각도에 따라 값이 설정되고, 화살표 키가 단계적으로 이동하며, pathLength="100"은 값을 대시로 바꿉니다.
컬러 휠
각도로 색조를, 중심에서의 거리로 채도를 선택합니다. 부채꼴 90개, 방사형 그라데이션, 어두운 원판으로 색상환을 구성합니다.
스피로그래프
바퀴가 고리 안에서 굴러가고 펜이 궤적을 그립니다. 프레임마다 선을 조금씩 늘리고 해당 scope()만 업데이트합니다.
튀는 공
requestAnimationFrame 루프의 중력, 벽 및 충돌. 뒤로 당겼다가 놓아 공을 발사하세요.
끈끈한 방울
블러와 색상 행렬 필터로 방울들이 녹아 붙는 듯한 효과를 만듭니다. 원으로 된 잔상이 포인터를 따라 움직입니다.
힘 기반 그래프
노드는 서로 밀어내고 링크는 서로 당깁니다. 시뮬레이션이 점차 안정되며 배치가 멈춥니다. 노드를 드래그하거나 클릭해서 자식 노드를 추가해 보세요.
브러시 및 줌
전체 보기에서 범위를 드래그해 위쪽 차트를 확대합니다. 선택 범위를 따라가는 clipPath로 해당 부분에 색을 입힙니다.
틱택토
컴퓨터와 대결해 보세요. when()이 표시를 하나씩 추가하고 대시 속성에 적용한 CSS 애니메이션이 그려지는 효과를 만듭니다.
원형 텍스트
배지에 표시할 텍스트를 입력하세요. textPath는 원 주위로 텍스트를 구부리고 textLength는 이를 정확히 한 바퀴에 맞춥니다.
라우팅
6라우트 테이블, 매칭, 활성 라우트, 레이어, 로더를 다룹니다. nuclo-router는 별도 패키지입니다: npm install nuclo nuclo-router.
라우팅된 앱
프레임 안에서 자체 라우터로 실행되는 앱입니다. 라우트 테이블, outlet() 하나, 일반 링크, 로딩 상태, 404를 갖춥니다. 여러 링크로 이동한 다음 뒤로 가기를 사용해 보세요.
중첩 경로
Docs는 하위 라우트가 있는 레이아웃입니다. 주제는 outlet()에 렌더링되고 ./topic 링크는 레이아웃의 라우트를 기준으로 해석됩니다. 메모를 입력한 뒤 주제를 바꿔 보세요. 레이아웃은 다시 생성되지 않습니다.
라우트 로더
게시물 페이지는 페이지 생성 전에 실행할 load()를 내보냅니다. 기다리는 동안 router.pending를 확인하고, 오류가 발생하는 게시물에서 오류 상태와 재시도 동작을 살펴보세요.
레이어
주문 폼에서 고객 페이지를 레이어로 열고 결과를 기다립니다. 폼을 다시 렌더링하지 않으므로 메모가 유지됩니다. 저장하면 push의 Promise가 결과로 이행되고 취소하거나 뒤로 가면 레이어가 닫힙니다.
다중 라우터 및 로딩
라우터 2개, 스피너 2개. 상점 레이아웃과 해당 섹션에는 모두 load()가 있습니다. 하나의 router.pending 아래에서 병렬로 실행됩니다. 사이드바에는 onNavigate에서 새로 고쳐진 자체 로딩 플래그를 사용하여 생성되었지만 시작되지 않은 자체 라우터가 있습니다.
패턴 매칭
정적, :param 및 *rest 패턴과 두 상위 항목 아래에 마운트된 섹션 테이블. 경로를 입력하고 아무것도 로드하지 않고 해결되는 match()를 살펴보세요.
앱
15전체 화면으로 실행되는 큰 프로그램과 탭에서 볼 수 있는 실제 소스 코드입니다. 창이 있는 데스크톱, 데이터 그리드, 채팅, 게임, 편집기, 자체 상태를 관리하는 라이브러리를 살펴봅니다.
페이지 빌더
페이지에 직접 쓰고, 그립을 드래그하여 블록 순서를 바꾸거나 레이아웃으로 이동하고, /를 눌러 삽입하고, 마우스 오른쪽 버튼을 클릭하여 작업을 수행하세요. 그리드 및 플렉스 레이아웃 스타일을 지정하고, 편집을 실행 취소하고, 휴대폰 크기로 미리 보고, HTML을 내보냅니다.
알고리즘 스테퍼
엔진은 일반 JavaScript로, 배열을 변경하고 단계마다 yield하는 제너레이터입니다. 플레이어가 next()와 update()를 호출합니다. 막대는 같은 객체를 사용하는 list()이므로 교환 시 요소 두 개만 이동합니다.
칸반 보드
팀 작업 보드입니다. 작업 추가, 담당자 지정, 대화 상자 편집, 담당자 필터와 검색, 열 사이 드래그, 삭제 취소를 지원합니다. 열과 카드는 같은 객체를 유지하는 일반 배열이며 이동은 모두 splice()로 처리합니다. 행은 동일성으로 연결되므로 드래그, 정렬, 할당, 편집 시 기존 요소를 재사용합니다. 화면의 마운트 횟수로 확인할 수 있습니다.
three.js 검사기
라이브러리가 자신의 상태를 관리합니다. 패널은 three.js 객체에서 위치, 색상, 플래그를 직접 읽고 편집 결과도 같은 객체에 씁니다. 렌더링 루프는 프레임당 한 번 update()를 호출하며 별도의 상태 복사본을 만들지 않습니다.
무한 스크롤
끝없이 이어지는 피드입니다. 빠른 모의 fetch()가 페이지를 즉석에서 생성해 하나의 일반 배열에 넣습니다. 뷰포트 근처의 행만 DOM에 남깁니다. list()가 두 스페이서 사이에 posts.slice(start, end)만 렌더링하므로 게시물이 10만 개여도 페이지가 가볍게 유지됩니다. 실제 끝에 둔 감지 요소가 화면에 들어오기 전에 다음 페이지를 요청합니다.
데스크톱
파일, 메모, 터미널, 계산기, 타이머, 칸반 보드, 재무 앱, 캘린더가 동작하는 데스크톱입니다. 브라우저에 저장되는 공유 가상 디스크에서 폴더를 만들고 정리하며 메모와 셸 명령을 사용합니다. 키보드로 계산기에 입력하고, 터미널의 아무 곳이나 클릭해 입력줄에 포커스를 맞추고, 열 사이로 카드를 드래그하거나 재무 스프레드시트에 장부를 기록하고 차트를 확인해 보세요. 장부는 IndexedDB에 저장됩니다. 창은 이동, 크기 조절, 앱 전환 중에도 상태를 유지하며 실행 중인 타이머는 into()로 작업 표시줄 트레이를 채웁니다.
노드 그래프
숫자, 텍스트, 스위치를 연산, 비교, If 노드로 연결하면 입력할 때마다 값이 업데이트됩니다. 함수도 그래프이며 Input과 Output 노드는 각 Call의 포트가 됩니다. Call에서 자기 함수도 호출할 수 있어 If를 종료 조건으로 팩토리얼과 합계를 재귀 계산합니다. 엔진은 일반 JavaScript입니다. 각 노드는 입력이 필요할 때 yield하는 제너레이터이며 하나의 루프가 별도 스택으로 실행합니다. sum(50000)은 JavaScript 호출 스택을 사용하지 않고 약 0.1초 만에 5만 단계 호출을 처리합니다. 종료 조건이 없는 재귀는 실행 단계 제한으로 중단됩니다. 드래그 시 x와 y만 바꾸고 캔버스 스코프만 업데이트합니다. 실행 횟수로 이동 중 그래프를 재계산하지 않는 것을 확인할 수 있습니다.
데이터 그리드
일반 행 객체 10,000개를 다루는 작업용 테이블입니다. 검색, 필터, 정렬, 페이지 이동은 배열을 처리하는 일반 함수이며 본문은 현재 페이지의 list()입니다. 행은 동일성으로 연결되므로 정렬해도 같은 페이지에 남는 행은 이동만 합니다. 편집한 행도 모든 곳에서 같은 객체입니다. 행 생성 횟수로 확인할 수 있습니다.
채팅
채널 세 개의 채팅입니다. 각 채널의 기록, 커서, 입력 상태, 초안, 스크롤 위치를 일반 객체 하나에 보관하므로 채널을 전환해도 그대로 유지됩니다. update("chat-sidebar")는 읽지 않은 메시지 배지만 갱신합니다. unshift()로 이전 기록을 위에 추가하고 추가된 높이만큼 scrollTop을 늘려 계속 불러옵니다. 서버에 도착하기 전에 메시지를 표시하고 send()로 같은 객체를 갱신합니다. 재시도, 편집, 삭제, 반응 시에도 행을 다시 만들지 않습니다. 메시지에는 코드, 굵은 글씨, 링크, @멘션을 표시할 수 있습니다.
라이브 대시보드
카드마다 초당 20회에서 초당 1회까지 다른 주기로 갱신됩니다. 각 카드는 scope()이며 타이머가 해당 ID로 update()를 호출하므로 한 틱에서는 그 카드만 평가합니다. 모든 동적 값의 평가 횟수가 화면에 표시됩니다. 일반 update()로 전환하면 초당 한 번 바뀌는 시계를 초당 약 100번 평가합니다.
픽셀 편집기
그림은 색상 문자열 1024개로 이루어진 일반 배열 하나이며 각 셀은 배열에서 자신의 색을 읽습니다. 그리는 동안 배열을 변경하고 update()를 호출하며, 획을 마치면 slice()로 복사본을 보관합니다. 실행 취소, 다시 실행, 기록 list()의 각 단계를 선택하면 이전 배열로 되돌립니다. 별도 스토어나 불변 데이터 구조는 사용하지 않습니다.
스네이크
게임 루프는 일반 객체에 step()을 실행한 뒤 틱마다 update()를 한 번 호출하는 타이머입니다. 뱀은 셀 객체의 list()이며 매 틱마다 꼬리 객체가 새 머리가 됩니다. 요소 하나를 이동할 뿐 새로 만들지 않으므로 몸통 생성 횟수는 먹이를 먹을 때만 증가합니다. 먹이는 keyframes() 애니메이션으로 나타납니다.
스텝 시퀀서
라이브러리가 자체 시계를 관리합니다. Web Audio는 자체 타임라인에 음을 미리 예약하고, 패턴은 격자에서 값을 토글하고 스케줄러가 읽는 일반 2차원 불리언 배열입니다. 클릭한 결과는 다음 재생 주기에 들립니다. 재생 위치 표시는 실제 들리는 스텝이 바뀔 때 자신의 scope()만 업데이트합니다. 첫 재생 시 오디오를 시작하고 마운트 정리 함수에서 종료하므로 예제를 나가면 소리도 멈춥니다.
로케일 전환기
모든 라벨을 단일 언어 앱처럼 정적 값으로 작성하므로 update()는 다시 읽지 않고 장바구니 클릭 시 수량과 합계만 갱신합니다. 언어를 바꾸면 이 트리에 forceUpdate()를 호출해 컴포넌트를 다시 실행하고 lang과 dir을 포함해 기존 요소를 갱신합니다. 통화, 복수형, 날짜, 목록 형식은 Intl로 처리하며 장바구니와 입력한 쿠폰은 언어 전환 후에도 유지됩니다.
테마 편집기
작은 컴포넌트 라이브러리입니다. createCss()로 토큰에 이름을 붙이고 variants()로 버튼, 배지, 카드, 입력 필드, 알림, 스위치를 만듭니다. 토큰이 CSS 변수이므로 각 클래스는 한 번만 컴파일됩니다. 각 컨트롤은 일반 테마 객체를 변경하고 update()를 호출해 스타일 요소 하나의 텍스트를 갱신합니다.