Skip to content

Update the tutorial - #34

Merged
fulopkovacs merged 22 commits into
mainfrom
tutorial
Jan 1, 2026
Merged

Update the tutorial#34
fulopkovacs merged 22 commits into
mainfrom
tutorial

Conversation

@fulopkovacs

@fulopkovacs fulopkovacs commented Dec 31, 2025

Copy link
Copy Markdown
Owner

The guide was in a rough state. Here are a few essential things that needed to be taken care of:

  • ugly design (now it's less ugly)
  • dark mode
  • highlights feature (bad UI + UX)
  • + other smaller improvements

Summary by CodeRabbit

  • New Features

    • Tutorial table of contents sidebar
  • New / Updated UI

    • Resizable tutorial window with close control and persistent sizing
    • Scroll-shadow indicators for scrollable regions
    • Updated primary button styling and smoother sidebar color transitions
    • Reworked tutorial navigation to use the new sidebar
  • Behavior Changes

    • Highlights now clear automatically after viewing; explicit clear-control removed
  • Content & Styling

    • Code presentation refreshed (Shiki-based styling, JetBrains Mono, improved code-block display)

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 31, 2025

Copy link
Copy Markdown

Walkthrough

Replaces an in-file ScrollShadow with a shared component, extends useScrollShadow API, adds TutorialTableOfContents and refactors TutorialWindow (scroll/resize/shadows/close/persistence), swaps syntax-highlighting to Shiki, removes ClearHighlightsButton exports, updates MDX imports and code-block languages, and adjusts styles and fonts.

Changes

Cohort / File(s) Summary
ScrollShadow component & usage
src/components/ui/scroll-shadow.tsx, src/components/TodoBoards.tsx
Adds exported ScrollShadow component; TodoBoards now imports and uses the shared component instead of an in-file implementation.
useScrollShadow hook
src/hooks/use-scroll-shadow.ts
Hook signature updated to `useScrollShadow(externalRef?: React.RefObject<HTMLDivElement
Tutorial TOC & window
src/components/tutorial/TutorialTableOfContents.tsx, src/components/tutorial/TutorialWindow.tsx, src/components/tutorial/index.tsx
Adds TutorialTableOfContents; refactors TutorialWindow to TOC-driven navigation and ScrollArea rendering; introduces ScrollShadow usage, FloatingWindow header/close, live resize handles, debounced windowSize persistence; FloatingWindow now accepts toggleWindow.
Tutorial highlight & API surface
src/components/tutorial/index.tsx, src/utils/highlight-collection-related-info.tsx
Removes ClearHighlightsButton export and removes its imports from MDX files; HighLightComponent prop aliasing changed internally; highlight wrapper now triggers timed removal of highlight query param and updates transition/outline styling.
UI styling tweaks
src/components/ToggleFloatingWindowButton.tsx, src/components/ui/sidebar.tsx
Button color classes replaced (e.g., bg-orange-*bg-primary + hover:brightness-90); SidebarMenuSubButton adds transition-colors.
Routing / root document
src/routes/__root.tsx
Added ScriptOnce import; swapped monospace font to JetBrains Mono via Google Fonts; adjusted HTML class specificity and import ordering.
Syntax highlighting & build
vite.config.ts, package.json, src/styles.css
Replaced rehype/prism stack with @shikijs/rehype (Shiki); Vite MDX plugin updated to use Shiki with theme mapping and a transformer to add data-language attributes; updated Shiki-related CSS and --font-mono.
MDX content changes
src/data/tutorial/collections-intro.mdx, src/data/tutorial/how-do-collections-work.mdx, src/data/tutorial/optimistic-actions.mdx, src/data/tutorial/optimistic-updates.mdx, src/data/tutorial/what-is-next.mdx, ...
Removed ClearHighlightsButton imports across multiple MDX files; converted several fenced code blocks from tstsx; minor text edits.
Minor utils & comments
src/utils/getTutorialDataHandlers.ts, src/utils/highlight-collection-related-info.tsx
Added a TODO/comment for future zod validation in parse flow; highlight wrapper adds navigation effect to clear highlight param after a delay.
Miscellaneous
package.json, src/components/TodoBoards.tsx, src/styles.css
Added @shikijs/rehype; removed prismjs and rehype-prism-plus; updated code block styling and fonts in CSS; TodoBoards switched to use shared ScrollShadow.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant TOC as TutorialTableOfContents
    participant Window as TutorialWindow / FloatingWindow
    participant Content as StepRenderer
    participant Hook as useScrollShadow
    participant Shadow as ScrollShadow
    participant Store as TutorialDataHandlers

    Note over User,TOC: User selects tutorial entry
    User->>TOC: click item
    TOC->>Window: onStepChange(stepTitle)
    Window->>Window: set activeStep & restore scroll position
    Window->>Content: render step content inside ScrollArea
    Content->>Hook: init with content ref (deps include activeStep)
    Hook->>Shadow: compute top/bottom visibility
    Shadow->>User: render shadows (visible/hidden)
    User->>Content: scroll
    Hook->>Shadow: update visibility on scroll
    Note over User,Window: resize interaction
    User->>Window: drag resize handle
    Window->>Window: apply live constrained DOM size
    Window->>Store: persist windowSize (debounced)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Update the theme #22: Overlaps on ScrollShadow component and useScrollShadow hook changes; likely closely related to the scroll-shadow API and implementation updates.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Update the tutorial' is vague and generic, using non-descriptive language that doesn't clearly convey the specific changes made in this comprehensive changeset. Revise the title to be more specific about the primary changes, such as 'Refactor tutorial UI with new component structure and styling updates' or 'Update tutorial with improved navigation and dark mode support'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent 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 64e4212 and 63641d5.

📒 Files selected for processing (1)
  • src/utils/highlight-collection-related-info.tsx
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always ensure no formatting/linting issues exist in code - use pnpm check --fix to automatically fix issues

Files:

  • src/utils/highlight-collection-related-info.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functions over arrow functions for React components

Files:

  • src/utils/highlight-collection-related-info.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer type over interface for type definitions

Files:

  • src/utils/highlight-collection-related-info.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
📚 Learning: 2025-12-28T23:34:13.416Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 32
File: src/components/HomeIntro.tsx:16-25
Timestamp: 2025-12-28T23:34:13.416Z
Learning: In Motion (motion/react), when configuring variant transitions, use delayChildren: stagger(x) to create per-child delays (e.g., delayChildren: stagger(0.2)). This is different from the older API that used a separate staggerChildren property. Apply this guidance to TSX files that declare motion variants (e.g., in src/components/**/*.tsx) and verify that stagger is imported from framer-motion. Ensure transitions reflect the intended stagger timing and that no conflicting delay values override the staggered effect.

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
🧬 Code graph analysis (1)
src/utils/highlight-collection-related-info.tsx (2)
src/components/tutorial/index.tsx (1)
  • HighlightParam (24-24)
src/lib/utils.ts (1)
  • cn (4-6)
⏰ 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). (1)
  • GitHub Check: Deploy Preview
🔇 Additional comments (4)
src/utils/highlight-collection-related-info.tsx (4)

1-4: LGTM! Clean import organization.

The imports are well-organized and follow TypeScript best practices with the type import syntax for ReactNode.


19-31: LGTM! Well-implemented auto-clear effect.

The useEffect correctly:

  • Sets a 1-second timeout to remove the highlight parameter
  • Cleans up the timeout on unmount or when isHighlighted changes
  • Uses replace: true to avoid polluting browser history
  • Handles the search param removal cleanly with destructuring

33-44: LGTM! Effective styling with good UX timing.

The conditional styling creates a nice visual effect:

  • Quick highlight appearance (300ms) provides immediate feedback
  • Slow fade-out (1000ms) ensures the highlight is noticeable
  • Dark mode variants are properly included
  • Previous accessibility concern with aria-hidden has been addressed ✅

16-17: The startsWith() logic is intentional and correctly implemented.

The naming convention in src/components/tutorial/index.tsx explicitly documents this behavior: "Naming convention: project highlights any ids starting with project (e.g., project, project_sidebar)". The partial matching using startsWith() is by design to enable grouping related highlight IDs—setting highlight="project" will highlight all elements with IDs like "project_sidebar" and "project_projectPage".

No changes needed.


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/utils/highlight-collection-related-info.tsx (1)

36-47: Reconsider aria-hidden="true" on the wrapper containing children.

Setting aria-hidden="true" hides the entire subtree from assistive technologies (screen readers). If children contains meaningful content that users need to access, this will create an accessibility barrier.

Consider whether this attribute is intentional. If the highlight wrapper is purely decorative, it might be better to apply aria-hidden only to the visual highlight effect rather than the content itself, or remove it entirely if the children should remain accessible.

🔎 Proposed fix if children should remain accessible
  return (
    <div
-     aria-hidden="true"
      className={cn(
        "outline outline-offset-4 transition-all ease-in-out rounded-sm",
        isHighlighted
          ? "outline-destructive bg-destructive/10 duration-300"
          : "outline-destructive/0 bg-destructive/0 duration-1000",
      )}
    >
      {children}
    </div>
  );
src/components/tutorial/TutorialWindow.tsx (1)

122-124: Remove commented-out code.

Lines 122-124 contain commented-out code that should be removed to maintain code cleanliness.

🔎 Proposed fix
     updateWindowSizeLimits();
     if (typeof window !== "undefined") {
-      // getTutorialDataHandlers().then(({ tutorialData }) => {
-      //   setWindowSize(tutorialData.windowSize);
-      // });
       window.addEventListener("resize", updateWindowSizeLimits);
       return () => {
🧹 Nitpick comments (2)
src/components/ToggleFloatingWindowButton.tsx (1)

18-20: Add an empty dependency array to the useEffect.

The effect is intended to run once on mount to set mounted to true, but without a dependency array, it runs on every render. While setMounted(true) is idempotent and won't cause re-renders after the first call, adding an empty dependency array makes the intent explicit and avoids unnecessary function calls.

🔎 Proposed fix
  useEffect(() => {
    setMounted(true);
- });
+ }, []);
src/hooks/use-scroll-shadow.ts (1)

3-7: Consider using type instead of interface for consistency.

Per coding guidelines, type is preferred over interface for type definitions in TypeScript files.

🔎 Proposed change
-export interface UseScrollShadowReturn {
+export type UseScrollShadowReturn = {
   scrollRef: React.RefObject<HTMLDivElement | null>;
   canScrollUp: boolean;
   canScrollDown: boolean;
-}
+};
📜 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 d159976 and dc4c280.

📒 Files selected for processing (10)
  • src/components/TodoBoards.tsx
  • src/components/ToggleFloatingWindowButton.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/components/ui/sidebar.tsx
  • src/hooks/use-scroll-shadow.ts
  • src/routes/__root.tsx
  • src/utils/highlight-collection-related-info.tsx
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always ensure no formatting/linting issues exist in code - use pnpm check --fix to automatically fix issues

Files:

  • src/components/ToggleFloatingWindowButton.tsx
  • src/components/ui/sidebar.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/hooks/use-scroll-shadow.ts
  • src/routes/__root.tsx
  • src/components/TodoBoards.tsx
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functions over arrow functions for React components

Files:

  • src/components/ToggleFloatingWindowButton.tsx
  • src/components/ui/sidebar.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/hooks/use-scroll-shadow.ts
  • src/routes/__root.tsx
  • src/components/TodoBoards.tsx
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer type over interface for type definitions

Files:

  • src/components/ToggleFloatingWindowButton.tsx
  • src/components/ui/sidebar.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/hooks/use-scroll-shadow.ts
  • src/routes/__root.tsx
  • src/components/TodoBoards.tsx
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/components/ToggleFloatingWindowButton.tsx
  • src/components/ui/sidebar.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/routes/__root.tsx
  • src/components/TodoBoards.tsx
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
📚 Learning: 2025-12-28T23:34:13.416Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 32
File: src/components/HomeIntro.tsx:16-25
Timestamp: 2025-12-28T23:34:13.416Z
Learning: In Motion (motion/react), when configuring variant transitions, use delayChildren: stagger(x) to create per-child delays (e.g., delayChildren: stagger(0.2)). This is different from the older API that used a separate staggerChildren property. Apply this guidance to TSX files that declare motion variants (e.g., in src/components/**/*.tsx) and verify that stagger is imported from framer-motion. Ensure transitions reflect the intended stagger timing and that no conflicting delay values override the staggered effect.

Applied to files:

  • src/components/ToggleFloatingWindowButton.tsx
  • src/components/ui/sidebar.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/routes/__root.tsx
  • src/components/TodoBoards.tsx
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
📚 Learning: 2025-12-29T13:20:08.377Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-29T13:20:08.377Z
Learning: Applies to src/route/__root.tsx : The root route is located at `src/route/__root.tsx` in this TanStack Start project

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
  • src/routes/__root.tsx
🧬 Code graph analysis (6)
src/components/ToggleFloatingWindowButton.tsx (2)
src/components/ui/button.tsx (1)
  • Button (42-61)
src/components/ui/switch.tsx (1)
  • Switch (6-27)
src/components/tutorial/TutorialTableOfContents.tsx (2)
src/data/tutorial.ts (2)
  • tutorialArticles (43-48)
  • deepDiveArticles (64-64)
src/components/ui/sidebar.tsx (8)
  • SidebarGroup (699-699)
  • SidebarGroupLabel (702-702)
  • SidebarGroupContent (701-701)
  • SidebarMenu (706-706)
  • SidebarMenuItem (710-710)
  • SidebarMenuSub (712-712)
  • SidebarMenuSubItem (714-714)
  • SidebarMenuSubButton (713-713)
src/components/ui/scroll-shadow.tsx (1)
src/lib/utils.ts (1)
  • cn (4-6)
src/utils/highlight-collection-related-info.tsx (1)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/tutorial/TutorialWindow.tsx (6)
src/utils/getTutorialDataHandlers.ts (1)
  • TutorialData (6-14)
src/hooks/use-scroll-shadow.ts (1)
  • useScrollShadow (17-84)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/tutorial/TutorialTableOfContents.tsx (1)
  • TutorialTableOfContents (31-76)
src/components/ui/scroll-shadow.tsx (1)
  • ScrollShadow (3-24)
src/data/tutorial.ts (1)
  • steps (66-66)
src/components/tutorial/index.tsx (1)
src/components/ui/button.tsx (1)
  • Button (63-63)
🪛 GitHub Actions: CI/CD
src/components/tutorial/TutorialTableOfContents.tsx

[error] 13-13: TS6133: 'Button' is declared but its value is never read.

🪛 GitHub Check: CI
src/components/tutorial/TutorialTableOfContents.tsx

[failure] 13-13:
'Button' is declared but its value is never read.

🔇 Additional comments (20)
src/components/ui/sidebar.tsx (1)

683-683: LGTM!

Adding transition-colors to SidebarMenuSubButton enables smooth color transitions on hover and active states, improving the visual feedback consistency with other sidebar components.

src/routes/__root.tsx (1)

207-207: LGTM!

Using the !important modifier (overflow-hidden!) ensures the root HTML element's overflow styling takes precedence over any conflicting styles, which is appropriate given the new scroll shadow features being added throughout the tutorial components.

src/components/ToggleFloatingWindowButton.tsx (1)

38-38: LGTM!

The styling change from hardcoded orange (bg-orange-500) to the theme-aware bg-primary with hover:brightness-90 and transition-all improves consistency with the design system and supports dark mode.

src/utils/highlight-collection-related-info.tsx (1)

21-33: LGTM on the auto-clear highlight behavior.

The effect correctly manages a timeout to auto-remove the highlight parameter after 1 second, with proper cleanup via clearTimeout. Using replace: true in the navigation prevents polluting the browser history.

src/components/tutorial/index.tsx (1)

77-89: LGTM!

The refactored HighLightComponent is cleaner with the Button wrapper providing consistent styling. Using replace={true} on the Link prevents polluting browser history when highlighting elements.

src/components/tutorial/TutorialTableOfContents.tsx (1)

31-76: LGTM on the component structure!

The TutorialTableOfContents component is well-structured with:

  • Proper use of type for props definition (per coding guidelines)
  • Function declaration syntax for the component
  • Clean mapping over sections and articles
  • Proper external link handling with rel="noreferrer"
src/hooks/use-scroll-shadow.ts (2)

17-22: LGTM on the extended hook API!

The optional externalRef and deps parameters provide flexibility for external control while maintaining backward compatibility. The internal ref fallback ensures the hook works without any arguments.


26-44: Good documentation for the lint suppression.

The comment clearly explains why scrollRef.current is intentionally excluded from dependencies—refs don't trigger re-renders, and the deps parameter provides an explicit recalculation mechanism for consumers who need it.

src/components/TodoBoards.tsx (3)

52-52: LGTM!

Good refactor to use the centralized ScrollShadow component from ./ui/scroll-shadow instead of a local implementation. This improves code reuse and maintainability across the application.


265-265: LGTM!

The ScrollShadow component is properly integrated with the useScrollShadow hook, using canScrollUp to control visibility at the top of the scrollable container.


306-306: LGTM!

Consistent usage of ScrollShadow at the bottom position, properly wired to canScrollDown for visibility control.

src/components/ui/scroll-shadow.tsx (1)

1-24: LGTM! Clean implementation with proper Tailwind v4 syntax.

The component correctly uses bg-linear-to-* gradient classes as per Tailwind v4 conventions, and the conditional rendering logic is sound. The opacity transition provides smooth visual feedback.

Based on learnings, the canonical bg-linear-to-* classes are preferred over older bg-gradient-to-* syntax.

src/components/tutorial/TutorialWindow.tsx (8)

1-17: LGTM! Import additions support the new scroll shadow and table of contents features.

All new imports are utilized in the refactored component structure.


19-35: LGTM! Clean header with proper gradient syntax and accessible close button.

The component uses Tailwind v4 canonical gradient classes (bg-linear-to-r) and provides clear window controls.

Based on learnings, bg-linear-to-* is preferred over older bg-gradient-to-* syntax.


50-55: LGTM! Proper integration of scroll shadow hook with external ref.

The useScrollShadow hook is correctly wired with an external ref and the activeStep dependency ensures shadow visibility updates when content changes.


57-121: LGTM! Well-implemented responsive window sizing with proper constraints.

The dynamic limit calculation based on viewport size and debounced persistence provide a good UX. The use of functional state updates (lines 105-114) correctly ensures the latest state is used during window resizing.

Also applies to: 125-164


166-192: LGTM! Clean step navigation with proper state management.

The function correctly clears highlights, persists the step change, and updates local state. The use of useCallback with appropriate dependencies is correct.


220-336: LGTM! Sophisticated resize implementation with good UX considerations.

The direct DOM manipulation during resize (lines 267-268) followed by React state sync (line 276) is an appropriate pattern for performance. The expanded hit areas and hover feedback on resize handles provide excellent usability.


338-414: LGTM! Well-structured layout with scroll shadows and dynamic content.

The integration of ScrollShadow components with the scrollable content area provides clear visual feedback. The dynamic rendering of tutorial steps with optional "Next" navigation is clean and maintainable.


417-509: LGTM! Smooth animations and proper route invalidation.

The motion animation with blur effects (lines 473-490) provides polished visual transitions. The router invalidation (lines 450-452) correctly ensures the loader data refreshes after window state changes, which is essential for persisting window size.

Comment thread src/components/tutorial/TutorialTableOfContents.tsx Outdated
@github-actions

github-actions Bot commented Dec 31, 2025

Copy link
Copy Markdown

🚀 Preview Deployment

Status: ✅ Ready!

Preview URL: Open Preview

Commit: 63641d589fc084561dc47108b8d3ecc304a1fa04

Built and deployed successfully

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/data/tutorial/collections-intro.mdx (1)

56-56: Empty href attribute creates unclear UX.

The link with <a href="">click here</a> has an empty href, which causes a page reload but isn't semantically clear. Consider either removing the link markup (leaving just "reload the page") or making the instruction more explicit.

🔎 Suggested fix

Option 1: Remove the link since the instruction is already clear:

-       2. reload the page (<a href="">click here</a>)
+       2. reload the page

Option 2: Keep the link but use standard reload pattern:

-       2. reload the page (<a href="">click here</a>)
+       2. reload the page (press F5 or Ctrl/Cmd+R)
src/components/tutorial/TutorialWindow.tsx (1)

122-124: Remove commented dead code.

The commented code at lines 122-124 should be removed to keep the codebase clean.

🔎 Proposed fix
     updateWindowSizeLimits();
     if (typeof window !== "undefined") {
-      // getTutorialDataHandlers().then(({ tutorialData }) => {
-      //   setWindowSize(tutorialData.windowSize);
-      // });
       window.addEventListener("resize", updateWindowSizeLimits);
🧹 Nitpick comments (3)
src/data/tutorial/collections-intro.mdx (1)

63-63: Grammar: missing verb in sentence.

The sentence "Live queries updated incrementally" is missing the auxiliary verb "are" or needs a verb form change.

🔎 Suggested fix
-2. Live queries updated incrementally, (they use <a href="https://github.com/electric-sql/d2ts" target="_blank">`d2ts`</a>, a differential dataflow library)
+2. Live queries are updated incrementally (they use <a href="https://github.com/electric-sql/d2ts" target="_blank">`d2ts`</a>, a differential dataflow library)

Note: Also removed the comma before the opening parenthesis for correct punctuation.

src/components/tutorial/TutorialWindow.tsx (2)

195-202: Verify smooth scroll restoration without flicker.

The scroll restoration logic (lines 195-202) combined with the key={activeStep} on the scroll container (line 372) might cause a brief flicker where content appears at the top before scrolling to the saved position. When activeStep changes:

  1. The scroll container remounts (due to the key)
  2. Scroll position resets to 0
  3. The useEffect runs (depending on when tutorialData reference updates)
  4. Scroll position is restored

Ensure this doesn't create a visible flash of content at the top position.

Additionally, line 199 uses parseInt(saved.toString(), 10) when saved should already be a number according to the TutorialData type. This might be defensive programming for legacy localStorage data, but consider simplifying to just scrollRef.current.scrollTop = saved if legacy data isn't a concern.


379-403: Consider performance implications of rendering all steps.

The current implementation maps over all steps and renders a TabsContent component for each one (lines 379-403). While Radix UI's TabsContent hides inactive content visually, all step components are still rendered to the DOM, which could impact performance if:

  • There are many tutorial steps
  • Step content is complex or heavy (e.g., code examples, images)
  • Users are on lower-end devices

Consider implementing lazy loading or conditional rendering to only render the active step's content, especially as the tutorial grows.

Example approach:

<TabsContent value={activeStep} className="w-full overflow-x-hidden pb-3">
  {activeStep && (() => {
    const step = steps.find(s => s.title === activeStep);
    return step ? (
      <div className="fade-in animate-in prose dark:prose-invert prose-md prose-neutral prose-base rounded-lg">
        <step.file />
        {step.nextStepName && (
          <div className="mt-4">
            <button
              type="button"
              onClick={() => handleStepChange(step.nextStepName!)}
              className="text-primary underline hover:brightness-75 transition-colors cursor-pointer"
            >
              Next: {step.nextStepName}
            </button>
          </div>
        )}
      </div>
    ) : null;
  })()}
</TabsContent>
📜 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 82b611f and efc08e3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • package.json
  • src/components/tutorial/TutorialWindow.tsx
  • src/data/tutorial/collections-intro.mdx
  • src/routes/__root.tsx
  • src/styles.css
  • vite.config.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functions over arrow functions for React components

Files:

  • vite.config.ts
  • src/components/tutorial/TutorialWindow.tsx
  • src/routes/__root.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer type over interface for type definitions

Files:

  • vite.config.ts
  • src/components/tutorial/TutorialWindow.tsx
  • src/routes/__root.tsx
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always ensure no formatting/linting issues exist in code - use pnpm check --fix to automatically fix issues

Files:

  • src/components/tutorial/TutorialWindow.tsx
  • src/routes/__root.tsx
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

**/package.json: Always use pnpm install instead of npm install for installing dependencies
Always use pnpm add <package> instead of npm install <package> for adding packages
Always use pnpm add -D <package> instead of npm install --save-dev <package> for adding dev dependencies
Always use pnpm remove <package> instead of npm uninstall <package> for removing packages
Always use pnpm run <script> instead of npm run <script> for running scripts
Always use pnpm dlx <command> instead of npx <command>
Always use pnpm create <template> instead of npm create <template>

Files:

  • package.json
package.json

📄 CodeRabbit inference engine (AGENTS.md)

package.json: Use pnpm dev for starting the development server
Use pnpm build for production build
Use pnpm run test for running tests
Use pnpm lint for linting
Use pnpm typecheck for type checking
Use pnpm format for code formatting
Use pnpm db.generate to generate database migrations
Use pnpm db.local.migrate to apply local migrations
Use pnpm db.prod.migrate to apply production migrations

Files:

  • package.json
🧠 Learnings (3)
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/components/tutorial/TutorialWindow.tsx
  • src/routes/__root.tsx
📚 Learning: 2025-12-28T23:34:13.416Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 32
File: src/components/HomeIntro.tsx:16-25
Timestamp: 2025-12-28T23:34:13.416Z
Learning: In Motion (motion/react), when configuring variant transitions, use delayChildren: stagger(x) to create per-child delays (e.g., delayChildren: stagger(0.2)). This is different from the older API that used a separate staggerChildren property. Apply this guidance to TSX files that declare motion variants (e.g., in src/components/**/*.tsx) and verify that stagger is imported from framer-motion. Ensure transitions reflect the intended stagger timing and that no conflicting delay values override the staggered effect.

Applied to files:

  • src/components/tutorial/TutorialWindow.tsx
  • src/routes/__root.tsx
📚 Learning: 2025-12-29T13:20:08.377Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-29T13:20:08.377Z
Learning: Applies to src/route/__root.tsx : The root route is located at `src/route/__root.tsx` in this TanStack Start project

Applied to files:

  • src/data/tutorial/collections-intro.mdx
  • src/routes/__root.tsx
🧬 Code graph analysis (1)
src/components/tutorial/TutorialWindow.tsx (6)
src/utils/getTutorialDataHandlers.ts (1)
  • TutorialData (6-14)
src/hooks/use-scroll-shadow.ts (1)
  • useScrollShadow (17-84)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/tutorial/TutorialTableOfContents.tsx (1)
  • TutorialTableOfContents (30-75)
src/components/ui/scroll-shadow.tsx (1)
  • ScrollShadow (3-24)
src/data/tutorial.ts (1)
  • steps (66-66)
🔇 Additional comments (16)
src/data/tutorial/collections-intro.mdx (1)

18-18: LGTM! Correct language identifiers for JSX content.

Changing the code fence language from ts to tsx is appropriate since both blocks contain JSX syntax. This ensures proper syntax highlighting in documentation viewers that support Shiki or similar highlighters.

Also applies to: 31-31

vite.config.ts (2)

3-3: LGTM - Syntax highlighting migration to Shiki.

The import of rehypeShiki aligns with the migration from Prism to Shiki for better syntax highlighting capabilities.


30-54: LGTM - Well-configured Shiki setup with custom transformer.

The configuration properly sets up dual-theme support and adds a custom transformer to inject data-language attributes for styling purposes. The type assertion in the transformer (lines 43-45) is a reasonable approach to access MDX plugin context.

src/styles.css (3)

14-17: LGTM - Consistent font variable usage.

The code styling now uses the --font-mono CSS variable, which provides consistency with the font definition at line 178.


19-52: LGTM - Comprehensive Shiki code block styling.

The styling provides:

  • Clean code block presentation with borders and padding
  • Language badge in top-right corner
  • Dual-theme support with proper CSS variable mapping

The !important declarations (lines 44-45, 50-51) are necessary to override Shiki's inline styles and are appropriate here.


178-178: LGTM - Font updated to JetBrains Mono.

This change aligns with the font link update in src/routes/__root.tsx (line 59) and the PR objective to improve legibility and size parity with Space Grotesk.

src/routes/__root.tsx (3)

8-8: LGTM - Import added for existing usage.

The ScriptOnce import was missing but was already being used at line 201. This corrects the import statement.


59-59: LGTM - Font updated to JetBrains Mono with display=swap.

This change aligns with:

  • The CSS variable update in src/styles.css (line 178)
  • PR objectives to improve legibility and size parity

The display=swap parameter ensures text remains visible during font loading.


206-206: LGTM - Correct Tailwind v4 important modifier syntax.

The ! suffix on overflow-hidden! follows Tailwind v4's breaking change where the important modifier now comes at the end of the utility name instead of at the beginning.

Based on learnings: This aligns with Tailwind v4 syntax requirements.

package.json (1)

42-42: Version @shikijs/rehype@3.20.0 is stable and has no known security vulnerabilities.

The latest version matches the pinned version in package.json, and no security advisories were found.

src/components/tutorial/TutorialWindow.tsx (6)

1-17: LGTM!

The import changes cleanly reflect the new architecture with scroll shadows, table of contents navigation, and streamlined tab usage.


19-35: LGTM!

The header component is well-structured with proper Tailwind v4 gradient syntax (bg-linear-to-r), clean close button integration, and follows the coding guideline of using function declarations.


266-268: Verify direct DOM manipulation doesn't cause React state inconsistencies.

The code bypasses React's rendering by directly manipulating the DOM during resize for performance (lines 266-268), then syncs the final size back to React state on mouseup (lines 273-276). While this is a valid optimization technique, ensure it doesn't cause any hydration mismatches, visual glitches, or state synchronization issues, especially when combined with the CSS containment on line 376.


53-55: LGTM!

The scroll shadow hook integration is correctly wired with the scrollRef and includes activeStep as a dependency to recalculate shadows when content changes.


365-409: LGTM!

The ScrollShadow components are properly positioned at top and bottom with correct visibility bindings and matching fromColor="from-card" to blend seamlessly with the card background.


417-509: LGTM!

The TutorialWindow component is well-structured with proper state management, router integration, and smooth animations. The toggleWindow callback is correctly threaded through to the FloatingWindow component.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/utils/highlight-collection-related-info.tsx (2)

38-44: Clean transition logic with minor cleanup needed.

The styling implementation creates a smooth highlight-to-normal transition with appropriate durations (300ms for highlighting, 1000ms for fade-out). The use of outline-destructive/0 for the unhighlighted state is a good pattern for smooth transitions.

Consider removing the commented-out code on line 43 to keep the codebase clean.

🔎 Cleanup: Remove commented code
        isHighlighted
          ? "outline-destructive bg-destructive/10 duration-300"
          : "outline-destructive/0 bg-destructive/0 duration-1000",
-       // "outline-destructive bg-destructive/10 outline rounded-sm outline-offset-4",
      )}

9-9: Remove commented-out asChild prop.

The asChild prop is commented out in both the destructuring (line 9) and type definition (line 13). If this feature isn't planned for the near term, removing these comments would improve code clarity.

🔎 Cleanup: Remove commented prop
export function HighlightWrapper({
  highlightId,
  children,
- // asChild,
}: {
  highlightId: Exclude<HighlightParam, undefined>;
  children: ReactNode;
- // asChild?: boolean;
}) {

Also applies to: 13-13

src/components/tutorial/index.tsx (1)

85-88: Button component appears incomplete.

The Button component at line 85 has an empty className="" prop and directly wraps the SearchIcon without any text or accessible label. Consider:

  • Removing the empty className or adding meaningful styles
  • Adding an aria-label to the Button for accessibility
  • Ensuring the Button variant/size is appropriate for this use case
🔎 Proposed improvements
-        <Button className="">
+        <Button aria-label={`Highlight ${children || newHighLightGroupId}`}>
           <SearchIcon />
           {children}
         </Button>
📜 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 efc08e3 and 8e4931b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • package.json
  • src/components/TodoBoards.tsx
  • src/components/ToggleFloatingWindowButton.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/components/ui/sidebar.tsx
  • src/data/tutorial/collections-intro.mdx
  • src/hooks/use-scroll-shadow.ts
  • src/routes/__root.tsx
  • src/styles.css
  • src/utils/getTutorialDataHandlers.ts
  • src/utils/highlight-collection-related-info.tsx
  • vite.config.ts
✅ Files skipped from review due to trivial changes (1)
  • src/utils/getTutorialDataHandlers.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/styles.css
  • src/components/TodoBoards.tsx
  • vite.config.ts
  • src/routes/__root.tsx
  • src/components/ui/scroll-shadow.tsx
  • src/components/tutorial/TutorialTableOfContents.tsx
  • src/components/ToggleFloatingWindowButton.tsx
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always ensure no formatting/linting issues exist in code - use pnpm check --fix to automatically fix issues

Files:

  • src/hooks/use-scroll-shadow.ts
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/components/ui/sidebar.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functions over arrow functions for React components

Files:

  • src/hooks/use-scroll-shadow.ts
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/components/ui/sidebar.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer type over interface for type definitions

Files:

  • src/hooks/use-scroll-shadow.ts
  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/components/ui/sidebar.tsx
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

**/package.json: Always use pnpm install instead of npm install for installing dependencies
Always use pnpm add <package> instead of npm install <package> for adding packages
Always use pnpm add -D <package> instead of npm install --save-dev <package> for adding dev dependencies
Always use pnpm remove <package> instead of npm uninstall <package> for removing packages
Always use pnpm run <script> instead of npm run <script> for running scripts
Always use pnpm dlx <command> instead of npx <command>
Always use pnpm create <template> instead of npm create <template>

Files:

  • package.json
package.json

📄 CodeRabbit inference engine (AGENTS.md)

package.json: Use pnpm dev for starting the development server
Use pnpm build for production build
Use pnpm run test for running tests
Use pnpm lint for linting
Use pnpm typecheck for type checking
Use pnpm format for code formatting
Use pnpm db.generate to generate database migrations
Use pnpm db.local.migrate to apply local migrations
Use pnpm db.prod.migrate to apply production migrations

Files:

  • package.json
🧠 Learnings (3)
📚 Learning: 2025-12-29T13:20:08.377Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-29T13:20:08.377Z
Learning: Applies to src/route/__root.tsx : The root route is located at `src/route/__root.tsx` in this TanStack Start project

Applied to files:

  • src/data/tutorial/collections-intro.mdx
  • src/components/tutorial/TutorialWindow.tsx
  • src/utils/highlight-collection-related-info.tsx
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/components/ui/sidebar.tsx
📚 Learning: 2025-12-28T23:34:13.416Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 32
File: src/components/HomeIntro.tsx:16-25
Timestamp: 2025-12-28T23:34:13.416Z
Learning: In Motion (motion/react), when configuring variant transitions, use delayChildren: stagger(x) to create per-child delays (e.g., delayChildren: stagger(0.2)). This is different from the older API that used a separate staggerChildren property. Apply this guidance to TSX files that declare motion variants (e.g., in src/components/**/*.tsx) and verify that stagger is imported from framer-motion. Ensure transitions reflect the intended stagger timing and that no conflicting delay values override the staggered effect.

Applied to files:

  • src/components/tutorial/TutorialWindow.tsx
  • src/components/tutorial/index.tsx
  • src/utils/highlight-collection-related-info.tsx
  • src/components/ui/sidebar.tsx
🧬 Code graph analysis (3)
src/components/tutorial/TutorialWindow.tsx (8)
src/utils/getTutorialDataHandlers.ts (1)
  • TutorialData (6-14)
src/hooks/use-scroll-shadow.ts (1)
  • useScrollShadow (17-84)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/tutorial/TutorialTableOfContents.tsx (1)
  • TutorialTableOfContents (30-75)
src/components/ui/scroll-area.tsx (1)
  • ScrollArea (62-62)
src/components/ui/scroll-shadow.tsx (1)
  • ScrollShadow (3-24)
src/data/tutorial.ts (1)
  • steps (66-66)
src/components/ui/tabs.tsx (1)
  • TabsContent (64-64)
src/components/tutorial/index.tsx (1)
src/components/ui/button.tsx (1)
  • Button (63-63)
src/utils/highlight-collection-related-info.tsx (2)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/HomeIntro.tsx (1)
  • HomeIntro (63-182)
🔇 Additional comments (14)
src/utils/highlight-collection-related-info.tsx (2)

1-2: LGTM: Clean import consolidation.

The imports are properly organized with the React Router hooks and React primitives. Using the type keyword for ReactNode follows the project's TypeScript guidelines.


16-33: Well-implemented auto-dismiss behavior.

The navigation logic correctly:

  • Computes isHighlighted using startsWith for prefix matching
  • Auto-dismisses the highlight after 1 second using replace: true to avoid polluting browser history
  • Properly cleans up the timeout on unmount or when dependencies change

This aligns well with the PR objective to improve the highlights feature's UX.

package.json (1)

42-42: Prism to Shiki migration is complete and properly implemented.

The package version @shikijs/rehype@^3.20.0 is valid and present in dependencies. Old Prism-related packages (prismjs, rehype-prism-plus) have been fully removed from the codebase. The Shiki integration is properly configured in vite.config.ts with Material themes and language attribute transformers.

src/components/ui/sidebar.tsx (1)

683-683: LGTM!

The addition of transition-colors enhances the UX by smoothing color transitions on hover and active states, consistent with other sidebar components.

src/data/tutorial/collections-intro.mdx (2)

18-18: LGTM!

Updating the code fence language from ts to tsx correctly reflects that these snippets contain JSX/React code.

Also applies to: 31-31


63-63: LGTM!

Grammar correction improves readability.

src/hooks/use-scroll-shadow.ts (2)

17-22: LGTM!

The enhanced API with externalRef and deps parameters provides flexible control while maintaining backward compatibility with sensible defaults.


26-31: Well-documented lint suppressions.

The biome-ignore and eslint-disable comments clearly explain why scrollRef.current is intentionally excluded from dependencies. The deps parameter provides a clean workaround for consumers who need to trigger recalculation.

Also applies to: 46-46, 80-81

src/components/tutorial/TutorialWindow.tsx (6)

25-41: LGTM!

The new FloatingWindowHeader component is well-structured and uses the canonical Tailwind v4 bg-linear-to-r class. Based on learnings, this aligns with the project's Tailwind LSP configuration.


197-205: LGTM!

Using useLayoutEffect for scroll restoration prevents visual flicker by applying the scroll position synchronously before the browser paints. The dependency on activeStep ensures restoration runs whenever the step changes.


59-61: Good use of the enhanced useScrollShadow hook.

Passing activeStep in the deps array ensures scroll shadows recalculate when the tutorial step changes, which is appropriate for content that changes per step.


357-361: Architecture improvement: Dedicated navigation component.

The refactor from inline TabsList/TabsTrigger to a dedicated TutorialTableOfContents component improves modularity and separation of concerns. The ScrollShadow integration enhances the visual feedback for scrollable content.

Also applies to: 368-412


444-460: LGTM!

The toggleWindow callback properly:

  • Updates local state
  • Invalidates the route to sync loader data
  • Persists changes to localStorage
  • Uses correct dependency array

382-406: The current pattern is appropriate for the 5 tutorial steps.

Radix UI's Tabs keeps all TabsContent in the DOM but visually hides non-active tabs—they don't mount/unmount on tab changes. With only 5 steps (4 tutorial articles + 1 deep dive), rendering all of them is not a performance concern. There's no evidence of a previous lazy-loading implementation being removed. If the tutorial grows significantly (dozens of steps), consider implementing conditional rendering or lazy loading at that point, but for the current scope this pattern is fine.

Comment thread src/components/tutorial/index.tsx
Comment thread src/utils/highlight-collection-related-info.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/utils/highlight-collection-related-info.tsx (1)

37-37: Accessibility concern already flagged.

The aria-hidden="true" attribute on the wrapper div has already been identified in previous reviews as potentially problematic for screen reader accessibility. Please refer to the earlier review comment for detailed guidance.

src/components/tutorial/index.tsx (1)

79-79: Navigation consistency concern already flagged.

The use of replace={true} in this Link and its inconsistency with other navigation patterns has already been identified in previous reviews. Please refer to the earlier review comment for guidance.

📜 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 8e4931b and 5302318.

📒 Files selected for processing (7)
  • src/components/tutorial/index.tsx
  • src/data/tutorial/collections-intro.mdx
  • src/data/tutorial/how-do-collections-work.mdx
  • src/data/tutorial/optimistic-actions.mdx
  • src/data/tutorial/optimistic-updates.mdx
  • src/data/tutorial/what-is-next.mdx
  • src/utils/highlight-collection-related-info.tsx
💤 Files with no reviewable changes (4)
  • src/data/tutorial/how-do-collections-work.mdx
  • src/data/tutorial/what-is-next.mdx
  • src/data/tutorial/optimistic-actions.mdx
  • src/data/tutorial/optimistic-updates.mdx
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always ensure no formatting/linting issues exist in code - use pnpm check --fix to automatically fix issues

Files:

  • src/utils/highlight-collection-related-info.tsx
  • src/components/tutorial/index.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functions over arrow functions for React components

Files:

  • src/utils/highlight-collection-related-info.tsx
  • src/components/tutorial/index.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer type over interface for type definitions

Files:

  • src/utils/highlight-collection-related-info.tsx
  • src/components/tutorial/index.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-29T13:20:08.377Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-29T13:20:08.377Z
Learning: Applies to src/route/__root.tsx : The root route is located at `src/route/__root.tsx` in this TanStack Start project

Applied to files:

  • src/data/tutorial/collections-intro.mdx
  • src/utils/highlight-collection-related-info.tsx
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
  • src/components/tutorial/index.tsx
📚 Learning: 2025-12-28T23:34:13.416Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 32
File: src/components/HomeIntro.tsx:16-25
Timestamp: 2025-12-28T23:34:13.416Z
Learning: In Motion (motion/react), when configuring variant transitions, use delayChildren: stagger(x) to create per-child delays (e.g., delayChildren: stagger(0.2)). This is different from the older API that used a separate staggerChildren property. Apply this guidance to TSX files that declare motion variants (e.g., in src/components/**/*.tsx) and verify that stagger is imported from framer-motion. Ensure transitions reflect the intended stagger timing and that no conflicting delay values override the staggered effect.

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
  • src/components/tutorial/index.tsx
🧬 Code graph analysis (1)
src/utils/highlight-collection-related-info.tsx (2)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/HomeIntro.tsx (1)
  • HomeIntro (63-182)
🪛 GitHub Actions: CI/CD
src/components/tutorial/index.tsx

[error] 2-2: TS6133: 'XCircleIcon' is declared but its value is never read. (tsc --noEmit)

🪛 GitHub Check: CI
src/components/tutorial/index.tsx

[failure] 2-2:
'XCircleIcon' is declared but its value is never read.

🔇 Additional comments (3)
src/utils/highlight-collection-related-info.tsx (1)

21-33: Auto-clear highlight logic looks good.

The implementation correctly:

  • Uses a 1-second timeout before clearing the highlight
  • Navigates with replace: true to avoid polluting browser history
  • Properly cleans up the timeout on unmount or when isHighlighted changes
src/components/tutorial/index.tsx (1)

85-88: Button integration looks good.

The replacement of the previous UI with a Button component wrapping SearchIcon and children provides a clearer, more accessible interaction pattern for highlighting.

src/data/tutorial/collections-intro.mdx (1)

2-2: LGTM! Clean-up changes align with PR objectives.

The changes appropriately:

  • Remove the now-unused ClearHighlightsButton import, consistent with its removal from the tutorial exports
  • Update code fence language specifiers from ts to tsx to accurately reflect React/JSX content
  • Improve grammar with "are updated" instead of "updated"

These are all appropriate polish and maintenance updates.

Also applies to: 18-18, 31-31, 63-63

Comment thread src/components/tutorial/index.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (1)
src/utils/highlight-collection-related-info.tsx (1)

42-42: Remove commented code.

Line 42 contains commented-out CSS classes that should be removed for cleaner code maintenance.

🔎 Proposed cleanup
          : "bg-red-500/0 outline-red-500/0 dark:outline-destructive/0 dark:bg-destructive/0 duration-1000",
-        // "outline-destructive bg-destructive/10 outline rounded-sm outline-offset-4",
      )}
📜 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 5302318 and 64e4212.

📒 Files selected for processing (2)
  • src/components/tutorial/index.tsx
  • src/utils/highlight-collection-related-info.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/tutorial/index.tsx
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always ensure no formatting/linting issues exist in code - use pnpm check --fix to automatically fix issues

Files:

  • src/utils/highlight-collection-related-info.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer functions over arrow functions for React components

Files:

  • src/utils/highlight-collection-related-info.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer type over interface for type definitions

Files:

  • src/utils/highlight-collection-related-info.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-29T13:20:08.377Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-29T13:20:08.377Z
Learning: Applies to src/route/__root.tsx : The root route is located at `src/route/__root.tsx` in this TanStack Start project

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
📚 Learning: 2025-12-28T23:34:13.416Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 32
File: src/components/HomeIntro.tsx:16-25
Timestamp: 2025-12-28T23:34:13.416Z
Learning: In Motion (motion/react), when configuring variant transitions, use delayChildren: stagger(x) to create per-child delays (e.g., delayChildren: stagger(0.2)). This is different from the older API that used a separate staggerChildren property. Apply this guidance to TSX files that declare motion variants (e.g., in src/components/**/*.tsx) and verify that stagger is imported from framer-motion. Ensure transitions reflect the intended stagger timing and that no conflicting delay values override the staggered effect.

Applied to files:

  • src/utils/highlight-collection-related-info.tsx
🧬 Code graph analysis (1)
src/utils/highlight-collection-related-info.tsx (1)
src/lib/utils.ts (1)
  • cn (4-6)
⏰ 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). (1)
  • GitHub Check: Deploy Preview
🔇 Additional comments (4)
src/utils/highlight-collection-related-info.tsx (4)

1-2: LGTM: Clean import structure.

The imports are well-organized and correctly use the type keyword for ReactNode, following TypeScript best practices.


21-33: LGTM: Well-implemented auto-clear effect.

The effect correctly:

  • Cleans up the timeout on unmount or when dependencies change
  • Uses replace: true to avoid polluting browser history
  • Properly destructures to remove only the highlight param while preserving other search params
  • Has the correct dependency array

The 1-second timeout is reasonable for tutorial highlighting.


36-46: Previous accessibility issue resolved.

The aria-hidden="true" attribute that was flagged in the previous review has been successfully removed, addressing the accessibility concern. The wrapper now correctly allows assistive technologies to access the highlighted content.


18-19: This prefix-based matching is documented behavior.

The naming convention in src/components/tutorial/index.tsx (lines 8–9) explicitly documents this design: "Naming convention: project highlights any ids starting with project (e.g., project, project_sidebar)". The highlightParamSchema restricts the highlight param to a controlled enum, preventing arbitrary overlapping prefixes. No changes needed.

Likely an incorrect or invalid review comment.

@fulopkovacs
fulopkovacs merged commit f9aac14 into main Jan 1, 2026
3 of 4 checks passed
@fulopkovacs
fulopkovacs deleted the tutorial branch January 1, 2026 17:59
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