Add scroll affordance to horizontal tab lists#225
Open
patcapulong wants to merge 1 commit intomainfrom
Open
Conversation
Horizontal tab lists (e.g. account type tabs on API reference pages) overflow but give no visual hint with scrollbars hidden. This adds gradient fade masks on the edges that appear/disappear based on scroll position, drag-to-scroll support for mouse users, and a grab cursor to signal the interaction. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
Greptile SummaryAdds visual and interactive scroll affordance to horizontal tab lists that overflow their container. Implements drag-to-scroll functionality with mouse and gradient fade masks that indicate scrollable content on the left/right edges.
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| mintlify/scroll-fade.js | Adds drag-to-scroll and gradient fade indicators for overflowing horizontal tab lists with debounced DOM observation |
| mintlify/style.css | Adds CSS mask-image gradients and cursor styles for scroll affordance on tab lists |
| mintlify/docs.json | Includes scroll-fade.js script in the document head |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Page Load] --> B{DOM Ready?}
B -->|Yes| C[initAll]
B -->|No| D[Wait for DOMContentLoaded]
D --> C
C --> E[Query all tabs-list elements]
E --> F[For each element]
F --> G{Already initialized?}
G -->|Yes| H[Skip]
G -->|No| I[Set scrollFadeInit flag]
I --> J[updateFadeClasses]
J --> K[Attach scroll listener]
K --> L[Attach ResizeObserver]
L --> M[initDragScroll]
M --> N[Attach mousedown listener]
N --> O[Attach mousemove listener]
O --> P[Attach mouseup/mouseleave listeners]
Q[MutationObserver watches DOM] --> R{DOM changes?}
R -->|Yes| S[Debounce 100ms]
S --> C
T[User scrolls] --> J
U[Window resizes] --> J
V[User mousedown] --> W{Mouse drag > 5px?}
W -->|Yes| X[Set hasDragged flag]
X --> Y[Add is-dragging class]
Y --> Z[Scroll container]
W -->|No| AA[Normal click]
Z --> AB[mouseup event]
AB --> AC[Remove is-dragging]
AC --> AD[Register click suppressor]
AD --> AE[Prevent next click]
J --> AF{Overflows?}
AF -->|No| AG[Remove fade classes]
AF -->|Yes| AH{Scroll position?}
AH -->|At start| AI[scroll-fade-right]
AH -->|At end| AJ[scroll-fade-left]
AH -->|Middle| AK[scroll-fade-both]
Last reviewed commit: 73dc4d4
Comment on lines
+63
to
+70
| el.addEventListener( | ||
| "click", | ||
| function (e) { | ||
| e.stopPropagation(); | ||
| e.preventDefault(); | ||
| }, | ||
| { once: true, capture: true } | ||
| ); |
Contributor
There was a problem hiding this comment.
click listener added synchronously in mouseup may miss the click event if the click fires before the listener is attached (browsers typically fire click after mouseup on the same tick). Consider adding the listener during mousedown instead and using a flag to determine whether to suppress it.
Suggested change
| el.addEventListener( | |
| "click", | |
| function (e) { | |
| e.stopPropagation(); | |
| e.preventDefault(); | |
| }, | |
| { once: true, capture: true } | |
| ); | |
| el.addEventListener("mousedown", function (e) { | |
| if (e.button !== 0) return; | |
| isDown = true; | |
| hasDragged = false; | |
| startX = e.pageX; | |
| startScrollLeft = el.scrollLeft; | |
| // Pre-register click suppression handler | |
| var clickHandler = function (clickEvent) { | |
| if (hasDragged) { | |
| clickEvent.stopPropagation(); | |
| clickEvent.preventDefault(); | |
| } | |
| }; | |
| el.addEventListener("click", clickHandler, { once: true, capture: true }); | |
| }); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/scroll-fade.js
Line: 63-70
Comment:
click listener added synchronously in `mouseup` may miss the click event if the click fires before the listener is attached (browsers typically fire click after mouseup on the same tick). Consider adding the listener during `mousedown` instead and using a flag to determine whether to suppress it.
```suggestion
el.addEventListener("mousedown", function (e) {
if (e.button !== 0) return;
isDown = true;
hasDragged = false;
startX = e.pageX;
startScrollLeft = el.scrollLeft;
// Pre-register click suppression handler
var clickHandler = function (clickEvent) {
if (hasDragged) {
clickEvent.stopPropagation();
clickEvent.preventDefault();
}
};
el.addEventListener("click", clickHandler, { once: true, capture: true });
});
```
How can I resolve this? If you propose a fix, please make it concise.| @@ -0,0 +1,116 @@ | |||
| (function () { | |||
There was a problem hiding this comment.
whoa this seems super hacky, they don't have any way of natively scrolling already?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
How it works
A vanilla JS script (
scroll-fade.js) observes the DOM for[data-component-part="tabs-list"]elements and attaches scroll/resize listeners. Based on scroll position, it toggles CSS classes that controlmask-imagegradients on the left/right edges. A 5px distance threshold distinguishes click-to-select-tab from drag-to-scroll gestures.Test plan
Made with Cursor