DEV Community

Stephen Chiang
Stephen Chiang

Posted on

How I'm starting my own Angular Component Library (part 2 - smooth-scroll-component)

It's been an insane few months so the build-up of this library has been last priority, here's a quick, very straightforward component that takes an input of any class name as a string and on click, scrolls the browser window smoothly to that class. It is possible to modify to go with an elementId, but i decided to go with classes for this use case. This allows you to insert these little components in a long list to go back to the top (header), bottom (footer), or anywhere else really.

TL;DR

Go straight to the AngularComponentLibrary Repo

What I want this component to be capable of handling

I wanted this component to be as simple and straightfoward as possible with consistent and predictable behavior. Just take a string input of an element class name and smoothly scroll the browser window to that location.

Steps

After generating the scroll-to.component with the inline template flag, I'll first write the actual html markup and specify the inputs:

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-scroll-to',
  template: `
  <div class="scrollLinkContainer" (click)="scrollTo()">
    <p class="button">{{ linkText }}<span class="icon"></span></p>
  </div>
  `,
  styleUrls: ['./scroll-to.component.scss']
})
export class ScrollToComponent implements OnInit {
  @Input()
  linkText: string;
  @Input()
  scrollToClass: string;
  @Output()
  onScroll: EventEmitter<string>;

constructor() {
    this.onScroll = new EventEmitter();
}

ngOnInit() {}
Enter fullscreen mode Exit fullscreen mode

Here we have an input on the text the parent component wants to give this component, the actual class name and then an event emitter to tell the parent component that the component was clicked. The emitter really isn't necessary, but may be useful in some cases down the line.

The rest of the scroll-to.component.ts and the actual meat, which is the scrollTo click event. Let's dissect this.

We select all elements matching the class name input as a node list. In this particular case, I want to scroll to the first instance of the match. One could avoid doing this by going with element Ids. We then make use of the scrollIntoView api to scroll the window. Note that the options for the api aren't fully supported, but the basic support is pretty good

Lastly there's the optional event emitter, which will notify the parent component that it's being scrolled if needed.

  scrollTo(): void {
    const elementList = document.querySelectorAll('.' + this.scrollToClass);
    const element = elementList[0] as HTMLElement;
    element.scrollIntoView({ behavior: 'smooth' });
    this.onScroll.emit('scrolled to: ' + this.scrollToClass);
  }
}
Enter fullscreen mode Exit fullscreen mode

Here's how it would look being used in the parent component as a way to school back to the navbar at the top, of course you would need a different class to go to top if you have a sticky navbar that follows the screen scroll.:

<navbar class="nav"></navbar>
<main></main>
<footer>
    <app-scroll-to [linkText]="'Back to top'" [scrollToClass]="'nav'" (onScroll)="someFunction()"></app-scroll-to>
</footer
Enter fullscreen mode Exit fullscreen mode

That's it, I'm hoping to make something more substantial in the next one. Cheers!

Oldest comments (0)