0.1.2
소비자가 스크롤 박스를 소유한 구성에서 열 가상화와 오버레이가 어긋나던 문제를 고치고, 선택할 수 없는 셀에서 그리드가 포인터를 잡지 않도록 바꿉니다.
스크롤 소유권 해석 통일
그리드는 스크롤 구조를 소비자가 소유하도록 열어 두었지만(Root 자체, <DataGrid.ScrollContainer>, 소비자가 만든 박스, 바깥 페이지 컨테이너), 내부의 네 표면이 각자 다른 요소를 스크롤러라고 가정하고 있었습니다. 기본 구성이 아니면 다음이 어긋났습니다.
| 증상 | 원인 |
|---|---|
| 열 가상화가 동작하지 않음 (빈 컬럼) | 가로 스크롤러를 Root으로 고정 — 바깥 박스가 양축을 쥐면 Root은 scroll 이벤트를 받지 못함 |
| 채우기 핸들·복사 점선·선택 핸들·세로병합 오버레이가 스크롤을 따라가지 않음 | Root의 scroll만 구독 |
| 같은 오버레이들이 일정한 거리만큼 어긋나 그려짐 | 좌표 기준과 배치 기준(containing block)이 다름 — 사이에 툴바 등이 끼면 그만큼 밀림 |
| 채우기 드래그의 가장자리 자동 스크롤이 동작하지 않음 | 스크롤하지 않는 요소를 밀고 있었음. 같은 화면에서 범위 선택 드래그는 동작해 결과가 갈렸음 |
| 스크롤 상태에서 리사이즈하면 행이 화면 밖으로 밀림 | 외부 스크롤 컨테이너를 지정했을 때의 offset 계산이 그리드가 그 안에 있다는 전제에 의존 |
이제 "이 요소를 실제로 스크롤하는 건 누구인가"를 한 곳에서 축별로 해석하고, 가상화·자동 스크롤·오버레이·활성 셀 스크롤이 모두 같은 답을 씁니다. 가로만 스크롤하는 박스 안에서 세로는 페이지가 스크롤하는 구성처럼 두 축의 주인이 다른 경우도 각 축이 자기 스크롤러를 따릅니다.
<DataGrid.Root>가 스크롤 박스인 기본 구성은 동작이 그대로입니다. 해석이 Root을 그대로 찾아내므로 계산 결과가 이전과 같습니다.
virtualization.getScrollElement는 세로 축 전용입니다. 이전 문서는 "열 가상화는 내부 박스 기준 유지"라고
설명했지만 실제로는 열 가상화가 Root에 고정되어 바깥 박스가 양축을 쥐는 구성에서 동작하지 않았습니다.
이제 가로 스크롤러는 항상 자동으로 탐색합니다. 바깥 박스에 overflow: auto(양축)를 주면 가로도 그 박스가,
overflow-y만 주면 내부 박스가 잡힙니다.
세로 스크롤러 자동 탐색은 문서 최상위(html / body)까지 올라가지 않습니다. 페이지 자체가 스크롤하는 임베드에서는 여전히 getScrollElement로 명시해야 합니다.
선택할 수 없는 셀에서 포인터를 잡지 않습니다
체크박스 같은 control 컬럼(meta.columnRole: 'control')이나 isCellSelectable로 잠근 셀에서도 그리드가 pointerdown을 가로채고 기본 동작을 막고 있었습니다. 선택은 일어나지 않으면서 브라우저의 텍스트 선택만 사라져, 화면에 보이는 값을 마우스로 긁어서 복사할 수 없었습니다.
이제 그런 셀에서는 그리드가 포인터를 잡지 않습니다. 텍스트 선택이 살아 있어 값을 긁어 복사할 수 있고, 십자 커서도 뜨지 않습니다.
같은 판정을 조회하는 selection.canSelectCell(coord)가 추가됐습니다. 내장 규칙(control 컬럼 제외)과 isCellSelectable 옵션을 합친 결과값입니다.
selection.canSelectCell({ rowId, columnId }); // 이 셀이 셀 커서를 받을 수 있는가editable과는 다른 축입니다. 읽기 전용 셀도 긁어서 복사할 수 있어야 하므로 여전히 선택 가능할 수 있습니다. transformSelection은 제안된 선택 전체를 보는 정책이라 셀 단위로 환원되지 않아 이 값에 반영되지 않습니다.
[data-cell-selectable]
같은 판정이 셀 속성으로도 노출됩니다. 십자 커서(cursor: cell)는 이 속성이 붙은 셀에만 적용됩니다. 이전에는 그리드 전체 스위치로 깔려서 고를 수 없는 셀까지 고를 수 있는 것처럼 보였습니다.
aria-selected
ARIA 명세에서 이 속성은 값이 셋입니다. true는 선택됨, false는 선택할 수 있으나 미선택, 속성 없음은 선택 불가입니다. 이제 셋을 사실대로 구분해서, 선택할 수 있는 셀에만 boolean을 노출하고 control 컬럼이나 잠근 셀에서는 속성을 뺍니다. 이전에는 그런 셀에도 false를 달아 "선택할 수 있는데 지금은 아님"이라고 잘못 알리고 있었습니다.
동작 변경 — control 셀을 클릭해도 그리드 컨테이너에 포커스가 가지 않습니다. 체크박스 자신이 포커스를
받습니다. createSelectColumn이 우회용으로 달고 있던 onPointerDown 전파 차단은 이제 불필요하며 제거됐습니다.
같은 우회를 직접 넣어 두었다면 빼도 됩니다.
고정 컬럼이 활성 셀과 병합 셀 위로 올라갑니다
고정(pin)한 컬럼이 활성 셀 테두리와 세로병합 오버레이보다 아래에 그려져서, 고정 컬럼 밑으로 스크롤된 셀이 고정 컬럼 위로 새어 나왔습니다. 스프레드시트에서 고정 창은 스크롤된 셀을 가리므로 그 규약에 맞췄습니다.
시각 변경 — 고정 컬럼 밑으로 스크롤된 활성 셀의 테두리가 이제 가려집니다. 고정 컬럼 자체가 활성일 때는 그대로 보입니다.
채우기 미리보기, 복사 점선, 채우기 핸들, 터치 선택 핸들과 편집 중인 셀은 여전히 고정 컬럼 위를 지납니다. 이들은 고정 셀과 다른 좌표계에 있어 쌓임 순서만 바꾸면 잘못된 위치를 가리게 되므로, 고정 영역과 스크롤 영역을 분리하는 별도 작업으로 남겨 두었습니다.
Cmd+Shift+D · Cmd+Shift+R을 브라우저에 돌려줍니다
가로로 두 컬럼 이상 선택한 상태에서 Cmd+Shift+R을 누르면 하드 리로드 대신 오른쪽 채우기가 실행되어 값이 덮어써졌습니다. Cmd+Shift+D도 같은 이유로 탭 전체 북마크를 가로챘습니다.
키보드 채우기는 이제 수정자 없는 Cmd+D / Cmd+R에만 반응합니다. Excel과 Google Sheets 모두 Shift 조합을 채우기에 쓰지 않습니다. Cmd+Shift+Z(다시 실행)처럼 Shift가 의미를 갖는 단축키는 그대로입니다.
편집기 placeholder 색
인라인 텍스트 편집기의 placeholder가 셀의 글자색을 그대로 물려받아 실제 값과 구별되지 않았습니다. TextInput / TextArea와 같은 토큰으로 맞췄습니다.
타입 변경
Breaking — DataGridRuntime.columnVirtualizer의 타입이 Virtualizer<HTMLDivElement, Element>에서
Virtualizer<HTMLElement, Element>로 넓어집니다. 스크롤러가 Root이 아닐 수 있기 때문입니다.
이 값을 좁은 타입으로 명시해 둔 코드는 선언을 고쳐야 합니다. 런타임 동작은 같습니다.
Breaking — DataGridSelection에 canSelectCell이 추가됩니다. 이 인터페이스는 useDataGridSelection이
돌려주는 값이므로 보통은 영향이 없지만, 테스트에서 이 타입으로 객체를 직접 만들어 쓰고 있다면 항목을 채워야 합니다.
내부 수정
- 세로병합 오버레이가 컨테이너 테두리 두께만큼 어긋나 그려지던 문제를 고쳤습니다.
- 행 id에 공백이 들어간 경우 세로병합 오버레이의 내부 키가 충돌할 수 있던 문제를 고쳤습니다.
<DataGrid.ScrollContainer>의data-scrolled-x/data-scrolled-y는 소비자 CSS를 위한 hook입니다. 이전 문서는 고정 컬럼 그림자의 트리거라고 설명했으나 실제로는 그렇지 않습니다. 고정 그림자는data-pinned-last가 담당합니다.