배경
카탈로그 TBD 손 가운데 Typeahead와 Canvas 부가손(마키·팬·스냅·넛지·Escape)은 패키지 API와 위젯 호출문이 이미 있다. 닫힘 표면만 Hands가 아니다. Listbox 위젯만 타입어헤드를 쓰고, Canvas 위젯만 마키·팬·스냅·넛지·Escape를 쓴다. Hands Order는 고르기·클립보드·삭제만, Hands Canvas는 고르기·드래그뿐이다.
이번 패스는 새 함수와 새 Intent 없이, 장르 표면 단위로 이미 만든 손을 붙인다.
Goal Anchor
- Outcome: Order에서 글쇠 prefix로 항목이 점프하고, Canvas에서 마키·팬·스냅·넛지·Escape가 살아 있다.
- Done:
/demo/order와 /demo/canvas가 위젯과 같은 applyAffordance 호출로 그 손을 쓴다. Typeahead·Escape·Marquee·Pan·Snap·Nudge가 이미 닫힌 손으로 올라간다. 패키지에 새 export가 없고, editor Intent가 늘지 않는다.
- Don't: Caret·Rename·Resize·Zoom·Scroll·Context menu를 만들지 않는다. Hover·Focus≠Select·Activate·Select all·Alt-드래그 복제·Tree 타입어헤드를 붙이지 않는다. 위젯 라우트를 Hands로 쓰지 않는다.
useAffordance를 만들지 않는다. Hands의 클립보드·채우기를 빼지 않는다.
Success Evidence
- Order 리스트에 포커스를 두고
T를 치면 Today가 선택된다. Escape는 타입어헤드 버퍼만 비운다.
- Canvas 빈 곳을 끌면 여러 상자가 선택된다. Space+드래그는 뷰포트만 옮긴다. 상자 드래그 커밋은 8px 스냅을 타고, Mod를 누르면 스냅하지 않는다. 화살표는
object.translate로 넛지한다. Escape는 드래그·마키·팬을 버린다.
packages/json-document-affordance/src/index.ts export 집합이 늘지 않는다. OrderIntent·ObjectIntent가 늘지 않는다.
docs/public/affordance.md에서 위 여섯 행이 TBD 표에서 빠진다.
Canonical Mapping
- Order 타입어헤드 =
ListboxWidgetRoute의 typeaheadAffordance + 버퍼용 escapeAffordance + selection.set { itemId, mode: "replace" }
- Canvas 부가손 =
CanvasWidgetRoute의 marqueeAffordance · panAffordance · snapAffordance · nudgeAffordance · escapeAffordance (forbiddenCursor 제외)
- 쓰기는 기존
selection.set / object.translate / 호스트 뷰포트·마키 상태
- 카탈로그 닫힘 = Typeahead, Escape, Marquee, Pan, Snap, Nudge
Behavior Contract
- Order 인쇄 글쇠 →
typeaheadAffordance → applyAffordance → selection.set { itemId, mode: "replace" } → 기존 getKeyDownHandler
- Order Escape →
escapeAffordance → 타입어헤드 버퍼 소거. 문서 값은 안 바뀜
- Canvas 빈 곳 pointerdown/move/up →
marqueeAffordance 미리보기, commitAffordance 후 호스트 히트 → selection.set { objectIds }
- Canvas Space 또는 가운데 버튼 →
panAffordance → 호스트 뷰포트. json-document 값은 안 바뀜
- Canvas 상자 드래그 커밋 →
snapAffordance { grid: 8, disable: meta/ctrl } → object.translate
- Canvas 화살표 →
nudgeAffordance → object.translate
- Canvas Escape / pointercancel →
escapeAffordance → drag·marquee·pan 폐기
Guardrails
- 호출문을 Hands 데모에 둔다.
site/src/routes/widgets를 가져가 마운트하지 않는다.
- 위젯 바인딩에 타입어헤드/캔버스 제스처 헬퍼를 승격하지 않는다.
- Canvas 표면 리스너는 호스트 마크업이다. 객체 위에만 포인터를 두는 지금 Hands 구조는 빈 곳 마키·팬을 위해 표면으로 옮긴다.
Smells
- Canvas/Order가 위젯 라우트를 import한다.
json-document-affordance에 파일이 생긴다.
- Hover·Focus·Activate가 같은 패스에 들어온다.
Work Topology
배경
카탈로그 TBD 손 가운데 Typeahead와 Canvas 부가손(마키·팬·스냅·넛지·Escape)은 패키지 API와 위젯 호출문이 이미 있다. 닫힘 표면만 Hands가 아니다. Listbox 위젯만 타입어헤드를 쓰고, Canvas 위젯만 마키·팬·스냅·넛지·Escape를 쓴다. Hands Order는 고르기·클립보드·삭제만, Hands Canvas는 고르기·드래그뿐이다.
이번 패스는 새 함수와 새 Intent 없이, 장르 표면 단위로 이미 만든 손을 붙인다.
Goal Anchor
/demo/order와/demo/canvas가 위젯과 같은applyAffordance호출로 그 손을 쓴다. Typeahead·Escape·Marquee·Pan·Snap·Nudge가이미 닫힌 손으로 올라간다. 패키지에 새 export가 없고, editor Intent가 늘지 않는다.useAffordance를 만들지 않는다. Hands의 클립보드·채우기를 빼지 않는다.Success Evidence
T를 치면 Today가 선택된다. Escape는 타입어헤드 버퍼만 비운다.object.translate로 넛지한다. Escape는 드래그·마키·팬을 버린다.packages/json-document-affordance/src/index.tsexport 집합이 늘지 않는다.OrderIntent·ObjectIntent가 늘지 않는다.docs/public/affordance.md에서 위 여섯 행이 TBD 표에서 빠진다.Canonical Mapping
ListboxWidgetRoute의typeaheadAffordance+ 버퍼용escapeAffordance+selection.set{ itemId, mode: "replace" }CanvasWidgetRoute의marqueeAffordance·panAffordance·snapAffordance·nudgeAffordance·escapeAffordance(forbiddenCursor제외)selection.set/object.translate/ 호스트 뷰포트·마키 상태Behavior Contract
typeaheadAffordance→applyAffordance→selection.set{ itemId, mode: "replace" }→ 기존getKeyDownHandlerescapeAffordance→ 타입어헤드 버퍼 소거. 문서 값은 안 바뀜marqueeAffordance미리보기,commitAffordance후 호스트 히트 →selection.set{ objectIds }panAffordance→ 호스트 뷰포트. json-document 값은 안 바뀜snapAffordance{ grid: 8, disable: meta/ctrl }→object.translatenudgeAffordance→object.translateescapeAffordance→ drag·marquee·pan 폐기Guardrails
site/src/routes/widgets를 가져가 마운트하지 않는다.Smells
json-document-affordance에 파일이 생긴다.Work Topology