Skip to content

Commit

Permalink
Proper margin orientation for scroll into view (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgreif committed Dec 3, 2021
1 parent 4062144 commit 9194ba4
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-months-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/behaviors': patch
---

Correct margin orientation for `scrollIntoView`
2 changes: 1 addition & 1 deletion docs/scroll-into-view.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ The `scrollIntoView` function takes the following arguments.
| Name | Type | Default | Description |
| :---------- | :-------------------------- | :----------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| direction | `'horizontal' │ 'vertical'` | `'vertical'` | The direction to scroll the viewing area |
| startMargin | `number` of pixels | 8 | A margin to leave between the start of the viewing area and the start of the child element (if room allows) |
| startMargin | `number` of pixels | 0 | A margin to leave between the start of the viewing area and the start of the child element (if room allows) |
| endMargin | `number` of pixels | 0 | A margin to leave between the end of the viewing area and the end of the child element (if room allows) |
| behavior | `ScrollBehavior` | `'smooth'` | Behavior for the browser to use when scrolling. `smooth` will transition with a smooth animation, while `auto` will immediately jump to the new scroll location |
2 changes: 1 addition & 1 deletion src/__tests__/scroll-into-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('scrollIntoView', () => {
const viewAreaHeight = 100
const childStart = viewAreaHeight + 10
const expectedScrollPosition = scrollPositionFormula(
{viewingAreaEdgePosition: viewAreaHeight, childEdgePosition: childStart + childHeight, margin: 8},
{viewingAreaEdgePosition: viewAreaHeight, childEdgePosition: childStart + childHeight, margin: 0},
false
)

Expand Down
10 changes: 5 additions & 5 deletions src/scroll-into-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ export interface ScrollIntoViewOptions {
export function scrollIntoView(
child: HTMLElement,
viewingArea: HTMLElement,
{direction = 'vertical', startMargin = 8, endMargin = 0, behavior = 'smooth'}: ScrollIntoViewOptions = {}
{direction = 'vertical', startMargin = 0, endMargin = 0, behavior = 'smooth'}: ScrollIntoViewOptions = {}
) {
const startSide = direction === 'vertical' ? 'top' : 'left'
const endSide = direction === 'vertical' ? 'bottom' : 'right'
const scrollSide = direction === 'vertical' ? 'scrollTop' : 'scrollLeft'
const {[startSide]: childStart, [endSide]: childEnd} = child.getBoundingClientRect()
const {[startSide]: viewingAreaStart, [endSide]: viewingAreaEnd} = viewingArea.getBoundingClientRect()

const isChildStartAboveViewingArea = childStart < viewingAreaStart + endMargin
const isChildBottomBelowViewingArea = childEnd > viewingAreaEnd - startMargin
const isChildStartAboveViewingArea = childStart < viewingAreaStart + startMargin
const isChildBottomBelowViewingArea = childEnd > viewingAreaEnd - endMargin

if (isChildStartAboveViewingArea) {
const scrollHeightToChildStart = childStart - viewingAreaStart + viewingArea[scrollSide]
viewingArea.scrollTo({behavior, [startSide]: scrollHeightToChildStart - endMargin})
viewingArea.scrollTo({behavior, [startSide]: scrollHeightToChildStart - startMargin})
} else if (isChildBottomBelowViewingArea) {
const scrollHeightToChildBottom = childEnd - viewingAreaEnd + viewingArea[scrollSide]
viewingArea.scrollTo({behavior, [startSide]: scrollHeightToChildBottom + startMargin})
viewingArea.scrollTo({behavior, [startSide]: scrollHeightToChildBottom + endMargin})
}

// either completely in view or outside viewing area on both ends, don't scroll
Expand Down

0 comments on commit 9194ba4

Please sign in to comment.