Skip to content

Shed legacy deps: flatpickr/react-select → native+MUI, auto-animate 0.9#167

Merged
rchalamala merged 1 commit into
devin/1781144786-mui-9-upgradefrom
devin/1781148194-shed-legacy-deps
Jun 11, 2026
Merged

Shed legacy deps: flatpickr/react-select → native+MUI, auto-animate 0.9#167
rchalamala merged 1 commit into
devin/1781144786-mui-9-upgradefrom
devin/1781148194-shed-legacy-deps

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Removes the last legacy UI deps (flatpickr, react-flatpickr, react-select) and bumps @formkit/auto-animate 0.8 → 0.9.

  • Available Times pickers (Planner.tsx): replaced <Flatpickr> with a small TimeInput component wrapping native <input type="time">, styled via .planner-time-input (same border/centering as the old flatpickr input; webkit picker indicator hidden so it fits the narrow per-day columns). Keeps the fix: mobile time-picker alignment + null-safe Default Schedule #162 grid layout so mobile alignment is preserved. onChange builds the new Date from the existing value via setHours(h, m, 0, 0), so updateAvailableTimes keeps the same interface.
  • react-select → MUI Autocomplete (Workspace.tsx): note — react-select was used in two places, not just one: the section dropdown (SectionDropdown) and the course search (WorkspaceSearch). Both now use Autocomplete + TextField. The course search's fzf fuzzy matching moved into filterOptions, which also let me delete the old "hacky" options/firstLoad state workaround.
  • @formkit/auto-animate ^0.9.0 — single useAutoAnimate usage unchanged.
  • README: documents that preact/@preact/signals are Schedule-X runtime peer deps and must not be removed despite never being imported in src/.

npm run verify and npx react-doctor@latest -y --offline --fail-on error both pass.

Before / After screenshots

🔴 Before (main: flatpickr time pickers) 🟢 After (native <input type="time">)
before time pickers after time pickers
🔴 Before (react-select course search) 🟢 After (MUI Autocomplete, fzf preserved)
before search after search
🔴 Before (mobile ~400px, main) 🟢 After (mobile ~400px, time pickers aligned)
before mobile after mobile

Note: there is no term-selector UI — terms are selected via URL path (e.g. /fa2027); react-select's actual second usage was the section dropdown, shown working in the E2E test results comment below.

Link to Devin session: https://app.devin.ai/sessions/b0dfbfcdc60a4103b556ac5fedbda923
Requested by: @rchalamala


Open in Devin Review

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 11, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
caltech-dev aa3fa14 Commit Preview URL

Branch Preview URL
Jun 11 2026, 04:17 AM

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

Open in Devin Review

Comment thread src/Workspace.tsx
Comment on lines 429 to 430
selector: (item) => `${item.number} ${item.name}`,
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Fzf instance recreated on every render in WorkspaceSearch

The new Fzf(courses, ...) at src/Workspace.tsx:428 is instantiated inside the component body, meaning it's recreated on every render. The Fzf constructor does internal preprocessing (e.g., building scoring structures) over all courses. While functionally correct — filterOptions always uses the latest fzf from the same render cycle — this is wasteful. The old code had a similar pattern (creating fzf in the component body). Consider wrapping in useMemo keyed on courses to avoid redundant work, though the impact depends on catalog size.

(Refers to lines 428-430)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/Workspace.tsx
Comment on lines 215 to 222
value={
course.sectionId !== null
? course.courseData.sections.find(
? (course.courseData.sections.find(
(c) =>
c.number ===
course.courseData.sections[course.sectionId!].number,
)
) ?? null)
: null

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: SectionDropdown value lookup is roundabout but correct

The value prop at src/Workspace.tsx:215-222 does a find by section number on the same array that's used as options, rather than simply using course.courseData.sections[course.sectionId!]. This roundabout lookup ensures the value is the exact same object reference from the options array, which is important for MUI Autocomplete's internal comparison logic. The isOptionEqualToValue at line 227-228 provides a fallback, so a simpler sections[sectionId] would also work — but the current approach is defensively correct.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/Workspace.tsx
Comment on lines 432 to 448
return (
<Select
isClearable
<Autocomplete
size="small"
className="my-3"
placeholder="Add a course..."
options={options}
options={courses}
value={selectedCourse}
getOptionLabel={(course) => `${course?.number} - ${course?.name}`}
onChange={handleSelect}
isOptionSelected={(course) => course.id === selectedCourse?.id}
onInputChange={sortCourses}
filterOption={() => {
return true;
}}
getOptionLabel={(course) => `${course.number} - ${course.name}`}
isOptionEqualToValue={(option, selected) => option.id === selected.id}
onChange={(_event, courseData) => handleSelect(courseData)}
filterOptions={(allOptions, { inputValue }) =>
inputValue ? fzf.find(inputValue).map((item) => item.item) : allOptions
}
renderInput={(params) => (
<TextField {...params} placeholder="Add a course..." />
)}
/>
);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Removed hacky options state workaround from old WorkspaceSearch

The old code had a comment acknowledging a hack: options = [] on second render was worked around with firstLoad state and manual override (src/Workspace.tsx:412-420 on the LEFT side). The new MUI Autocomplete approach passes courses directly as the options prop and delegates filtering to filterOptions, which cleanly eliminates the need for the options state and the workaround. This is a genuine improvement in code quality.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/css/planner.css
Comment on lines +27 to +28
.planner-time-input::-webkit-calendar-picker-indicator {
display: none;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Native time input hides picker indicator via webkit-only pseudo-element

The CSS at src/css/planner.css:27-28 uses ::-webkit-calendar-picker-indicator { display: none; } to hide the browser's time picker button. This only works in WebKit/Blink browsers (Chrome, Edge, Safari). In Firefox, the native time input renders its own spinner/picker UI which cannot be hidden with this selector. This is a minor cross-browser styling inconsistency but doesn't affect functionality.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

E2E Test Results — all 6 tests passed

Tested on the Vite dev server (PR branch), desktop + mobile (~400px) viewports, term /fa2027 (and /wi2026 for term switch). CI is green; npm run verify and react-doctor pass.

  • ✔ Native time pickers: Monday start set to 12:00 PM, value displays correctly and arrangement scheduling reflects the constraint
  • ✔ Course search (MUI Autocomplete + fzf): "cs 1" fuzzy-filters; selecting CS 152 adds it to list + calendar (units 33 → 45)
  • ✔ Section dropdown (MUI Autocomplete): Ph 1a section 1 → 3 updates card location (107 DWN → 187 LINDE) and calendar
  • ✔ Auto-animate 0.9: card collapse/expand animates smoothly, console clean
  • ✔ Mobile alignment (preserve fix: mobile time-picker alignment + null-safe Default Schedule #162): 5 time-picker columns aligned over weekday columns at 400px, no overflow
  • ✔ Term switch regression: /wi2026 footer + winter catalog search work
Time pickers & section dropdown (the replaced components)
Native time pickers + section dropdown (desktop) Section dropdown open (sections 1–10)
desktop section dropdown
Course search + auto-animate + mobile + term switch
MUI Autocomplete course search ("cs 1") Ma 1a card collapsed (auto-animate 0.9)
search collapsed
Mobile 400px alignment wi2026 term search
mobile wi2026

Notes:

  • "No arrangements found :(" after Unlock All on the default schedule is preexisting on main (reproduced identically there) — not a regression from this PR.
  • The native time input was set programmatically in automated testing (native setter + change event) since keyboard segment entry is finicky to script; it exercises the same React onChange path.

Tested by Devin

…animate

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>
@devin-ai-integration devin-ai-integration Bot force-pushed the devin/1781148194-shed-legacy-deps branch from f7ead4d to aa3fa14 Compare June 11, 2026 04:16
@devin-ai-integration devin-ai-integration Bot changed the base branch from main to devin/1781144786-mui-9-upgrade June 11, 2026 04:16
@rchalamala rchalamala merged commit 56fba89 into devin/1781144786-mui-9-upgrade Jun 11, 2026
6 checks passed
rchalamala added a commit that referenced this pull request Jun 12, 2026
…catalogs, MUI 9, dep-shedding (#166)

* deps: bump vite to 7.3.5, wrangler to 4.98.0; npm audit clean

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* chore: upgrade toolchain majors (TypeScript 6, Vite 8, svgr 5, tsconfig-paths 6)

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* perf: lazy-load term catalogs and split vendor chunks

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: no-op workspace mutations while term catalog is loading

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: log error when term catalog fails to load

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: sync catalog state before paint when the term changes

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* build: use function-form manualChunks for rolldown compatibility

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* chore: upgrade MUI to v9.1.0 (HelpOutline -> HelpOutlined icon rename)

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: use HelpOutlineOutlined to preserve original HelpOutline glyph

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: re-sync search options after async catalog load

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: key search option re-sync on catalog identity

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* chore: upgrade toolchain majors (TypeScript 6, Vite 8, svgr 5, tsconfig-paths 6) (#165)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* perf: lazy-load term catalogs + vendor code splitting (8.2 MB → ~1.0 MB initial JS) (#164)

* perf: lazy-load term catalogs and split vendor chunks

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: no-op workspace mutations while term catalog is loading

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: log error when term catalog fails to load

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: sync catalog state before paint when the term changes

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* build: use function-form manualChunks for rolldown compatibility

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: re-sync search options after async catalog load

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: key search option re-sync on catalog identity

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* chore: upgrade MUI to v9.1.0 (#163)

* chore: upgrade MUI to v9.1.0 (HelpOutline -> HelpOutlined icon rename)

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: use HelpOutlineOutlined to preserve original HelpOutline glyph

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* Replace flatpickr and react-select with native/MUI inputs, bump auto-animate (#167)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* build: pin wrangler to exact 4.98.0 (4.99+ wrangler dev assets 404 regression)

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* chore: gitignore .wrangler local dev cache

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* review: restore Icon gitignore CRs, drop stale lightningcss errorRecovery (flatpickr removed)

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

* fix: alert instead of silent no-op for Import Workspace / Default Schedule while catalog loads

Co-Authored-By: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rahul Chalamala <22563365+rchalamala@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant