사용자 Host와 Slot
comins-sortable@0.1.6
아래 Playground 경로는 해당 모듈 저장소에서 개발 서버를 실행한 뒤 사용하는 로컬 경로입니다. 현재 문서 사이트의 실행 링크는 아닙니다.
React의 as와 Vue의 tag는 Area 계약을 바꾸지 않고 정렬 Host를 변경합니다.
Svelte와 Vanilla는 항목을 직접 포함하는 element를 등록합니다.
전체 예제
섹션 제목: “전체 예제”import { useState } from 'react';import { SortableArea, SortableRoot } from 'comins-sortable/react';
type Item = { id: string; label: string };
export function CustomHostExample() { const [items, setItems] = useState<Item[]>([ { id: 'task-1', label: 'Plan' }, { id: 'task-2', label: 'Build' }, ]);
return ( <SortableRoot<Item>> <SortableArea as="ul" areaId="tasks" areaProps={{ 'aria-label': 'Tasks', style: { listStyle: 'none', padding: 0 } }} items={items} itemKey="id" handle=".drag-handle" header={<li>Tasks to complete</li>} footer={<li>End of list — not a drop target</li>} onItemsChange={(next) => setItems([...next])} > {(item) => ( <li> <button type="button" className="drag-handle" aria-label={`Drag ${item.label}`} style={{ touchAction: 'none', userSelect: 'none', WebkitUserSelect: 'none' }} > ⠿ </button> <span>{item.label}</span> </li> )} </SortableArea> </SortableRoot> );}이 예제는 실제 ul을 Host로 사용하고 헤더·푸터 li를 정렬 항목에서 제외합니다.
as에 사용자 컴포넌트를 전달하는 경우에는 React ref를 실제 Host까지 전달해야
합니다. Vue 컴포넌트도 등록할 실제 root element를 노출해야 합니다.
React의 header·footer, Vue slot 또는 범위를 좁힌 Vanilla/Svelte item
selector로 같은 Host에 비정렬 콘텐츠를 유지합니다. 비정렬 형제는 item selector와
일치해서는 안 되며 제어 item 배열에도 포함하지 않습니다. 포인터가 이러한
형제 위에 있으면 삽입 위치로 해석하지 않고 not-accepted 피드백을 표시합니다.
Vanilla/Svelte에서는 item: ':scope > .task-item'처럼 직접 항목만 지정할 수
있습니다. 자식 항목에 matches()를 호출하지 않고 등록 Area에서 선택자를 평가합니다.
헤더·푸터에는 .task-item을 붙이지 않습니다.
항목이 모두 다른 목록으로 이동해도 기존 항목 구간의 footer 경계를 유지합니다. 다시 넣을 때 미리보기와 실제 항목은 동일하게 header와 footer 사이에 위치합니다. React의 header·footer는 항목 수가 바뀌어도 같은 DOM을 유지하도록 별도 렌더링 위치를 사용합니다. 이 동작은 이미 관찰한 경계를 보존하며, 최초부터 빈 임의 DOM에서 어떤 비정렬 요소가 header인지 footer인지 자동으로 판별하는 계약은 아닙니다.
third-party는 외부 UI 패키지 의존성 없이 소비자 컴포넌트를 Host로 쓰는 예제입니다.
이름이 외부 라이브러리 통합을 보증하지는 않습니다. 테이블 행·열 Playground 데모는
제거되었으며, 일반 Host API의 존재를 테이블 정렬 지원 근거로 사용하지 않습니다.
Playground:
/examples/third-party/react/examples/footer-slot/react/examples/header-slot/react/examples/two-list-slots/react
Playground Host 설명
섹션 제목: “Playground Host 설명”React는 as와 ref 전달, Vue는 tag와 componentProps를 사용합니다.
Svelte는 직접 작성한 div에 use:sortable을 연결하고, Vanilla는 생성한 div를
createSortable에 전달합니다. 뒤의 두 탭은 컴포넌트 교체 예제가 아니라 직접 DOM
등록 예제입니다. functional-third-party 경로도 이 차이를 유지하며 parent로
자식 영역을 연결합니다.
화면의 사용자 컨테이너 연결/중첩 안내는 실제 DOM 구조와 연결 API를 함께
보여줍니다. Host는 정렬 항목을 직접 담는 요소이며, DOM 이벤트와 커스텀 이벤트를
비교하는 개념이 아닙니다. Vanilla의 변경 알림은 onChange 옵션 callback입니다.