diff --git a/README.md b/README.md
index 86845a3..9a26c23 100644
--- a/README.md
+++ b/README.md
@@ -104,6 +104,15 @@ In this scenario the nav element will have the class `sn-affix` added when the u
}
```
+A `[yOffset]` can also be applied. Here `sn-affix` will be added when the top of the viewport is within 200 pixels of the top of the nav.
+
+```html
+
+
+```
+
### Minimise mode
In this scenario the nav element will have the class `sn-minimise` added when the user scrolls 100px (the original height of the element) down the page.
diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts
index 6f04b22..eed2c8f 100644
--- a/e2e/app.e2e-spec.ts
+++ b/e2e/app.e2e-spec.ts
@@ -1,36 +1,51 @@
import { AppPage } from './app.po';
import { browser, element, by } from 'protractor';
-describe('ScrollCollapse Lib E2E Tests', function () {
+describe('ScrollCollapse Lib E2E Tests', function() {
let page: AppPage;
- beforeEach(() => page = new AppPage());
+ beforeEach(() => (page = new AppPage()));
beforeEach(() => page.navigateTo());
beforeEach(() => browser.executeScript('window.scrollTo(0,0)'));
afterEach(() => {
- browser.manage().logs().get('browser').then((browserLog: any[]) => {
- expect(browserLog).toEqual([]);
- });
+ browser
+ .manage()
+ .logs()
+ .get('browser')
+ .then((browserLog: any[]) => {
+ expect(browserLog).toEqual([]);
+ });
});
describe('scroll direction', () => {
it('should add scrolling direction class', () => {
page.scrollTo();
- expect(page.getNavElement().getAttribute('class')).not.toContain('sn-scrolling-down');
- expect(page.getNavElement().getAttribute('class')).not.toContain('sn-scrolling-up');
+ expect(page.getNavElement().getAttribute('class')).not.toContain(
+ 'sn-scrolling-down'
+ );
+ expect(page.getNavElement().getAttribute('class')).not.toContain(
+ 'sn-scrolling-up'
+ );
page.scrollTo(0, 10);
page.scrollTo(0, 200);
- expect(page.getNavElement().getAttribute('class')).toContain('sn-scrolling-down');
- expect(page.getNavElement().getAttribute('class')).not.toContain('sn-scrolling-up');
-
+ expect(page.getNavElement().getAttribute('class')).toContain(
+ 'sn-scrolling-down'
+ );
+ expect(page.getNavElement().getAttribute('class')).not.toContain(
+ 'sn-scrolling-up'
+ );
page.scrollTo(0, 100);
- expect(page.getNavElement().getAttribute('class')).not.toContain('sn-scrolling-down');
- expect(page.getNavElement().getAttribute('class')).toContain('sn-scrolling-up');
+ expect(page.getNavElement().getAttribute('class')).not.toContain(
+ 'sn-scrolling-down'
+ );
+ expect(page.getNavElement().getAttribute('class')).toContain(
+ 'sn-scrolling-up'
+ );
});
});
@@ -38,10 +53,14 @@ describe('ScrollCollapse Lib E2E Tests', function () {
it('should add "sn-minimise" class', () => {
page.scrollTo();
page.scrollTo(0, 10);
- expect(page.getNavElement().getAttribute('class')).not.toContain('sn-minimise');
+ expect(page.getNavElement().getAttribute('class')).not.toContain(
+ 'sn-minimise'
+ );
page.scrollTo(0, 110);
- expect(page.getNavElement().getAttribute('class')).toContain('sn-minimise');
+ expect(page.getNavElement().getAttribute('class')).toContain(
+ 'sn-minimise'
+ );
});
});
@@ -49,11 +68,12 @@ describe('ScrollCollapse Lib E2E Tests', function () {
it('should add "sn-affix" class', () => {
page.scrollTo();
page.scrollTo(0, 10);
- expect(page.getBarElement().getAttribute('class')).not.toContain('sn-affix');
+ expect(page.getBarElement().getAttribute('class')).not.toContain(
+ 'sn-affix'
+ );
page.scrollTo(0, 768 * 3);
expect(page.getBarElement().getAttribute('class')).toContain('sn-affix');
});
});
-
});
diff --git a/e2e/app.po.ts b/e2e/app.po.ts
index 58403da..7ac9f1c 100644
--- a/e2e/app.po.ts
+++ b/e2e/app.po.ts
@@ -17,4 +17,8 @@ export class AppPage {
getBarElement() {
return element(by.css('.bar'));
}
+
+ getOffsetBarElement() {
+ return element(by.css('.bar--offset'));
+ }
}
diff --git a/src/app/app.component.html b/src/app/app.component.html
index e9ea83d..fe5c834 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -16,3 +16,12 @@
Scroll down ↓
+
+
+
+
+ Classes applied when original Y position of element approaches yOffset. [yOffset]="200"
+
+
+
+
diff --git a/src/app/app.component.scss b/src/app/app.component.scss
index 1fb1c60..f42dc67 100644
--- a/src/app/app.component.scss
+++ b/src/app/app.component.scss
@@ -53,6 +53,15 @@
z-index: 9999;
}
+.bar.bar--offset.sn-affix {
+ top: 100px;
+}
+
+.bar.bar--offset.sn-minimise {
+ background-color: #586e5d;
+ height: 50px;
+}
+
.spacer {
height: 150vh;
}
diff --git a/src/app/scroll-collapse/scroll-collapse.directive.spec.ts b/src/app/scroll-collapse/scroll-collapse.directive.spec.ts
index c3dc94c..843d64a 100644
--- a/src/app/scroll-collapse/scroll-collapse.directive.spec.ts
+++ b/src/app/scroll-collapse/scroll-collapse.directive.spec.ts
@@ -199,5 +199,42 @@ describe('ScrollCollapseDirective', () => {
});
expect(directive.affixMode).toBeFalsy();
});
+
+ it('should factor in yOffset property when calculating affix mode', () => {
+ directive.originalHeight = 100;
+ directive.originalTop = 500;
+ directive.yOffset = 200;
+ directive.calculateAffixMode({
+ scrollX: 0,
+ scrollY: 0,
+ width: 1366,
+ height: 768
+ });
+ expect(directive.affixMode).toBeFalsy();
+
+ directive.calculateAffixMode({
+ scrollX: 0,
+ scrollY: 200,
+ width: 1366,
+ height: 768
+ });
+ expect(directive.affixMode).toBeFalsy();
+
+ directive.calculateAffixMode({
+ scrollX: 0,
+ scrollY: 300,
+ width: 1366,
+ height: 768
+ });
+ expect(directive.affixMode).toBeTruthy();
+
+ directive.calculateAffixMode({
+ scrollX: 0,
+ scrollY: 299,
+ width: 1366,
+ height: 768
+ });
+ expect(directive.affixMode).toBeFalsy();
+ });
});
});
diff --git a/src/app/scroll-collapse/scroll-collapse.directive.ts b/src/app/scroll-collapse/scroll-collapse.directive.ts
index 7bd0bc0..45d8f81 100644
--- a/src/app/scroll-collapse/scroll-collapse.directive.ts
+++ b/src/app/scroll-collapse/scroll-collapse.directive.ts
@@ -74,6 +74,17 @@ export class ScrollCollapseDirective implements AfterViewInit, OnDestroy {
* @memberof ScrollCollapseDirective
*/
@Input() public debounce = 0;
+ /**
+ * Number of pixels before the elements originalTop
+ * position is scroll to that the sn-affix class will be applied.
+ * This value will need to take into account elements which become
+ * fixed above this element while scrolling as they reduce
+ * the height of the document and the scrollY number.
+ *
+ * @default 0
+ * @memberof ScrollCollapseDirective
+ */
+ @Input() public yOffset = 0;
/**
* Returns true if last scroll direction is UP
*
@@ -199,7 +210,7 @@ export class ScrollCollapseDirective implements AfterViewInit, OnDestroy {
* @memberof ScrollCollapseDirective
*/
public calculateAffixMode(viewport: Viewport): void {
- this.affixMode = viewport.scrollY >= this.originalTop;
+ this.affixMode = viewport.scrollY >= this.originalTop - this.yOffset;
}
/**
* Return current viewport values