app-lesson-sidebar lists 100+ lessons and currently drives the page to a very tall scroll height. Users can accidentally scroll the whole page with the mouse wheel and lose context (question, editor, answer area) instead of staying focused in the lesson workspace.
Goal
Keep the main lesson view within a predictable viewport (e.g. 100vh / full-height app shell) so the primary content does not feel like it “drifts” under global page scroll. Scrolling the lesson list should be local to the sidebar (or virtualized), not the entire document.
Options to evaluate (pick at implementation time)
A. Constrained sidebar + internal scroll
Sidebar column has max-height: 100vh (or fills flex grid row) with overflow-y: auto (or overflow: hidden on body with flex children).
Pros: Simple, no new deps, works everywhere.
Cons: Still renders all DOM nodes for 100+ items (usually fine at this scale).
B. Virtual scrolling (CDK or similar)
Render only visible lesson rows; smooth scroll for long lists.
Pros: Scales if lists grow further; less DOM.
Cons: More integration work; keyboard/focus/ARIA need care; another dependency if not already on CDK.
C. Hybrid
Internal scroll for the list region only; optional virtual scroll later if profiling shows need.
Acceptance criteria (high level)
Page-level scroll is not required only because of the lesson list length; list scroll is contained in the sidebar (or equivalent panel).
Question / answer / playground areas remain usable without the default wheel behavior pulling the user through a miles-long page.
Final approach documented in PR (A vs B vs C).
Component
app-lesson-sidebar (layout / global shell may need small adjustments so height constraints propagate).
## Problem
`app-lesson-sidebar` lists **100+ lessons** and currently drives the **page** to a very tall scroll height. Users can accidentally **scroll the whole page** with the mouse wheel and lose context (question, editor, answer area) instead of staying focused in the lesson workspace.
## Goal
Keep the **main lesson view** within a predictable viewport (e.g. **`100vh`** / full-height app shell) so the primary content does not feel like it “drifts” under global page scroll. Scrolling the lesson list should be **local to the sidebar** (or virtualized), not the entire document.
## Options to evaluate (pick at implementation time)
### A. Constrained sidebar + internal scroll
- Sidebar column has `max-height: 100vh` (or fills flex grid row) with **`overflow-y: auto`** (or `overflow: hidden` on body with flex children).
- **Pros:** Simple, no new deps, works everywhere.
- **Cons:** Still renders all DOM nodes for 100+ items (usually fine at this scale).
### B. Virtual scrolling (CDK or similar)
- Render only visible lesson rows; smooth scroll for long lists.
- **Pros:** Scales if lists grow further; less DOM.
- **Cons:** More integration work; keyboard/focus/ARIA need care; another dependency if not already on CDK.
### C. Hybrid
- Internal scroll for the list region only; optional virtual scroll later if profiling shows need.
## Acceptance criteria (high level)
- [ ] Page-level scroll is not required **only** because of the lesson list length; list scroll is contained in the sidebar (or equivalent panel).
- [ ] Question / answer / playground areas remain usable without the default wheel behavior pulling the user through a miles-long page.
- [ ] Final approach documented in PR (A vs B vs C).
## Component
`app-lesson-sidebar` (layout / global shell may need small adjustments so height constraints propagate).
Closing — already implemented (Approach A, exactly as this ticket proposed) and shipped with the feature-based architecture revamp (spikersoft-angular commit 4a362ba). The shared app-lesson-sidebar (libraries/shared/lesson-panes/.../lesson-sidebar.scss) carries the implementation with an explicit "Issue #22 — Approach A" comment:
max-height: calc(100vh - var(--app-toolbar-height) - 2rem) + overflow-y: auto — the catalog scrolls inside the sidebar, never dragging the page height
:host { height: 100%; min-height: 0 } so it fills the sticky workspace grid cell but stays safe in unbounded contexts
Option B (CDK virtual scroll) deliberately deferred in the comment — DOM cost is negligible at 100-ish items and it avoids focus/ARIA complexity
Verified the shared component is what the playground shells render (language-runner.html, clang-runtime shell). Nothing further to do; if lists grow into the thousands, reopen for Option B.
Closing — **already implemented** (Approach A, exactly as this ticket proposed) and shipped with the feature-based architecture revamp (`spikersoft-angular` commit `4a362ba`). The shared `app-lesson-sidebar` (`libraries/shared/lesson-panes/.../lesson-sidebar.scss`) carries the implementation with an explicit "Issue #22 — Approach A" comment:
- `max-height: calc(100vh - var(--app-toolbar-height) - 2rem)` + `overflow-y: auto` — the catalog scrolls **inside** the sidebar, never dragging the page height
- `:host { height: 100%; min-height: 0 }` so it fills the sticky workspace grid cell but stays safe in unbounded contexts
- Option B (CDK virtual scroll) deliberately deferred in the comment — DOM cost is negligible at 100-ish items and it avoids focus/ARIA complexity
Verified the shared component is what the playground shells render (`language-runner.html`, `clang-runtime` shell). Nothing further to do; if lists grow into the thousands, reopen for Option B.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
app-lesson-sidebarlists 100+ lessons and currently drives the page to a very tall scroll height. Users can accidentally scroll the whole page with the mouse wheel and lose context (question, editor, answer area) instead of staying focused in the lesson workspace.Goal
Keep the main lesson view within a predictable viewport (e.g.
100vh/ full-height app shell) so the primary content does not feel like it “drifts” under global page scroll. Scrolling the lesson list should be local to the sidebar (or virtualized), not the entire document.Options to evaluate (pick at implementation time)
A. Constrained sidebar + internal scroll
max-height: 100vh(or fills flex grid row) withoverflow-y: auto(oroverflow: hiddenon body with flex children).B. Virtual scrolling (CDK or similar)
C. Hybrid
Acceptance criteria (high level)
Component
app-lesson-sidebar(layout / global shell may need small adjustments so height constraints propagate).Closing — already implemented (Approach A, exactly as this ticket proposed) and shipped with the feature-based architecture revamp (
spikersoft-angularcommit4a362ba). The sharedapp-lesson-sidebar(libraries/shared/lesson-panes/.../lesson-sidebar.scss) carries the implementation with an explicit "Issue #22 — Approach A" comment:max-height: calc(100vh - var(--app-toolbar-height) - 2rem)+overflow-y: auto— the catalog scrolls inside the sidebar, never dragging the page height:host { height: 100%; min-height: 0 }so it fills the sticky workspace grid cell but stays safe in unbounded contextsVerified the shared component is what the playground shells render (
language-runner.html,clang-runtimeshell). Nothing further to do; if lists grow into the thousands, reopen for Option B.