드래그핸들 기능 수정
This commit is contained in:
parent
980c929d83
commit
a3c83c834e
|
|
@ -822,7 +822,43 @@ export const EditableSpreadsheet: React.FC<EditableSpreadsheetProps> = ({
|
||||||
}
|
}
|
||||||
}, [isDraggingFill, selection]);
|
}, [isDraggingFill, selection]);
|
||||||
|
|
||||||
|
// 열의 숫자 패턴 간격 계산 (예: 201, 202 → 간격 1)
|
||||||
|
const calculateColumnIncrement = (colIndex: number, startRow: number, endRow: number): number | null => {
|
||||||
|
if (startRow === endRow) return 1; // 단일 행이면 기본 증가 1
|
||||||
|
|
||||||
|
const colName = columns[colIndex];
|
||||||
|
const increments: number[] = [];
|
||||||
|
|
||||||
|
for (let row = startRow; row < endRow; row++) {
|
||||||
|
const currentValue = String(data[row]?.[colName] ?? "");
|
||||||
|
const nextValue = String(data[row + 1]?.[colName] ?? "");
|
||||||
|
|
||||||
|
const currentPattern = extractNumberPattern(currentValue);
|
||||||
|
const nextPattern = extractNumberPattern(nextValue);
|
||||||
|
|
||||||
|
if (currentPattern && nextPattern) {
|
||||||
|
// 접두사와 접미사가 같은지 확인
|
||||||
|
if (currentPattern.prefix === nextPattern.prefix && currentPattern.suffix === nextPattern.suffix) {
|
||||||
|
increments.push(nextPattern.number - currentPattern.number);
|
||||||
|
} else {
|
||||||
|
return null; // 패턴이 다르면 복사 모드
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null; // 숫자 패턴이 없으면 복사 모드
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모든 간격이 같은지 확인
|
||||||
|
if (increments.length > 0 && increments.every(inc => inc === increments[0])) {
|
||||||
|
return increments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
// 자동 채우기 드래그 종료 (다중 셀 지원)
|
// 자동 채우기 드래그 종료 (다중 셀 지원)
|
||||||
|
// - 숫자 패턴이 있으면: 패턴 간격을 인식하여 증가 (201, 202 → 203, 204)
|
||||||
|
// - 숫자 패턴이 없으면: 선택된 패턴 그대로 반복 (복사)
|
||||||
const handleFillDragEnd = useCallback(() => {
|
const handleFillDragEnd = useCallback(() => {
|
||||||
if (!isDraggingFill || !selection || fillPreviewEnd === null) {
|
if (!isDraggingFill || !selection || fillPreviewEnd === null) {
|
||||||
setIsDraggingFill(false);
|
setIsDraggingFill(false);
|
||||||
|
|
@ -836,15 +872,16 @@ export const EditableSpreadsheet: React.FC<EditableSpreadsheetProps> = ({
|
||||||
|
|
||||||
if (endRow !== norm.endRow && norm.startRow >= 0) {
|
if (endRow !== norm.endRow && norm.startRow >= 0) {
|
||||||
const newData = [...data];
|
const newData = [...data];
|
||||||
|
|
||||||
|
// 각 열별로 증가 패턴 계산
|
||||||
|
const columnIncrements: Map<number, number | null> = new Map();
|
||||||
|
for (let col = norm.startCol; col <= norm.endCol; col++) {
|
||||||
|
columnIncrements.set(col, calculateColumnIncrement(col, norm.startRow, norm.endRow));
|
||||||
|
}
|
||||||
|
|
||||||
if (endRow > norm.endRow) {
|
if (endRow > norm.endRow) {
|
||||||
// 아래로 채우기
|
// 아래로 채우기
|
||||||
for (let targetRow = norm.endRow + 1; targetRow <= endRow; targetRow++) {
|
for (let targetRow = norm.endRow + 1; targetRow <= endRow; targetRow++) {
|
||||||
// 선택 범위 내 행 순환
|
|
||||||
const sourceRowOffset = (targetRow - norm.startRow) % selectionHeight;
|
|
||||||
const sourceRow = norm.startRow + sourceRowOffset;
|
|
||||||
const stepMultiplier = Math.floor((targetRow - norm.startRow) / selectionHeight);
|
|
||||||
|
|
||||||
if (!newData[targetRow]) {
|
if (!newData[targetRow]) {
|
||||||
newData[targetRow] = {};
|
newData[targetRow] = {};
|
||||||
columns.forEach((c) => {
|
columns.forEach((c) => {
|
||||||
|
|
@ -855,20 +892,32 @@ export const EditableSpreadsheet: React.FC<EditableSpreadsheetProps> = ({
|
||||||
// 선택된 모든 열에 대해 채우기
|
// 선택된 모든 열에 대해 채우기
|
||||||
for (let col = norm.startCol; col <= norm.endCol; col++) {
|
for (let col = norm.startCol; col <= norm.endCol; col++) {
|
||||||
const colName = columns[col];
|
const colName = columns[col];
|
||||||
const sourceValue = String(data[sourceRow]?.[colName] ?? "");
|
const increment = columnIncrements.get(col);
|
||||||
const step = targetRow - sourceRow;
|
|
||||||
newData[targetRow] = {
|
if (increment !== null) {
|
||||||
...newData[targetRow],
|
// 숫자 패턴 증가 모드
|
||||||
[colName]: generateNextValue(sourceValue, step),
|
// 마지막 선택 행의 값을 기준으로 증가
|
||||||
};
|
const lastValue = String(data[norm.endRow]?.[colName] ?? "");
|
||||||
|
const step = (targetRow - norm.endRow) * increment;
|
||||||
|
newData[targetRow] = {
|
||||||
|
...newData[targetRow],
|
||||||
|
[colName]: generateNextValue(lastValue, step),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// 복사 모드 (패턴 반복)
|
||||||
|
const sourceRowOffset = (targetRow - norm.endRow - 1) % selectionHeight;
|
||||||
|
const sourceRow = norm.startRow + sourceRowOffset;
|
||||||
|
const sourceValue = String(data[sourceRow]?.[colName] ?? "");
|
||||||
|
newData[targetRow] = {
|
||||||
|
...newData[targetRow],
|
||||||
|
[colName]: sourceValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (endRow < norm.startRow) {
|
} else if (endRow < norm.startRow) {
|
||||||
// 위로 채우기
|
// 위로 채우기
|
||||||
for (let targetRow = norm.startRow - 1; targetRow >= endRow; targetRow--) {
|
for (let targetRow = norm.startRow - 1; targetRow >= endRow; targetRow--) {
|
||||||
const sourceRowOffset = (norm.startRow - targetRow - 1) % selectionHeight;
|
|
||||||
const sourceRow = norm.endRow - sourceRowOffset;
|
|
||||||
|
|
||||||
if (!newData[targetRow]) {
|
if (!newData[targetRow]) {
|
||||||
newData[targetRow] = {};
|
newData[targetRow] = {};
|
||||||
columns.forEach((c) => {
|
columns.forEach((c) => {
|
||||||
|
|
@ -878,12 +927,26 @@ export const EditableSpreadsheet: React.FC<EditableSpreadsheetProps> = ({
|
||||||
|
|
||||||
for (let col = norm.startCol; col <= norm.endCol; col++) {
|
for (let col = norm.startCol; col <= norm.endCol; col++) {
|
||||||
const colName = columns[col];
|
const colName = columns[col];
|
||||||
const sourceValue = String(data[sourceRow]?.[colName] ?? "");
|
const increment = columnIncrements.get(col);
|
||||||
const step = targetRow - sourceRow;
|
|
||||||
newData[targetRow] = {
|
if (increment !== null) {
|
||||||
...newData[targetRow],
|
// 숫자 패턴 감소 모드
|
||||||
[colName]: generateNextValue(sourceValue, step),
|
const firstValue = String(data[norm.startRow]?.[colName] ?? "");
|
||||||
};
|
const step = (targetRow - norm.startRow) * increment;
|
||||||
|
newData[targetRow] = {
|
||||||
|
...newData[targetRow],
|
||||||
|
[colName]: generateNextValue(firstValue, step),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// 복사 모드 (패턴 반복)
|
||||||
|
const sourceRowOffset = (norm.startRow - targetRow - 1) % selectionHeight;
|
||||||
|
const sourceRow = norm.endRow - sourceRowOffset;
|
||||||
|
const sourceValue = String(data[sourceRow]?.[colName] ?? "");
|
||||||
|
newData[targetRow] = {
|
||||||
|
...newData[targetRow],
|
||||||
|
[colName]: sourceValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue