Skip to content

Conversation

@ComputelessComputer
Copy link
Collaborator

@ComputelessComputer ComputelessComputer commented Dec 3, 2025

feat(web): preserve scroll position and add query params to about/brand pages

Summary

This PR makes two related improvements to the about and brand pages:

  1. Scroll Position Preservation: Added resetScroll: false to all navigate() calls in both pages so the global scroll position is maintained when navigating between items inside the MockWindow component.

  2. Query Params for Brand Page: Added URL query parameter support to brand.tsx (matching the existing pattern in about.tsx) so users can deep link to specific items:

    • /brand?type=visual&id=icon
    • /brand?type=typography&id=primary-font
    • /brand?type=color&id=stone-600
  3. Invalid Deep Link Handling: Added else branches to clear selection when a valid type is provided but the ID doesn't match any item (fixes a potential stale state issue).

Review & Testing Checklist for Human

  • Test scroll preservation: Navigate to /about or /brand, scroll down the page, then click on items in the MockWindow. The page scroll position should NOT reset to top.
  • Test deep linking on brand page: Try URLs like /brand?type=visual&id=logo and verify the correct item is selected on page load.
  • Test invalid deep links: Try /brand?type=visual&id=nonexistent and verify the selection is cleared (not stuck on stale state).

Notes

… brand pages

- Add resetScroll: false to navigate calls in about.tsx to preserve scroll position
- Add query params handling to brand.tsx (type: visual/typography/color, id)
- Add resetScroll: false to navigate calls in brand.tsx
- Fix potential issue where invalid deep links now properly clear selection

Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
@devin-ai-integration
Copy link
Contributor

🤖 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 that start with 'DevinAI' or '@devin'.
  • 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 and CI monitoring

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

📝 Walkthrough

Walkthrough

Two view routes were updated to improve navigation state management. The about route adds null fallback handling when searches fail and adds resetScroll flags to navigation calls. The brand route introduces a public BrandSearch type, adds a validateSearch hook to Route, and implements URL-based state synchronization with navigation integration on item selection.

Changes

Cohort / File(s) Summary
About view navigation handling
apps/web/src/routes/_view/about.tsx
Added null fallback when search queries fail to match items; updated all navigation calls to include resetScroll: false to prevent scroll resets during item selection
Brand view routing and state sync
apps/web/src/routes/_view/brand.tsx
Introduced public BrandSearch type and validateSearch hook on Route; integrated useNavigate with useEffect to sync URL search parameters (type/id) with internal state; added handleSetSelectedItem handler to update navigation on item selection

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • brand.tsx route validation: Ensure validateSearch correctly maps and validates search parameters for visual/typography/color types and id fields
  • State synchronization logic: Review useEffect dependencies and sync correctness between Route search params and component state
  • Navigation consistency: Verify resetScroll flag handling is applied uniformly across both routes and all navigation call sites
  • Public API stability: Confirm BrandSearch type definition and validateSearch behavior meet requirements for external consumers

Possibly related PRs

Suggested reviewers

  • yujonglee

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main changes: scroll position preservation and query parameter support for about and brand pages.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining scroll preservation, query params support, and invalid link handling with testing guidance.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/1764760699-preserve-scroll-position

Comment @coderabbitai help to get the list of available commands and usage tips.

@netlify
Copy link

netlify bot commented Dec 3, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit 7cdc315
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/69301e799ff9d20008635749
😎 Deploy Preview https://deploy-preview-2100--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Dec 3, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 7cdc315
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/69301e795e49c40008569691
😎 Deploy Preview https://deploy-preview-2100--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/web/src/routes/_view/about.tsx (1)

18-21: Consider inlining the type per coding guidelines.

The AboutSearch type is only used as the return type for validateSearch and isn't shared across files. Per coding guidelines, types should generally be inlined unless shared. However, having the explicit type does improve readability, so this is a minor point.

As per coding guidelines, consider inlining:

-type AboutSearch = {
-  type?: "story" | "founder" | "photo";
-  id?: string;
-};
-
 export const Route = createFileRoute("/_view/about")({
   component: Component,
-  validateSearch: (search: Record<string, unknown>): AboutSearch => {
+  validateSearch: (search: Record<string, unknown>): { type?: "story" | "founder" | "photo"; id?: string } => {
apps/web/src/routes/_view/brand.tsx (1)

16-19: Consider inlining the type per coding guidelines.

Similar to the about.tsx file, BrandSearch is only used locally for the validateSearch return type. Per coding guidelines, consider inlining the type, though the explicit type does improve readability.

As per coding guidelines, consider inlining:

-type BrandSearch = {
-  type?: "visual" | "typography" | "color";
-  id?: string;
-};
-
 export const Route = createFileRoute("/_view/brand")({
   component: Component,
-  validateSearch: (search: Record<string, unknown>): BrandSearch => {
+  validateSearch: (search: Record<string, unknown>): { type?: "visual" | "typography" | "color"; id?: string } => {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d847251 and 7cdc315.

📒 Files selected for processing (2)
  • apps/web/src/routes/_view/about.tsx (2 hunks)
  • apps/web/src/routes/_view/brand.tsx (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/routes/_view/brand.tsx
  • apps/web/src/routes/_view/about.tsx
🧠 Learnings (1)
📚 Learning: 2025-11-24T16:32:23.055Z
Learnt from: CR
Repo: fastrepl/hyprnote PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T16:32:23.055Z
Learning: Applies to **/*.{ts,tsx} : Use `motion/react` instead of `framer-motion`.

Applied to files:

  • apps/web/src/routes/_view/brand.tsx
🧬 Code graph analysis (2)
apps/web/src/routes/_view/brand.tsx (2)
apps/web/src/routes/_view/about.tsx (1)
  • Route (23-45)
apps/web/src/routes/_view/index.tsx (1)
  • Route (115-117)
apps/web/src/routes/_view/about.tsx (1)
plugins/windows/src/ext.rs (1)
  • navigate (19-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - hyprnote-storybook
  • GitHub Check: Header rules - hyprnote-storybook
  • GitHub Check: Pages changed - hyprnote-storybook
  • GitHub Check: ci
  • GitHub Check: fmt
  • GitHub Check: Devin
🔇 Additional comments (8)
apps/web/src/routes/_view/about.tsx (3)

25-35: LGTM! Proper input validation.

The validateSearch implementation correctly validates and sanitizes search parameters, ensuring only valid type values and string IDs are accepted.


159-179: LGTM! Robust URL-to-state synchronization.

The useEffect properly syncs URL search params to local state with defensive null checks when items aren't found. Lines 166-167 and 173-174 correctly handle missing founders/photos by setting state to null rather than leaving stale data.


181-198: LGTM! Consistent scroll preservation.

The handleSetSelectedItem function correctly:

  • Updates local state immediately for responsive UI
  • Syncs state to URL with resetScroll: false to preserve scroll position (per PR objectives)
  • Handles all item types consistently
apps/web/src/routes/_view/brand.tsx (5)

1-1: LGTM! Correct imports for URL state management.

The additions of useNavigate and useEffect imports are necessary for the URL-driven state synchronization implementation.

Also applies to: 4-4


23-33: LGTM! Proper search parameter validation.

The validateSearch implementation correctly validates search parameters for the brand route, ensuring type safety.


143-168: LGTM! Comprehensive URL synchronization.

The useEffect correctly handles all three item types (visual, typography, color) with proper null fallback when items aren't found. The defensive programming ensures no stale state remains when an invalid ID is provided.


170-190: LGTM! Consistent state-to-URL navigation.

The handleSetSelectedItem function mirrors the pattern in about.tsx, providing:

  • Immediate local state updates for responsive UI
  • URL synchronization with resetScroll: false to preserve scroll position
  • Consistent handling across all item types

139-140: LGTM! Clean integration of URL state management.

The integration of useNavigate, Route.useSearch(), and handleSetSelectedItem seamlessly adds URL-driven state management without disrupting the existing component structure.

Also applies to: 201-201

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.

2 participants