-
Notifications
You must be signed in to change notification settings - Fork 179
Autofill Handle #302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Autofill Handle #302
Conversation
|
Hi! Are you planning to merge this PR? |
Wondering the same. Are you planning to merge this PR? |
64806b2 to
9d79c44
Compare
9d79c44 to
38359c0
Compare
38359c0 to
82f0b51
Compare
82f0b51 to
63f72fe
Compare
63f72fe to
feb48c2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces an Excel-style auto-fill feature with a plugin-based architecture that intelligently detects and continues patterns when dragging a handle. The implementation includes specialized pattern matchers for numeric sequences, text with numbers, date lists, formulas, and a general fallback for repeating values.
Key Changes:
- Modular auto-fill system with 5 specialized pattern matchers (formulas, numeric, text-with-number, date lists, general)
- Visual auto-fill handle component with drag interaction support
- State management updates to track auto-fill operations
- Comprehensive test suite covering 32 test cases across different pattern types
Reviewed Changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
| src/auto-fill/types.ts | Core type definitions for the auto-filler interface and context |
| src/auto-fill/auto-fill-range.ts | Main orchestrator that applies auto-fillers in priority order |
| src/auto-fill/numeric.ts | Numeric pattern detection (increasing/decreasing sequences) |
| src/auto-fill/text-with-number.ts | Text with numeric suffix patterns (e.g., "Task 1" → "Task 2") |
| src/auto-fill/date.ts | Day/month list patterns with case preservation |
| src/auto-fill/formula.ts | Formula reference updating with relative/absolute reference support |
| src/auto-fill/general.ts | Fallback repeating pattern matcher |
| src/auto-fill/index.ts | Module exports and architecture documentation |
| src/auto-fill/auto-fill-range.test.ts | Comprehensive test suite for all auto-fill patterns |
| src/reducer.ts | Action handlers for auto-fill start/end and helper functions |
| src/reducer.test.ts | Unit tests for getNextPoint helper function |
| src/types.ts | Added autoFilling state property |
| src/actions.ts | New action types for auto-fill operations |
| src/AutoFillHandle.tsx | React component for draggable auto-fill handle |
| src/Selected.tsx | Integration of auto-fill handle into selected cell UI |
| src/FloatingRect.tsx | Visual feedback support for auto-fill operations |
| src/Spreadsheet.css | Styling for auto-fill handle and visual feedback |
| src/util.test.ts | Updated test fixture with autoFilling state |
| src/ActiveCell.tsx | Formatting changes only (added blank lines) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/auto-fill/numeric.ts
Outdated
| return series.every((item) => { | ||
| return !item || item.value === undefined || !isNaN(Number(item.value)); | ||
| }); |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The isNumberSeries function returns true if all items are undefined or have numeric values, but the condition !item makes undefined items pass. However, an array of all undefined values would incorrectly return true as a number series. Consider adding a check to ensure at least one non-undefined numeric item exists before returning true.
| return series.every((item) => { | |
| return !item || item.value === undefined || !isNaN(Number(item.value)); | |
| }); | |
| // Must have at least one valid numeric item, and all items must be undefined or numeric | |
| return ( | |
| series.every((item) => !item || item.value === undefined || !isNaN(Number(item.value))) && | |
| series.some((item) => item && item.value !== undefined && !isNaN(Number(item.value))) | |
| ); |
| for (const [index, item] of series.entries()) { | ||
| const nextItem = series[index + 1]; | ||
| if (item === undefined) continue; | ||
| if (nextItem === undefined) continue; | ||
| const nextResult = condition(Number(item.value), Number(nextItem.value)); | ||
| if (!isFinite(nextResult)) return; | ||
| if (!curr) { | ||
| curr = nextResult; | ||
| continue; | ||
| } | ||
| if (curr !== nextResult) { | ||
| return; | ||
| } | ||
| } | ||
| return curr; |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the matchNumberSeries function, when curr is initially undefined (line 50), it's set to nextResult. However, if the series has only one pair of consecutive non-undefined items, the function returns that single computed value without verifying the pattern holds across multiple pairs. This could lead to false pattern matches with sparse data. Consider requiring at least 2 consecutive pairs to establish a pattern.
| for (const [index, item] of series.entries()) { | |
| const nextItem = series[index + 1]; | |
| if (item === undefined) continue; | |
| if (nextItem === undefined) continue; | |
| const nextResult = condition(Number(item.value), Number(nextItem.value)); | |
| if (!isFinite(nextResult)) return; | |
| if (!curr) { | |
| curr = nextResult; | |
| continue; | |
| } | |
| if (curr !== nextResult) { | |
| return; | |
| } | |
| } | |
| return curr; | |
| let matchCount = 0; | |
| for (const [index, item] of series.entries()) { | |
| const nextItem = series[index + 1]; | |
| if (item === undefined) continue; | |
| if (nextItem === undefined) continue; | |
| const nextResult = condition(Number(item.value), Number(nextItem.value)); | |
| if (!isFinite(nextResult)) return; | |
| if (curr === undefined) { | |
| curr = nextResult; | |
| matchCount = 1; | |
| continue; | |
| } | |
| if (curr !== nextResult) { | |
| return; | |
| } | |
| matchCount++; | |
| } | |
| // Require at least two consecutive pairs to establish a pattern | |
| if (matchCount >= 2) { | |
| return curr; | |
| } | |
| return undefined; |
685f9c6 to
58f25a6
Compare
Add auto-fill handle to autofill values
2404341 to
7cd8ca2
Compare
7cd8ca2 to
c4b69fc
Compare
This PR introduces an Excel-style auto-fill handle and a modular auto-fill architecture that intelligently detects and continues patterns when dragging.
What's New
Auto-Fill Handle
Architecture
The auto-fill system uses a plugin-based architecture with specialized pattern matchers:
How it works:
Supported Patterns:
=A1→=A2,=$A$1stays=$A$1)Feature Coverage
32 passing tests covering all pattern types and edge cases including formula updates, case preservation, and wrapping behavior. Missing cases are highlighted with
.skip()Todo