@topgrid/grid-pro-range 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -0
- package/dist/index.cjs +8 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +390 -0
- package/dist/index.d.ts +390 -0
- package/dist/index.mjs +8 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/normalize.ts","../src/internal/fillRange.ts","../src/useCellRange.ts","../src/useKeyboardNav.ts","../src/internal/tsvUtils.ts","../src/useClipboard.ts","../src/useKeyboardEdit.ts","../src/DragFillHandle.tsx","../src/RangeSelectGrid.tsx","../src/index.ts"],"names":["normalizeRange","range","isInRange","row","col","n","detectSeriesStep","values","step","i","fillRange","sourceRange","direction","fillCount","getCellValue","start","end","sourceRows","sourceCols","r","c","sourceValues","updates","colLength","fi","targetRow","ci","colValues","_","ri","generateFillValue","rowLength","targetCol","rowValues","stepIndex","v","nums","useCellRange","onRangeChange","setRange","useState","dragging","setDragging","dragStart","useRef","handleMouseDown","useCallback","shiftKey","newRange","handleMouseEnter","handleMouseUp","useKeyboardNav","options","table","activeCell","onActiveCellChange","anchorCellRef","e","rowCount","colCount","current","clampRow","clampCol","isArrow","isTab","isEnter","d","anchor","cursor","nextCursor","findDataEdge","next","key","dRow","dCol","nextVal","escapeTsvCell","value","stringifyTsv","matrix","cell","parseTsv","tsv","normalized","trimmed","rows","lines","line","j","tabIdx","useClipboard","props","selection","onPaste","onError","copyToClipboard","textarea","ok","err","pasteFromClipboard","tsvString","pasteRows","pasteCols","cells","truncated","result","isCopy","isPaste","isSingleCell","getEditableCells","isEditableColumn","useKeyboardEdit","onDeleteRange","onBulkEdit","onEditStart","resolvedIsEditable","colIndex","DragFillHandle","onFillComplete","onFillTargetChange","containerRef","getCellRect","isDraggingRef","dragStartRef","fillTargetRef","coordFromMouseEvent","clientX","clientY","container","containerRect","relX","relY","rect","useEffect","handleMouseMove","targetCoord","newTarget","target","endRect","handleStyle","jsx","RangeSelectGrid","_lic","useLicenseStatus","data","columns","loading","emptyText","className","enableRangeSelection","enableKeyboardNav","enableDragFill","enableClipboard","enableKeyboardEdit","enableVirtualization","onClipboardError","sorting","setSorting","useReactTable","getCoreRowModel","getSortedRowModel","leafCols","selector","cr","setActiveCell","noop","_r","navKeyDown","getCellValueFallback","clipKeyDown","editKeyDown","handleKeyDown","virtualizer","useVirtualizer","virtualRows","totalHeight","renderCells","rowIdx","colIdx","selected","isActive","flexRender","jsxs","headerGroup","header","vRow","_row","Watermark","checkLicense"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * @topgrid/grid-pro-range — 순수 범위 유틸 함수 (AC-002).\r\n *\r\n * normalizeRange: start ≤ end 방향으로 정규화 (역방향 드래그 지원).\r\n * isInRange: 좌표가 범위 내 포함 여부 판별.\r\n *\r\n * 두 함수 모두 부수효과 없음 — 순수 함수 (pure functions).\r\n */\r\nimport type { CellCoord, CellRange } from '../types';\r\n\r\n/**\r\n * CellRange를 start ≤ end 방향으로 정규화.\r\n *\r\n * 드래그 방향과 무관하게 항상 정규화된 범위를 반환.\r\n * 역방향(end < start) 입력도 올바르게 처리.\r\n *\r\n * @example\r\n * normalizeRange({ start: {row:3, col:2}, end: {row:0, col:0} })\r\n * // → { start: {row:0, col:0}, end: {row:3, col:2} }\r\n */\r\nexport function normalizeRange(range: CellRange): CellRange {\r\n return {\r\n start: {\r\n row: Math.min(range.start.row, range.end.row),\r\n col: Math.min(range.start.col, range.end.col),\r\n },\r\n end: {\r\n row: Math.max(range.start.row, range.end.row),\r\n col: Math.max(range.start.col, range.end.col),\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 주어진 좌표(row, col)가 범위 내에 포함되는지 판별.\r\n *\r\n * range가 null이면 항상 false 반환.\r\n *\r\n * @example\r\n * isInRange(1, 1, { start: {row:0,col:0}, end: {row:2,col:2} }) // → true\r\n * isInRange(3, 3, { start: {row:0,col:0}, end: {row:2,col:2} }) // → false\r\n * isInRange(0, 0, null) // → false\r\n */\r\nexport function isInRange(\r\n row: number,\r\n col: number,\r\n range: CellRange | null,\r\n): boolean {\r\n if (!range) return false;\r\n const n = normalizeRange(range);\r\n return (\r\n row >= n.start.row &&\r\n row <= n.end.row &&\r\n col >= n.start.col &&\r\n col <= n.end.col\r\n );\r\n}\r\n\r\n// Re-export CellCoord type for internal consumers\r\nexport type { CellCoord };\r\n","/**\r\n * @topgrid/grid-pro-range — Drag-fill pure functions (G-003).\r\n *\r\n * fillRange: 소스 범위 값을 지정 방향·개수만큼 CellUpdate 배열로 생성.\r\n * detectSeriesStep: 숫자 배열에서 등차 step 감지.\r\n *\r\n * 두 함수 모두 부수효과 없음 — 순수 함수 (pure functions).\r\n * 제네릭 <TCell> 사용 — any 미사용 (AC-001, AC-002).\r\n */\r\nimport type { CellRange, CellUpdate, FillDirection } from '../types';\r\n\r\n/**\r\n * 숫자 배열에서 등차 step 감지.\r\n * 요소가 1개이면 step = 0 (단순 복사).\r\n * 요소가 2개 이상이고 모두 step 동일하면 해당 step 반환.\r\n * step 불일치 시 null 반환 (단순 복사 모드).\r\n */\r\nexport function detectSeriesStep(values: number[]): number | null {\r\n if (values.length < 2) return 0;\r\n const step = values[1] - values[0];\r\n for (let i = 2; i < values.length; i++) {\r\n if (values[i] - values[i - 1] !== step) return null;\r\n }\r\n return step;\r\n}\r\n\r\n/**\r\n * 소스 범위 값을 채울 방향·개수만큼 CellUpdate 배열 생성.\r\n * 제네릭 <TCell> — any 미사용 (AC-002).\r\n *\r\n * @param sourceRange 소스 CellRange (G-001 normalizeRange 보장된 값)\r\n * @param direction 채울 방향 (FillDirection)\r\n * @param fillCount 채울 셀 개수\r\n * @param getCellValue 소스 셀 값 getter\r\n */\r\nexport function fillRange<TCell>(\r\n sourceRange: CellRange,\r\n direction: FillDirection,\r\n fillCount: number,\r\n getCellValue: (row: number, col: number) => TCell,\r\n): CellUpdate<TCell>[] {\r\n if (fillCount <= 0) return [];\r\n\r\n const { start, end } = sourceRange;\r\n const sourceRows: number[] = [];\r\n const sourceCols: number[] = [];\r\n\r\n for (let r = start.row; r <= end.row; r++) sourceRows.push(r);\r\n for (let c = start.col; c <= end.col; c++) sourceCols.push(c);\r\n\r\n // 소스 값 수집\r\n const sourceValues: TCell[][] = sourceRows.map((r) =>\r\n sourceCols.map((c) => getCellValue(r, c)),\r\n );\r\n\r\n const updates: CellUpdate<TCell>[] = [];\r\n\r\n if (direction === 'down') {\r\n const colLength = sourceCols.length;\r\n for (let fi = 0; fi < fillCount; fi++) {\r\n const targetRow = end.row + 1 + fi;\r\n for (let ci = 0; ci < colLength; ci++) {\r\n const colValues = sourceRows.map((_, ri) => sourceValues[ri][ci]);\r\n updates.push({\r\n row: targetRow,\r\n col: sourceCols[ci],\r\n value: generateFillValue(colValues, fi + 1),\r\n });\r\n }\r\n }\r\n } else if (direction === 'up') {\r\n const colLength = sourceCols.length;\r\n for (let fi = 0; fi < fillCount; fi++) {\r\n const targetRow = start.row - fillCount + fi;\r\n for (let ci = 0; ci < colLength; ci++) {\r\n const colValues = sourceRows.map((_, ri) => sourceValues[ri][ci]).reverse();\r\n updates.push({\r\n row: targetRow,\r\n col: sourceCols[ci],\r\n value: generateFillValue(colValues, fillCount - fi),\r\n });\r\n }\r\n }\r\n } else if (direction === 'right') {\r\n const rowLength = sourceRows.length;\r\n for (let fi = 0; fi < fillCount; fi++) {\r\n const targetCol = end.col + 1 + fi;\r\n for (let ri = 0; ri < rowLength; ri++) {\r\n const rowValues = sourceCols.map((_, ci) => sourceValues[ri][ci]);\r\n updates.push({\r\n row: sourceRows[ri],\r\n col: targetCol,\r\n value: generateFillValue(rowValues, fi + 1),\r\n });\r\n }\r\n }\r\n } else {\r\n // direction === 'left'\r\n const rowLength = sourceRows.length;\r\n for (let fi = 0; fi < fillCount; fi++) {\r\n const targetCol = start.col - fillCount + fi;\r\n for (let ri = 0; ri < rowLength; ri++) {\r\n const rowValues = sourceCols.map((_, ci) => sourceValues[ri][ci]).reverse();\r\n updates.push({\r\n row: sourceRows[ri],\r\n col: targetCol,\r\n value: generateFillValue(rowValues, fillCount - fi),\r\n });\r\n }\r\n }\r\n }\r\n\r\n return updates;\r\n}\r\n\r\n/**\r\n * 소스 값 배열 + step 인덱스로 단일 fill 값 산출.\r\n * - 숫자 배열 + 일정 step: 시리즈 연장\r\n * - 그 외: 순환 복사 (modulo)\r\n */\r\nfunction generateFillValue<TCell>(sourceValues: TCell[], stepIndex: number): TCell {\r\n const allNumbers = sourceValues.every((v) => typeof v === 'number');\r\n if (allNumbers && sourceValues.length > 0) {\r\n const nums = sourceValues as number[];\r\n const step = detectSeriesStep(nums);\r\n if (step !== null) {\r\n const lastVal = nums[nums.length - 1];\r\n return (lastVal + step * stepIndex) as TCell;\r\n }\r\n }\r\n\r\n // 순환 복사 (modulo)\r\n return sourceValues[stepIndex % sourceValues.length] as TCell;\r\n}\r\n","/**\r\n * @topgrid/grid-pro-range — useCellRange 훅 (AC-003, AC-004, AC-006).\r\n *\r\n * 마우스 드래그/Shift+Click 셀 범위 선택 핸들러를 제공하는 headless React 훅.\r\n *\r\n * 라이선스 검증: index.ts module-load checkLicense() 호출로 처리 (ADR-MOD-GRID-00-012 Sunset 완료).\r\n */\r\nimport { useCallback, useRef, useState } from 'react';\r\n\r\nimport type { CellCoord, CellRange } from './types';\r\nimport { normalizeRange } from './internal/normalize';\r\n\r\n/** useCellRange 훅 반환 타입 (AC-003, AC-004, AC-006). */\r\nexport interface UseCellRangeReturn {\r\n /** 현재 선택된 셀 범위. 선택 없으면 null. */\r\n range: CellRange | null;\r\n /** 드래그 중 여부. */\r\n dragging: boolean;\r\n /**\r\n * 셀 mousedown 핸들러.\r\n * @param row 0-based 행 인덱스\r\n * @param col 0-based 열 인덱스\r\n * @param shiftKey Shift 키 눌림 여부\r\n */\r\n handleMouseDown: (row: number, col: number, shiftKey: boolean) => void;\r\n /**\r\n * 셀 mouseenter 핸들러 (드래그 범위 확장).\r\n * @param row 0-based 행 인덱스\r\n * @param col 0-based 열 인덱스\r\n */\r\n handleMouseEnter: (row: number, col: number) => void;\r\n /** mouseup 핸들러 (드래그 종료). */\r\n handleMouseUp: () => void;\r\n}\r\n\r\n/**\r\n * 마우스 드래그/Shift+Click 셀 범위 선택 훅.\r\n *\r\n * @param onRangeChange 범위 변경 시 호출되는 콜백 (AC-006).\r\n * @returns 범위 state + 이벤트 핸들러 3종.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { range, handleMouseDown, handleMouseEnter, handleMouseUp } =\r\n * useCellRange((r) => console.log('range changed:', r));\r\n * ```\r\n */\r\nexport function useCellRange(\r\n onRangeChange?: (range: CellRange | null) => void,\r\n): UseCellRangeReturn {\r\n const [range, setRange] = useState<CellRange | null>(null);\r\n const [dragging, setDragging] = useState(false);\r\n const dragStart = useRef<CellCoord | null>(null);\r\n\r\n const handleMouseDown = useCallback(\r\n (row: number, col: number, shiftKey: boolean) => {\r\n if (shiftKey && range) {\r\n // Shift+Click: 기존 start 유지, 새 end로 범위 확장 (AC-004).\r\n const newRange = normalizeRange({ start: range.start, end: { row, col } });\r\n setRange(newRange);\r\n onRangeChange?.(newRange);\r\n } else {\r\n // 새 drag start (AC-003).\r\n dragStart.current = { row, col };\r\n setDragging(true);\r\n const newRange: CellRange = { start: { row, col }, end: { row, col } };\r\n setRange(newRange);\r\n onRangeChange?.(newRange);\r\n }\r\n },\r\n [range, onRangeChange],\r\n );\r\n\r\n const handleMouseEnter = useCallback(\r\n (row: number, col: number) => {\r\n if (!dragging || !dragStart.current) return;\r\n // 드래그 중 범위 확장 (AC-003).\r\n const newRange = normalizeRange({\r\n start: dragStart.current,\r\n end: { row, col },\r\n });\r\n setRange(newRange);\r\n onRangeChange?.(newRange);\r\n },\r\n [dragging, onRangeChange],\r\n );\r\n\r\n const handleMouseUp = useCallback(() => {\r\n setDragging(false);\r\n }, []);\r\n\r\n return { range, dragging, handleMouseDown, handleMouseEnter, handleMouseUp };\r\n}\r\n","/**\r\n * @topgrid/grid-pro-range — useKeyboardNav 훅 (AC-002~AC-007).\r\n *\r\n * 키보드 내비게이션 + Shift+방향키 범위 확장 headless React 훅.\r\n *\r\n * D4: controlled 패턴 — useCellRange 미수정, { range, onRangeChange } 수신.\r\n * D3: handleKeyDown → Grid container <div tabIndex={0}> 부착.\r\n * ADR-MOD-GRID-11-006: normalize-on-extend + anchor 유지 패턴 재사용.\r\n */\r\nimport { useCallback, useRef } from 'react';\r\nimport type { Table } from '@tanstack/react-table';\r\n\r\nimport type { CellCoord, CellRange } from './types';\r\nimport { normalizeRange } from './internal/normalize';\r\n\r\nexport interface UseKeyboardNavOptions<TData> {\r\n /** TanStack table 인스턴스 (경계 계산용 — D5). */\r\n table: Table<TData>;\r\n /** 현재 활성 셀 좌표 (controlled). */\r\n activeCell: CellCoord | null;\r\n /** 활성 셀 변경 콜백. */\r\n onActiveCellChange: (cell: CellCoord) => void;\r\n /** 현재 선택 범위 (useCellRange에서 수신 — D4 controlled). */\r\n range: CellRange | null;\r\n /** 범위 변경 콜백 (useCellRange의 onRangeChange와 동일 시그니처 — D4). */\r\n onRangeChange: (range: CellRange | null) => void;\r\n /** Ctrl+Arrow data-edge 탐색 함수 (선택적). */\r\n getCellValue?: (row: number, col: number) => unknown;\r\n}\r\n\r\nexport interface UseKeyboardNavReturn {\r\n /** Grid container에 부착할 keydown 핸들러 (D3). */\r\n handleKeyDown: (e: React.KeyboardEvent) => void;\r\n}\r\n\r\nexport function useKeyboardNav<TData>(\r\n options: UseKeyboardNavOptions<TData>,\r\n): UseKeyboardNavReturn {\r\n const { table, activeCell, onActiveCellChange, range, onRangeChange, getCellValue } = options;\r\n\r\n // anchor ref: Shift+Arrow 시 start 고정 (ADR-MOD-GRID-11-006 anchor 유지 패턴)\r\n const anchorCellRef = useRef<CellCoord | null>(null);\r\n\r\n const handleKeyDown = useCallback(\r\n (e: React.KeyboardEvent) => {\r\n const rowCount = table.getRowModel().rows.length;\r\n const colCount = table.getAllColumns().filter((c) => c.getIsVisible()).length;\r\n\r\n if (rowCount === 0 || colCount === 0) return;\r\n\r\n const current = activeCell ?? { row: 0, col: 0 };\r\n\r\n const clampRow = (r: number) => Math.max(0, Math.min(r, rowCount - 1));\r\n const clampCol = (c: number) => Math.max(0, Math.min(c, colCount - 1));\r\n\r\n const isArrow = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key);\r\n const isTab = e.key === 'Tab';\r\n const isEnter = e.key === 'Enter';\r\n\r\n if (!isArrow && !isTab && !isEnter) return;\r\n\r\n e.preventDefault();\r\n\r\n if (isArrow) {\r\n const delta: Record<string, CellCoord> = {\r\n ArrowUp: { row: -1, col: 0 },\r\n ArrowDown: { row: 1, col: 0 },\r\n ArrowLeft: { row: 0, col: -1 },\r\n ArrowRight: { row: 0, col: 1 },\r\n };\r\n const d = delta[e.key];\r\n if (d === undefined) return;\r\n\r\n if (e.shiftKey) {\r\n // anchor 유지 패턴: 첫 Shift+Arrow 시 anchor 세팅\r\n if (anchorCellRef.current === null) {\r\n anchorCellRef.current = range?.start ?? current;\r\n }\r\n const anchor = anchorCellRef.current;\r\n\r\n // cursor = range.end (또는 activeCell) 이동\r\n const cursor = range?.end ?? current;\r\n let nextCursor: CellCoord;\r\n\r\n if (e.ctrlKey) {\r\n // Ctrl+Shift+Arrow: data-edge까지 확장\r\n nextCursor = findDataEdge(cursor, e.key, rowCount, colCount, getCellValue);\r\n } else {\r\n nextCursor = {\r\n row: clampRow(cursor.row + d.row),\r\n col: clampCol(cursor.col + d.col),\r\n };\r\n }\r\n\r\n // normalize-on-extend 패턴 (ADR-MOD-GRID-11-006)\r\n const newRange = normalizeRange({ start: anchor, end: nextCursor });\r\n onRangeChange(newRange);\r\n // activeCell은 cursor 위치 추적\r\n onActiveCellChange(nextCursor);\r\n } else {\r\n // 일반 Arrow: anchor 초기화, 범위 해제\r\n anchorCellRef.current = null;\r\n onRangeChange(null);\r\n\r\n if (e.ctrlKey) {\r\n // Ctrl+Arrow: data-edge 이동\r\n const next = findDataEdge(current, e.key, rowCount, colCount, getCellValue);\r\n onActiveCellChange(next);\r\n } else {\r\n onActiveCellChange({\r\n row: clampRow(current.row + d.row),\r\n col: clampCol(current.col + d.col),\r\n });\r\n }\r\n }\r\n } else if (isTab) {\r\n anchorCellRef.current = null;\r\n onRangeChange(null);\r\n\r\n if (e.shiftKey) {\r\n // Shift+Tab: 역방향 (AC-005)\r\n if (current.col > 0) {\r\n onActiveCellChange({ row: current.row, col: current.col - 1 });\r\n } else if (current.row > 0) {\r\n onActiveCellChange({ row: current.row - 1, col: colCount - 1 });\r\n }\r\n } else {\r\n // Tab: wrap (AC-005)\r\n if (current.col < colCount - 1) {\r\n onActiveCellChange({ row: current.row, col: current.col + 1 });\r\n } else if (current.row < rowCount - 1) {\r\n onActiveCellChange({ row: current.row + 1, col: 0 });\r\n }\r\n }\r\n } else if (isEnter) {\r\n anchorCellRef.current = null;\r\n onRangeChange(null);\r\n // Enter: 아래로 이동 (AC-006)\r\n if (current.row < rowCount - 1) {\r\n onActiveCellChange({ row: current.row + 1, col: current.col });\r\n }\r\n }\r\n },\r\n [table, activeCell, onActiveCellChange, range, onRangeChange, getCellValue],\r\n );\r\n\r\n return { handleKeyDown };\r\n}\r\n\r\n/** Ctrl+Arrow data-edge 탐색 (AC-007). */\r\nfunction findDataEdge(\r\n start: CellCoord,\r\n key: string,\r\n rowCount: number,\r\n colCount: number,\r\n getCellValue?: (row: number, col: number) => unknown,\r\n): CellCoord {\r\n if (getCellValue === undefined) {\r\n // getCellValue 미제공: 경계로 이동\r\n switch (key) {\r\n case 'ArrowUp': return { row: 0, col: start.col };\r\n case 'ArrowDown': return { row: rowCount - 1, col: start.col };\r\n case 'ArrowLeft': return { row: start.row, col: 0 };\r\n case 'ArrowRight': return { row: start.row, col: colCount - 1 };\r\n default: return start;\r\n }\r\n }\r\n let { row, col } = start;\r\n let dRow = 0;\r\n let dCol = 0;\r\n switch (key) {\r\n case 'ArrowUp': dRow = -1; break;\r\n case 'ArrowDown': dRow = 1; break;\r\n case 'ArrowLeft': dCol = -1; break;\r\n case 'ArrowRight': dCol = 1; break;\r\n default: return start;\r\n }\r\n while (\r\n row + dRow >= 0 && row + dRow < rowCount &&\r\n col + dCol >= 0 && col + dCol < colCount\r\n ) {\r\n const nextVal = getCellValue(row + dRow, col + dCol);\r\n if (nextVal === undefined || nextVal === null || nextVal === '') break;\r\n row += dRow;\r\n col += dCol;\r\n }\r\n return { row, col };\r\n}\r\n","/**\r\n * @topgrid/grid-pro-range — RFC 4180 호환 TSV 유틸리티 (G-004, AC-003).\r\n *\r\n * stringifyTsv: 2D 값 배열 → TSV 문자열 (탭/줄바꿈 포함 셀은 \" 래핑)\r\n * parseTsv: TSV 문자열 → 2D string 배열\r\n *\r\n * grid-export/copyToClipboard.ts의 공백 치환 escapeTsvValue와 다른 전략:\r\n * - grid-export: 행 단위 복사, 특수문자 → 공백 (D6 역할 분리)\r\n * - tsvUtils: 셀 범위 단위 복사, RFC 4180 완전 보존\r\n *\r\n * 두 함수 모두 부수효과 없음 — 순수 함수 (pure functions).\r\n */\r\n\r\n/**\r\n * 단일 셀 값을 RFC 4180 TSV 포맷으로 이스케이프.\r\n * - 탭(\\t), 줄바꿈(\\n, \\r), 쌍따옴표(\") 포함 시 \" 래핑\r\n * - 셀 내부 \" → \"\" (RFC 4180 §2.7)\r\n */\r\nfunction escapeTsvCell(value: string): string {\r\n const needsQuoting =\r\n value.includes('\\t') || value.includes('\\n') || value.includes('\\r') || value.includes('\"');\r\n if (!needsQuoting) return value;\r\n return '\"' + value.replace(/\"/g, '\"\"') + '\"';\r\n}\r\n\r\n/**\r\n * 2D 값 배열을 RFC 4180 호환 TSV 문자열로 직렬화.\r\n * 행 구분: \\n, 셀 구분: \\t.\r\n *\r\n * @param matrix row-major 2D 배열. 빈 배열이면 빈 문자열 반환.\r\n */\r\nexport function stringifyTsv(matrix: readonly (readonly unknown[])[]): string {\r\n if (matrix.length === 0) return '';\r\n return matrix\r\n .map((row) =>\r\n row\r\n .map((cell) =>\r\n escapeTsvCell(cell === null || cell === undefined ? '' : String(cell)),\r\n )\r\n .join('\\t'),\r\n )\r\n .join('\\n');\r\n}\r\n\r\n/**\r\n * RFC 4180 호환 TSV 문자열을 2D string 배열로 파싱.\r\n * - \" 래핑 셀: 언래핑 + \"\" → \" 복원\r\n * - 빈 문자열 또는 공백만: [['']] 반환\r\n *\r\n * @param tsv TSV 문자열 (Excel 복사 형식 포함).\r\n * @returns row-major 2D string 배열. 행 수 = rows, 최대 열 수 = cols.\r\n */\r\nexport function parseTsv(tsv: string): string[][] {\r\n if (tsv.trim() === '') return [['']];\r\n\r\n // 줄바꿈 정규화: \\r\\n → \\n, 단독 \\r → \\n\r\n const normalized = tsv.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\r\n // 말미 \\n 제거 (Excel이 마지막 행 후 \\n 추가하는 경우)\r\n const trimmed = normalized.endsWith('\\n') ? normalized.slice(0, -1) : normalized;\r\n\r\n const rows: string[][] = [];\r\n const lines = trimmed.split('\\n');\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const row: string[] = [];\r\n let line = lines[i];\r\n let col = 0;\r\n\r\n while (line.length > 0 || col === 0) {\r\n if (line.startsWith('\"')) {\r\n // RFC 4180 쌍따옴표 래핑 셀: 다음 언이스케이프된 \" 까지\r\n let j = 1;\r\n let cell = '';\r\n while (j < line.length) {\r\n if (line[j] === '\"') {\r\n if (j + 1 < line.length && line[j + 1] === '\"') {\r\n // \"\" → \"\r\n cell += '\"';\r\n j += 2;\r\n } else {\r\n // 닫는 \"\r\n j++;\r\n break;\r\n }\r\n } else {\r\n cell += line[j];\r\n j++;\r\n }\r\n }\r\n row.push(cell);\r\n line = line.slice(j);\r\n // 다음 탭 또는 EOL\r\n if (line.startsWith('\\t')) {\r\n line = line.slice(1);\r\n } else {\r\n break;\r\n }\r\n } else {\r\n // 일반 셀: 다음 탭까지\r\n const tabIdx = line.indexOf('\\t');\r\n if (tabIdx === -1) {\r\n row.push(line);\r\n line = '';\r\n break;\r\n } else {\r\n row.push(line.slice(0, tabIdx));\r\n line = line.slice(tabIdx + 1);\r\n }\r\n }\r\n col++;\r\n }\r\n rows.push(row);\r\n }\r\n\r\n return rows;\r\n}\r\n","/**\r\n * @topgrid/grid-pro-range — useClipboard hook (G-004).\r\n *\r\n * Ctrl+C: 현재 선택 범위 → RFC 4180 TSV → navigator.clipboard.writeText.\r\n * Ctrl+V: navigator.clipboard.readText → parseTsv → CellUpdate[] → onPaste 콜백.\r\n *\r\n * D3: onPaste callback — MOD-GRID-10 분리.\r\n * D5: navigator.clipboard 우선 + document.execCommand fallback.\r\n * D7: onKeyDown 반환 — G-002 useKeyboardNav와 컴포저블 결합.\r\n */\r\nimport { useCallback } from 'react';\r\nimport type {\r\n CellUpdate,\r\n PasteResult,\r\n UseClipboardProps,\r\n UseClipboardReturn,\r\n} from './types';\r\nimport { stringifyTsv, parseTsv } from './internal/tsvUtils';\r\n\r\nexport function useClipboard<TData, TCell = unknown>(\r\n props: UseClipboardProps<TData, TCell>,\r\n): UseClipboardReturn {\r\n const { selection, activeCell, rowCount, colCount, getCellValue, onPaste, onError } = props;\r\n\r\n /** 선택 범위 → 2D 매트릭스 → TSV string → 클립보드 (AC-001) */\r\n const copyToClipboard = useCallback(async (): Promise<void> => {\r\n // EC-001: selection null → no-op\r\n if (selection === null) return;\r\n\r\n const { start, end } = selection;\r\n const matrix: TCell[][] = [];\r\n for (let r = start.row; r <= end.row; r++) {\r\n const row: TCell[] = [];\r\n for (let c = start.col; c <= end.col; c++) {\r\n row.push(getCellValue(r, c));\r\n }\r\n matrix.push(row);\r\n }\r\n\r\n // C-31: stringifyTsv import + 호출 (wire-up audit)\r\n const tsv = stringifyTsv(matrix as readonly (readonly unknown[])[]);\r\n\r\n try {\r\n if (\r\n typeof navigator !== 'undefined' &&\r\n navigator.clipboard &&\r\n typeof navigator.clipboard.writeText === 'function'\r\n ) {\r\n await navigator.clipboard.writeText(tsv);\r\n } else {\r\n // D5 fallback: document.execCommand (HTTP 환경)\r\n const textarea = document.createElement('textarea');\r\n textarea.value = tsv;\r\n textarea.style.cssText = 'position:fixed;opacity:0';\r\n document.body.appendChild(textarea);\r\n textarea.select();\r\n const ok = document.execCommand('copy');\r\n document.body.removeChild(textarea);\r\n if (!ok) throw new Error('[grid-pro-range] copyToClipboard: Clipboard API not supported');\r\n }\r\n } catch (err) {\r\n const e = err instanceof Error ? err : new Error(String(err));\r\n if (onError !== undefined) {\r\n onError(e);\r\n } else {\r\n console.warn('[grid-pro-range] copyToClipboard error:', e.message);\r\n }\r\n }\r\n }, [selection, getCellValue, onError]);\r\n\r\n /**\r\n * TSV string → CellUpdate[] 파싱 후 onPaste 콜백 (AC-002, D3).\r\n * tsvString 미제공 시 navigator.clipboard.readText() 호출.\r\n * grid 경계 초과 시 clamp + truncated=true 보고 (EC-005).\r\n */\r\n const pasteFromClipboard = useCallback(\r\n async (tsvString?: string): Promise<PasteResult<TCell>> => {\r\n // EC-004: activeCell null → no-op\r\n if (activeCell === null) {\r\n return { cells: [], truncated: false, rows: 0, cols: 0 };\r\n }\r\n\r\n let tsv: string;\r\n if (tsvString !== undefined) {\r\n tsv = tsvString;\r\n } else {\r\n try {\r\n if (\r\n typeof navigator !== 'undefined' &&\r\n navigator.clipboard &&\r\n typeof navigator.clipboard.readText === 'function'\r\n ) {\r\n tsv = await navigator.clipboard.readText();\r\n } else {\r\n const err = new Error(\r\n '[grid-pro-range] pasteFromClipboard: Clipboard read API not supported',\r\n );\r\n if (onError !== undefined) onError(err);\r\n else console.warn(err.message);\r\n return { cells: [], truncated: false, rows: 0, cols: 0 };\r\n }\r\n } catch (err) {\r\n const e = err instanceof Error ? err : new Error(String(err));\r\n // EC-002: 권한 거부 → graceful no-op\r\n if (onError !== undefined) onError(e);\r\n else console.warn('[grid-pro-range] pasteFromClipboard error:', e.message);\r\n return { cells: [], truncated: false, rows: 0, cols: 0 };\r\n }\r\n }\r\n\r\n // EC-007: 빈 TSV → no-op\r\n if (tsv.trim() === '') {\r\n return { cells: [], truncated: false, rows: 0, cols: 0 };\r\n }\r\n\r\n // C-31: parseTsv import + 호출 (wire-up audit)\r\n const matrix = parseTsv(tsv);\r\n const pasteRows = matrix.length;\r\n const pasteCols = Math.max(...matrix.map((r) => r.length), 0);\r\n\r\n const cells: CellUpdate<TCell>[] = [];\r\n let truncated = false;\r\n\r\n for (let ri = 0; ri < pasteRows; ri++) {\r\n const targetRow = activeCell.row + ri;\r\n if (targetRow >= rowCount) {\r\n truncated = true;\r\n break;\r\n }\r\n const row = matrix[ri];\r\n for (let ci = 0; ci < row.length; ci++) {\r\n const targetCol = activeCell.col + ci;\r\n if (targetCol >= colCount) {\r\n truncated = true;\r\n continue;\r\n }\r\n cells.push({ row: targetRow, col: targetCol, value: row[ci] as unknown as TCell });\r\n }\r\n }\r\n\r\n const result: PasteResult<TCell> = { cells, truncated, rows: pasteRows, cols: pasteCols };\r\n\r\n if (cells.length > 0 && onPaste !== undefined) {\r\n onPaste(cells);\r\n }\r\n\r\n return result;\r\n },\r\n [activeCell, rowCount, colCount, onPaste, onError],\r\n );\r\n\r\n /** D7: Ctrl+C / Ctrl+V 키 캡처 (G-002 useKeyboardNav와 컴포저블 결합) */\r\n const onKeyDown = useCallback(\r\n (e: React.KeyboardEvent): void => {\r\n const isCopy = (e.ctrlKey || e.metaKey) && e.key === 'c';\r\n const isPaste = (e.ctrlKey || e.metaKey) && e.key === 'v';\r\n if (!isCopy && !isPaste) return;\r\n\r\n e.preventDefault();\r\n if (isCopy) {\r\n void copyToClipboard();\r\n } else {\r\n void pasteFromClipboard();\r\n }\r\n },\r\n [copyToClipboard, pasteFromClipboard],\r\n );\r\n\r\n return { onKeyDown, copyToClipboard, pasteFromClipboard };\r\n}\r\n","/**\r\n * @topgrid/grid-pro-range — useKeyboardEdit hook (G-005).\r\n *\r\n * Delete 키: 선택 범위 내 편집 가능 컬럼 셀 초기화 → onDeleteRange callback (D3).\r\n * Printable key: 범위 전체 동일 값 입력 → onBulkEdit callback (D3, D6 IME 검사).\r\n * F2: 단일 활성 셀 편집 시작 → onEditStart callback (D4).\r\n * Enter: 단일 셀 선택 시 편집 시작(D5), 범위 선택 시 G-002에 위임.\r\n *\r\n * D3: onDeleteRange / onBulkEdit callback — MOD-GRID-10 분리.\r\n * D4: onEditStart callback — MOD-GRID-05 InlineEditCell 분리.\r\n * D5: Enter 키 충돌 해소 — 단일 셀 선택 시에만 편집 소비.\r\n * D6: printable key 감지 — isComposing 검사 포함.\r\n * D7: onKeyDown 반환 — G-002/G-004와 컴포저블 결합.\r\n * ADR-MOD-GRID-11-006: 2D matrix iteration (isInRange 패턴 재사용).\r\n */\r\nimport { useCallback } from 'react';\r\nimport type {\r\n CellCoord,\r\n CellRange,\r\n UseKeyboardEditProps,\r\n UseKeyboardEditReturn,\r\n} from './types';\r\n\r\n/** 선택 범위가 단일 셀인지 확인 (D5 Enter 분기 보조). */\r\nfunction isSingleCell(range: CellRange): boolean {\r\n return range.start.row === range.end.row && range.start.col === range.end.col;\r\n}\r\n\r\n/** 범위 내 편집 가능 셀 좌표 배열 반환 (AC-001 Delete + AC-002 bulk). */\r\nfunction getEditableCells(\r\n range: CellRange,\r\n isEditableColumn: (colIndex: number) => boolean,\r\n): CellCoord[] {\r\n const cells: CellCoord[] = [];\r\n for (let r = range.start.row; r <= range.end.row; r++) {\r\n for (let c = range.start.col; c <= range.end.col; c++) {\r\n if (isEditableColumn(c)) {\r\n cells.push({ row: r, col: c });\r\n }\r\n }\r\n }\r\n return cells;\r\n}\r\n\r\n/**\r\n * useKeyboardEdit — Delete/F2/Enter/printable key 분기 hook.\r\n *\r\n * @returns `{ onKeyDown }` — Grid container에 부착할 keydown 핸들러 (D7).\r\n *\r\n * @example\r\n * ```tsx\r\n * const { onKeyDown: editKeyDown } = useKeyboardEdit({ selection, activeCell, ... });\r\n * // D7: G-005 앞에 배치 (D5 Enter 우선순위)\r\n * const onKeyDown = useCallback((e: React.KeyboardEvent) => {\r\n * editKeyDown(e);\r\n * if (e.defaultPrevented) return;\r\n * navKeyDown(e); // G-002\r\n * clipKeyDown(e); // G-004\r\n * }, [editKeyDown, navKeyDown, clipKeyDown]);\r\n * ```\r\n */\r\nexport function useKeyboardEdit<TData, TCell = unknown>(\r\n props: UseKeyboardEditProps<TData, TCell>,\r\n): UseKeyboardEditReturn {\r\n const {\r\n selection,\r\n activeCell,\r\n isEditableColumn,\r\n onDeleteRange,\r\n onBulkEdit,\r\n onEditStart,\r\n } = props;\r\n\r\n /** isEditableColumn 미제공 시 모든 컬럼 편집 가능으로 취급 (AC-001). */\r\n const resolvedIsEditable = useCallback(\r\n (colIndex: number): boolean => {\r\n if (isEditableColumn === undefined) return true;\r\n return isEditableColumn(colIndex);\r\n },\r\n [isEditableColumn],\r\n );\r\n\r\n const onKeyDown = useCallback(\r\n (e: React.KeyboardEvent): void => {\r\n // ── Delete / Backspace 키 (AC-001) ─────────────────────────────────\r\n if (e.key === 'Delete' || e.key === 'Backspace') {\r\n // Ctrl/Meta 조합은 브라우저 단축키 — G-005 제외\r\n if (e.ctrlKey || e.metaKey) return;\r\n if (selection === null) return; // EC-001: selection null → no-op\r\n\r\n const cells = getEditableCells(selection, resolvedIsEditable);\r\n if (cells.length === 0) return; // EC-002: 편집 가능 컬럼 없음 → no-op\r\n\r\n e.preventDefault();\r\n if (onDeleteRange !== undefined) {\r\n onDeleteRange(cells);\r\n }\r\n return;\r\n }\r\n\r\n // ── F2 키 (AC-003) ──────────────────────────────────────────────────\r\n if (e.key === 'F2') {\r\n if (activeCell === null) return; // EC-003: activeCell null → no-op\r\n e.preventDefault();\r\n if (onEditStart !== undefined) {\r\n onEditStart(activeCell);\r\n }\r\n return;\r\n }\r\n\r\n // ── Enter 키 (AC-003, D5) ───────────────────────────────────────────\r\n if (e.key === 'Enter') {\r\n if (activeCell === null) return;\r\n // D5: 단일 셀 선택 시에만 편집 시작 소비\r\n const singleCell =\r\n selection !== null && isSingleCell(selection);\r\n if (!singleCell) return; // EC-004: 범위 선택 시 G-002 handleKeyDown에 위임\r\n e.preventDefault();\r\n if (onEditStart !== undefined) {\r\n onEditStart(activeCell);\r\n }\r\n return;\r\n }\r\n\r\n // ── Printable key 일괄 입력 (AC-002, D6) ────────────────────────────\r\n const isPrintable =\r\n e.key.length === 1 &&\r\n !e.ctrlKey &&\r\n !e.metaKey &&\r\n !e.altKey &&\r\n !e.nativeEvent.isComposing; // EC-007: IME 조합 중 제외 (D6)\r\n\r\n if (isPrintable) {\r\n if (selection === null) return; // EC-001: selection null → no-op\r\n\r\n const cells = getEditableCells(selection, resolvedIsEditable);\r\n if (cells.length === 0) return;\r\n\r\n // printable key는 e.preventDefault() 생략 — 브라우저 기본 input 동작 유지.\r\n // 단일 셀의 경우 onEditStart + initialValue 호출 (AC-003 연동, EC-009)\r\n if (isSingleCell(selection) && activeCell !== null) {\r\n if (onEditStart !== undefined) {\r\n onEditStart(activeCell, e.key as unknown as TCell);\r\n }\r\n return;\r\n }\r\n\r\n if (onBulkEdit !== undefined) {\r\n onBulkEdit(cells, e.key as unknown as TCell);\r\n }\r\n }\r\n },\r\n [selection, activeCell, resolvedIsEditable, onDeleteRange, onBulkEdit, onEditStart],\r\n );\r\n\r\n return { onKeyDown };\r\n}\r\n","/**\r\n * @topgrid/grid-pro-range — DragFillHandle component (G-003).\r\n *\r\n * D4: isDraggingRef + dragStartRef + fillTargetRef 3개 ref로 drag 상태 추적.\r\n * ADR-MOD-GRID-11-006: mousedown/move/up 시퀀스 + drag state ref 패턴.\r\n */\r\nimport { useCallback, useEffect, useRef } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport type { CellRange, DragFillHandleProps, FillDirection } from './types';\r\nimport { normalizeRange } from './internal/normalize';\r\nimport { fillRange } from './internal/fillRange';\r\n\r\nexport function DragFillHandle<TCell = unknown>({\r\n range,\r\n getCellValue,\r\n onFillComplete,\r\n onFillTargetChange,\r\n rowCount,\r\n colCount,\r\n containerRef,\r\n getCellRect,\r\n}: DragFillHandleProps<TCell>): ReactElement | null {\r\n // D4: Drag state refs (ADR-MOD-GRID-11-006 mousedown/move/up 패턴)\r\n const isDraggingRef = useRef(false);\r\n const dragStartRef = useRef<{ x: number; y: number } | null>(null);\r\n const fillTargetRef = useRef<CellRange | null>(null);\r\n\r\n const clampRow = useCallback(\r\n (r: number) => Math.max(0, Math.min(r, rowCount - 1)),\r\n [rowCount],\r\n );\r\n const clampCol = useCallback(\r\n (c: number) => Math.max(0, Math.min(c, colCount - 1)),\r\n [colCount],\r\n );\r\n\r\n /** 마우스 좌표 → CellCoord 변환 (AC-004 가상화 호환) */\r\n const coordFromMouseEvent = useCallback(\r\n (clientX: number, clientY: number): { row: number; col: number } | null => {\r\n const container = containerRef.current;\r\n if (container === null) return null;\r\n const containerRect = container.getBoundingClientRect();\r\n const relX = clientX - containerRect.left;\r\n const relY = clientY - containerRect.top;\r\n\r\n // AC-004: 가상화 환경에서도 row/col index 정확하게 getCellRect 기반 hit-test\r\n for (let r = 0; r < rowCount; r++) {\r\n for (let c = 0; c < colCount; c++) {\r\n const rect = getCellRect(r, c);\r\n if (\r\n relX >= rect.x &&\r\n relX < rect.x + rect.width &&\r\n relY >= rect.y &&\r\n relY < rect.y + rect.height\r\n ) {\r\n return { row: clampRow(r), col: clampCol(c) };\r\n }\r\n }\r\n }\r\n return null;\r\n },\r\n [containerRef, rowCount, colCount, getCellRect, clampRow, clampCol],\r\n );\r\n\r\n const handleMouseDown = useCallback(\r\n (e: React.MouseEvent) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n isDraggingRef.current = true;\r\n dragStartRef.current = { x: e.clientX, y: e.clientY };\r\n fillTargetRef.current = null;\r\n },\r\n [],\r\n );\r\n\r\n // window-level mousemove/mouseup: 컨테이너 밖으로 나가도 drag 유지 (D4)\r\n useEffect(() => {\r\n const handleMouseMove = (e: MouseEvent) => {\r\n if (!isDraggingRef.current || range === null) return;\r\n\r\n const targetCoord = coordFromMouseEvent(e.clientX, e.clientY);\r\n if (targetCoord === null) return;\r\n\r\n // 드래그 방향 감지 (D5)\r\n const { start, end } = range;\r\n let newTarget: CellRange | null = null;\r\n\r\n if (targetCoord.row > end.row) {\r\n // down\r\n newTarget = normalizeRange({\r\n start: { row: end.row + 1, col: start.col },\r\n end: { row: targetCoord.row, col: end.col },\r\n });\r\n } else if (targetCoord.row < start.row) {\r\n // up\r\n newTarget = normalizeRange({\r\n start: { row: targetCoord.row, col: start.col },\r\n end: { row: start.row - 1, col: end.col },\r\n });\r\n } else if (targetCoord.col > end.col) {\r\n // right\r\n newTarget = normalizeRange({\r\n start: { row: start.row, col: end.col + 1 },\r\n end: { row: end.row, col: targetCoord.col },\r\n });\r\n } else if (targetCoord.col < start.col) {\r\n // left\r\n newTarget = normalizeRange({\r\n start: { row: start.row, col: targetCoord.col },\r\n end: { row: end.row, col: start.col - 1 },\r\n });\r\n }\r\n\r\n fillTargetRef.current = newTarget;\r\n if (onFillTargetChange !== undefined) {\r\n onFillTargetChange(newTarget);\r\n }\r\n };\r\n\r\n const handleMouseUp = () => {\r\n if (!isDraggingRef.current || range === null) {\r\n isDraggingRef.current = false;\r\n return;\r\n }\r\n isDraggingRef.current = false;\r\n\r\n const target = fillTargetRef.current;\r\n if (target === null) return;\r\n\r\n // 방향 파생\r\n const { start, end } = range;\r\n let direction: FillDirection = 'down';\r\n let fillCount = 0;\r\n\r\n if (target.start.row > end.row) {\r\n direction = 'down';\r\n fillCount = target.end.row - end.row;\r\n } else if (target.end.row < start.row) {\r\n direction = 'up';\r\n fillCount = start.row - target.start.row;\r\n } else if (target.start.col > end.col) {\r\n direction = 'right';\r\n fillCount = target.end.col - end.col;\r\n } else {\r\n direction = 'left';\r\n fillCount = start.col - target.start.col;\r\n }\r\n\r\n if (fillCount > 0 && onFillComplete !== undefined) {\r\n const updates = fillRange<TCell>(range, direction, fillCount, getCellValue);\r\n onFillComplete(updates);\r\n }\r\n\r\n fillTargetRef.current = null;\r\n if (onFillTargetChange !== undefined) {\r\n onFillTargetChange(null);\r\n }\r\n };\r\n\r\n window.addEventListener('mousemove', handleMouseMove);\r\n window.addEventListener('mouseup', handleMouseUp);\r\n return () => {\r\n window.removeEventListener('mousemove', handleMouseMove);\r\n window.removeEventListener('mouseup', handleMouseUp);\r\n };\r\n }, [range, getCellValue, onFillComplete, onFillTargetChange, coordFromMouseEvent]);\r\n\r\n // range 없으면 핸들 미렌더링\r\n if (range === null) return null;\r\n\r\n // 핸들 위치: 소스 range 우하단 셀 rect 기준\r\n const endRect = getCellRect(range.end.row, range.end.col);\r\n const handleStyle: React.CSSProperties = {\r\n position: 'absolute',\r\n left: endRect.x + endRect.width - 4,\r\n top: endRect.y + endRect.height - 4,\r\n };\r\n\r\n return (\r\n // Tailwind: absolute 2×2 파란 핸들 (C-5 — CSS 파일 미사용)\r\n <div\r\n role=\"presentation\"\r\n style={handleStyle}\r\n className=\"absolute w-2 h-2 bg-blue-500 cursor-crosshair border border-white z-10\"\r\n onMouseDown={handleMouseDown}\r\n />\r\n );\r\n}\r\n","/**\r\n * @topgrid/grid-pro-range — RangeSelectGrid 컴포넌트 (G-006 Capstone).\r\n *\r\n * 5-hook 완전 통합: useCellRange + useKeyboardNav + DragFillHandle +\r\n * useClipboard + useKeyboardEdit + @tanstack/react-virtual 가상화.\r\n *\r\n * D4: enable* props = behavior gate (hook 호출 게이팅 아님).\r\n * D5: Rules of Hooks — 5개 hook 무조건 호출.\r\n * D9: onKeyDown 합성 순서 = editKeyDown → navKeyDown → clipKeyDown.\r\n * C-5: Tailwind className만 사용. CSS 파일 없음.\r\n * C-16: Wijmo import 없음.\r\n * C-29: exactOptionalPropertyTypes — optional props spread-skip 패턴.\r\n */\r\nimport { useCallback, useRef, useState } from 'react';\r\nimport {\r\n flexRender,\r\n getCoreRowModel,\r\n getSortedRowModel,\r\n useReactTable,\r\n type SortingState,\r\n} from '@tanstack/react-table';\r\nimport { useVirtualizer } from '@tanstack/react-virtual';\r\nimport { useLicenseStatus, Watermark } from '@topgrid/grid-license';\r\n\r\nimport type { CellCoord, CellRange, RangeSelectGridAllProps } from './types';\r\nimport { isInRange } from './internal/normalize';\r\nimport { useCellRange } from './useCellRange';\r\nimport { useKeyboardNav } from './useKeyboardNav';\r\nimport { useClipboard } from './useClipboard';\r\nimport { useKeyboardEdit } from './useKeyboardEdit';\r\nimport { DragFillHandle } from './DragFillHandle';\r\n\r\n/**\r\n * RangeSelectGrid — G-006 5-hook 완전 통합 (AC-001, D4, D5, D9).\r\n *\r\n * D5 Rules of Hooks: 5개 hook 전부 무조건 호출.\r\n * D4 enable* = behavior gate (not hook invocation gate).\r\n * D9 onKeyDown 합성: editKeyDown → navKeyDown → clipKeyDown.\r\n *\r\n * @example\r\n * ```tsx\r\n * // v0.1.x 그대로 동작 (C-6 backward compat)\r\n * <RangeSelectGrid data={rows} columns={columns} />\r\n *\r\n * // v0.2.0 — Drag-fill + Clipboard 활성화\r\n * <RangeSelectGrid<MyData, string>\r\n * data={data}\r\n * columns={columns}\r\n * enableDragFill\r\n * enableClipboard\r\n * getCellValue={(row, col) => getValue(row, col)}\r\n * onFillComplete={(cells) => apply(cells)}\r\n * onPaste={(cells) => apply(cells)}\r\n * />\r\n * ```\r\n */\r\nexport function RangeSelectGrid<TData extends object, TCell = unknown>(\r\n props: RangeSelectGridAllProps<TData, TCell>,\r\n): React.ReactElement {\r\n // ADR-MOD-GRID-REFACTOR-2026-05-17-001 — license watermark wiring\r\n const _lic = useLicenseStatus();\r\n\r\n const {\r\n data,\r\n columns,\r\n onRangeChange,\r\n loading,\r\n emptyText = '데이터가 없습니다.',\r\n className,\r\n enableRangeSelection = true,\r\n enableKeyboardNav = true,\r\n enableDragFill = false,\r\n enableClipboard = false,\r\n enableKeyboardEdit = false,\r\n enableVirtualization = false,\r\n getCellValue,\r\n onFillComplete,\r\n onFillTargetChange,\r\n onPaste,\r\n onClipboardError,\r\n isEditableColumn,\r\n onDeleteRange,\r\n onBulkEdit,\r\n onEditStart,\r\n } = props;\r\n\r\n // ── TanStack Table ──────────────────────────────────────────────────────\r\n const [sorting, setSorting] = useState<SortingState>([]);\r\n const table = useReactTable({\r\n data,\r\n columns,\r\n state: { sorting },\r\n onSortingChange: setSorting,\r\n getCoreRowModel: getCoreRowModel(),\r\n getSortedRowModel: getSortedRowModel(),\r\n });\r\n const rows = table.getRowModel().rows;\r\n const leafCols = table.getAllLeafColumns();\r\n const rowCount = rows.length;\r\n const colCount = leafCols.length;\r\n\r\n // ── containerRef (getCellRect + useVirtualizer scroll element) ──────────\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // ── getCellRect helper (D7: coord → pixel rect, DragFillHandle용) ───────\r\n const getCellRect = useCallback(\r\n (row: number, col: number): { x: number; y: number; width: number; height: number } => {\r\n if (containerRef.current === null) return { x: 0, y: 0, width: 0, height: 0 };\r\n const selector = `[data-row=\"${row}\"][data-col=\"${col}\"]`;\r\n const cell = containerRef.current.querySelector(selector);\r\n if (cell === null) return { x: 0, y: 0, width: 0, height: 0 };\r\n const r = cell.getBoundingClientRect();\r\n const cr = containerRef.current.getBoundingClientRect();\r\n return { x: r.left - cr.left, y: r.top - cr.top, width: r.width, height: r.height };\r\n },\r\n [],\r\n );\r\n\r\n // ── G-001 useCellRange (D5: 무조건 호출) ────────────────────────────────\r\n // 실제 시그니처: useCellRange(onRangeChange?) — 단일 callback 인자.\r\n // enableRangeSelection=false 시 undefined 전달 → hook 내부 no-op.\r\n const { range, handleMouseDown, handleMouseEnter, handleMouseUp } = useCellRange(\r\n enableRangeSelection ? onRangeChange : undefined,\r\n );\r\n\r\n // ── G-002 useKeyboardNav (D5: 무조건 호출) ──────────────────────────────\r\n const [activeCell, setActiveCell] = useState<CellCoord | null>(null);\r\n const noop = useCallback((_r: CellRange | null) => undefined, []);\r\n const { handleKeyDown: navKeyDown } = useKeyboardNav<TData>({\r\n table,\r\n activeCell,\r\n onActiveCellChange: setActiveCell,\r\n range,\r\n onRangeChange: enableKeyboardNav ? (onRangeChange ?? noop) : noop,\r\n ...(getCellValue !== undefined ? { getCellValue } : {}),\r\n });\r\n\r\n // ── G-004 useClipboard (D5: 무조건 호출) ────────────────────────────────\r\n // getCellValue required by useClipboard — fallback noop when undefined.\r\n const getCellValueFallback = useCallback(\r\n () => undefined as TCell,\r\n [],\r\n );\r\n const { onKeyDown: clipKeyDown } = useClipboard<TData, TCell>({\r\n selection: range,\r\n activeCell,\r\n rowCount,\r\n colCount,\r\n getCellValue: getCellValue ?? getCellValueFallback,\r\n ...(enableClipboard && onPaste !== undefined ? { onPaste } : {}),\r\n ...(enableClipboard && onClipboardError !== undefined ? { onError: onClipboardError } : {}),\r\n });\r\n\r\n // ── G-005 useKeyboardEdit (D5: 무조건 호출) ─────────────────────────────\r\n const { onKeyDown: editKeyDown } = useKeyboardEdit<TData, TCell>({\r\n selection: range,\r\n activeCell,\r\n ...(isEditableColumn !== undefined ? { isEditableColumn } : {}),\r\n ...(enableKeyboardEdit && onDeleteRange !== undefined ? { onDeleteRange } : {}),\r\n ...(enableKeyboardEdit && onBulkEdit !== undefined ? { onBulkEdit } : {}),\r\n ...(enableKeyboardEdit && onEditStart !== undefined ? { onEditStart } : {}),\r\n });\r\n\r\n // ── D9: onKeyDown 합성 체인 (G-005 → G-002 → G-004) ────────────────────\r\n const handleKeyDown = useCallback(\r\n (e: React.KeyboardEvent): void => {\r\n editKeyDown(e);\r\n if (e.defaultPrevented) return;\r\n navKeyDown(e);\r\n if (e.defaultPrevented) return;\r\n clipKeyDown(e);\r\n },\r\n [editKeyDown, navKeyDown, clipKeyDown],\r\n );\r\n\r\n // ── 가상화 (AC-002, C-18, @tanstack/react-virtual) ──────────────────────\r\n // D5: useVirtualizer는 hook이므로 무조건 호출.\r\n // enableVirtualization=false 시 count=0 → 빈 items, 비가상화 렌더 fallback.\r\n const virtualizer = useVirtualizer({\r\n count: enableVirtualization ? rowCount : 0,\r\n getScrollElement: () => containerRef.current,\r\n estimateSize: () => 36,\r\n });\r\n const virtualRows = enableVirtualization ? virtualizer.getVirtualItems() : null;\r\n const totalHeight = enableVirtualization ? virtualizer.getTotalSize() : undefined;\r\n\r\n // ── Loading 상태 ─────────────────────────────────────────────────────────\r\n if (loading === true) {\r\n return (\r\n <div className={`flex flex-col ${className ?? ''}`}>\r\n <div className=\"h-40 flex items-center justify-center\">\r\n <div className=\"animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-blue-500\" />\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // ── 셀 렌더 helper ───────────────────────────────────────────────────────\r\n const renderCells = (rowIdx: number) => {\r\n const row = rows[rowIdx];\r\n return row.getVisibleCells().map((cell, colIdx) => {\r\n const selected = isInRange(rowIdx, colIdx, range);\r\n const isActive =\r\n activeCell !== null && activeCell.row === rowIdx && activeCell.col === colIdx;\r\n return (\r\n <td\r\n key={cell.id}\r\n data-row={rowIdx}\r\n data-col={colIdx}\r\n // AC-005: 선택 셀 bg-blue-100 ring-1 ring-blue-400 (ADR-004)\r\n // activeCell: ring-2 ring-blue-600 (G-002 패턴)\r\n className={`px-4 py-3 whitespace-nowrap text-gray-700 cursor-cell border border-transparent transition-colors ${\r\n isActive\r\n ? 'bg-blue-50 ring-2 ring-blue-600'\r\n : selected\r\n ? 'bg-blue-100 ring-1 ring-blue-400'\r\n : ''\r\n }`}\r\n onMouseDown={(e) => {\r\n if (!enableRangeSelection) return;\r\n e.preventDefault(); // 텍스트 선택 방지\r\n handleMouseDown(rowIdx, colIdx, e.shiftKey);\r\n }}\r\n onMouseEnter={() => {\r\n if (!enableRangeSelection) return;\r\n handleMouseEnter(rowIdx, colIdx);\r\n }}\r\n >\r\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\r\n </td>\r\n );\r\n });\r\n };\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={`flex flex-col ${className ?? ''} relative`}\r\n tabIndex={0}\r\n onKeyDown={handleKeyDown}\r\n onMouseUp={handleMouseUp}\r\n onMouseLeave={handleMouseUp}\r\n >\r\n <div className=\"overflow-x-auto rounded-lg border border-gray-200 select-none overflow-y-auto\">\r\n <table className=\"min-w-full text-sm divide-y divide-gray-200\">\r\n <thead className=\"bg-gray-50\">\r\n {table.getHeaderGroups().map((headerGroup) => (\r\n <tr key={headerGroup.id}>\r\n {headerGroup.headers.map((header) => (\r\n <th\r\n key={header.id}\r\n className={`px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap select-none ${\r\n header.column.getCanSort()\r\n ? 'cursor-pointer hover:bg-gray-100'\r\n : ''\r\n }`}\r\n onClick={header.column.getToggleSortingHandler()}\r\n >\r\n <div className=\"flex items-center gap-1\">\r\n {header.isPlaceholder\r\n ? null\r\n : flexRender(\r\n header.column.columnDef.header,\r\n header.getContext(),\r\n )}\r\n {header.column.getCanSort() && (\r\n <span className=\"text-gray-400\">\r\n {(\r\n { asc: '▲', desc: '▼' } as Record<string, string>\r\n )[header.column.getIsSorted() as string] ?? '⇅'}\r\n </span>\r\n )}\r\n </div>\r\n </th>\r\n ))}\r\n </tr>\r\n ))}\r\n </thead>\r\n <tbody className=\"bg-white divide-y divide-gray-100\">\r\n {rows.length === 0 ? (\r\n <tr>\r\n <td\r\n colSpan={leafCols.length}\r\n className=\"px-4 py-10 text-center text-gray-400\"\r\n >\r\n {emptyText}\r\n </td>\r\n </tr>\r\n ) : virtualRows !== null ? (\r\n // ── 가상화 렌더 (enableVirtualization=true) ────────────────\r\n <tr>\r\n <td colSpan={leafCols.length} className=\"p-0\">\r\n <div style={{ height: totalHeight, position: 'relative' }}>\r\n {virtualRows.map((vRow) => (\r\n <table\r\n key={vRow.key}\r\n style={{\r\n position: 'absolute',\r\n top: vRow.start,\r\n width: '100%',\r\n tableLayout: 'fixed',\r\n }}\r\n className=\"min-w-full text-sm\"\r\n >\r\n <tbody>\r\n <tr className=\"hover:bg-gray-50\">\r\n {renderCells(vRow.index)}\r\n </tr>\r\n </tbody>\r\n </table>\r\n ))}\r\n </div>\r\n </td>\r\n </tr>\r\n ) : (\r\n // ── 일반 렌더 ─────────────────────────────────────────────\r\n rows.map((_row, rowIdx) => (\r\n <tr key={_row.id} className=\"hover:bg-gray-50\">\r\n {renderCells(rowIdx)}\r\n </tr>\r\n ))\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* G-003 DragFillHandle — 컴포넌트이므로 조건부 렌더 허용 (D4, D5) */}\r\n {/* EC-001: getCellValue 미제공 시 DragFillHandle 렌더 skip */}\r\n {enableDragFill && range !== null && getCellValue !== undefined && (\r\n <DragFillHandle<TCell>\r\n range={range}\r\n getCellValue={getCellValue}\r\n rowCount={rowCount}\r\n colCount={colCount}\r\n containerRef={containerRef}\r\n getCellRect={getCellRect}\r\n {...(onFillComplete !== undefined ? { onFillComplete } : {})}\r\n {...(onFillTargetChange !== undefined ? { onFillTargetChange } : {})}\r\n />\r\n )}\r\n {_lic.watermarkRequired && <Watermark required />}\r\n </div>\r\n );\r\n}\r\n","import { checkLicense } from '@topgrid/grid-license';\r\n\r\ncheckLicense();\r\n\r\n/**\r\n * @topgrid/grid-pro-range — public API (MOD-GRID-11 / G-001, G-002, G-003).\r\n *\r\n * CellRange 모델 + 마우스 드래그/Shift+Click 셀 범위 선택 + Drag-fill.\r\n * AC-009: types, 함수, 훅, 컴포넌트 전부 named export.\r\n */\r\n\r\n// Types (AC-001)\r\nexport type { CellCoord, CellRange, RangeSelectGridProps, RangeSelectGridAllProps } from './types';\r\n// G-003 신규 타입 export (AC-009)\r\nexport type { CellUpdate, FillDirection, DragFillHandleProps } from './types';\r\n\r\n// Pure functions (AC-002)\r\nexport { normalizeRange, isInRange } from './internal/normalize';\r\n// G-003 순수 함수 export\r\nexport { fillRange, detectSeriesStep } from './internal/fillRange';\r\n\r\n// Hook (AC-003, AC-004, AC-006)\r\nexport { useCellRange } from './useCellRange';\r\nexport type { UseCellRangeReturn } from './useCellRange';\r\n\r\n// Component (AC-003, AC-004, AC-005, AC-006)\r\nexport { RangeSelectGrid } from './RangeSelectGrid';\r\n\r\n// Keyboard navigation hook (G-002, AC-002~AC-007)\r\nexport { useKeyboardNav } from './useKeyboardNav';\r\nexport type { UseKeyboardNavOptions, UseKeyboardNavReturn } from './useKeyboardNav';\r\n// G-003 컴포넌트 export\r\nexport { DragFillHandle } from './DragFillHandle';\r\n\r\n// G-004 Clipboard (AC-001, AC-002, AC-003, AC-009)\r\nexport { useClipboard } from './useClipboard';\r\nexport type { PasteResult, UseClipboardProps, UseClipboardReturn } from './types';\r\nexport { stringifyTsv, parseTsv } from './internal/tsvUtils';\r\n\r\n// G-005 Keyboard Edit (AC-001~AC-003, Delete/F2/Enter/printable key)\r\nexport { useKeyboardEdit } from './useKeyboardEdit';\r\nexport type { UseKeyboardEditProps, UseKeyboardEditReturn } from './types';\r\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@topgrid/grid-pro-range",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "SEE LICENSE IN EULA",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"description": "Pro: Cell Range Selection, Drag-fill, Clipboard",
|
|
10
|
+
"main": "./dist/index.cjs",
|
|
11
|
+
"module": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.mjs",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@topgrid/grid-license": "0.1.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@topgrid/grid-core": "0.1.0"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"@tanstack/react-table": "^8.0.0",
|
|
32
|
+
"@tanstack/react-virtual": "^3.0.0",
|
|
33
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
34
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"@tanstack/react-virtual": {
|
|
38
|
+
"optional": true
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"test": "echo TODO"
|
|
45
|
+
}
|
|
46
|
+
}
|