Angular ScrollBar - Setup

Smart UI for Angular supports both standalone components (bootstrapApplication) and NgModule-based apps (bootstrapModule(AppModule)). Steps 1-5 show the standalone path; the section below shows the NgModule path with the same package and styles.

Demo source (Smart UI repo): angular/src/scrollbar/overview

1 NPM Install

Install the smart-webcomponents-angular package:

npm install smart-webcomponents-angular

2 Register styles

Add the default Smart UI stylesheet to angular.json -> projects -> <your-project> -> architect -> build -> options -> styles (merge with existing entries):

"styles": [
		"node_modules/smart-webcomponents-angular/source/styles/smart.default.css"
	]

Add optional theme CSS from the same package after smart.default.css if you use Bootstrap, Fluent, or other bundled themes.

3 Import the Angular module

Import ScrollBarModule from smart-webcomponents-angular/scrollbar: use @Component.imports for standalone, or add it to your AppModule (or feature module) imports array for NgModule apps.

import { ScrollBarModule } from 'smart-webcomponents-angular/scrollbar';

4 Root component (standalone)

Add ScrollBarModule to your root standalone component (src/app/app.ts). Snippet from Smart UI demos (paths normalized to app.html / App where applicable):

 import { Component, ViewChild, OnInit, AfterViewInit } from '@angular/core';
import { ScrollBarComponent, ScrollBar } from 'smart-webcomponents-angular/scrollbar';

import { ScrollBarModule } from 'smart-webcomponents-angular/scrollbar';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ ScrollBarModule ],
  templateUrl: './app.html',
  styleUrl: './app.css'
})

export class App implements AfterViewInit, OnInit {
    @ViewChild('scrollbar', { read: ScrollBarComponent, static: false }) scrollbar!: ScrollBarComponent;
    @ViewChild('scrollbar2', { read: ScrollBarComponent, static: false }) scrollbar2!: ScrollBarComponent;
    @ViewChild('scrollbar3', { read: ScrollBarComponent, static: false }) scrollbar3!: ScrollBarComponent;
    @ViewChild('scrollbar4', { read: ScrollBarComponent, static: false }) scrollbar4!: ScrollBarComponent;
    @ViewChild('scrollbar5', { read: ScrollBarComponent, static: false }) scrollbar5!: ScrollBarComponent;
    @ViewChild('scrollbar6', { read: ScrollBarComponent, static: false }) scrollbar6!: ScrollBarComponent;
    @ViewChild('scrollbar7', { read: ScrollBarComponent, static: false }) scrollbar7!: ScrollBarComponent;
    @ViewChild('scrollbar8', { read: ScrollBarComponent, static: false }) scrollbar8!: ScrollBarComponent;
    @ViewChild('scrollbar9', { read: ScrollBarComponent, static: false }) scrollbar9!: ScrollBarComponent;
    @ViewChild('scrollbar10', { read: ScrollBarComponent, static: false }) scrollbar10!: ScrollBarComponent;
    @ViewChild('scrollbar11', { read: ScrollBarComponent, static: false }) scrollbar11!: ScrollBarComponent;
    @ViewChild('scrollbar12', { read: ScrollBarComponent, static: false }) scrollbar12!: ScrollBarComponent;
    @ViewChild('scrollbar13', { read: ScrollBarComponent, static: false }) scrollbar13!: ScrollBarComponent;


    ngOnInit(): void {
        // onInit code.
    }

    ngAfterViewInit(): void {
        // afterViewInit code.
        this.init();
    }

    init(): void {
        // init code.


        const mediaSlider = document.getElementById('mediaSlider')
        const alarmSlider = document.getElementById('alarmSlider')
        const volumeSlider = document.getElementById('volumeSlider')
        const lowBatterySlider = document.getElementById('lowBatterySlider')
        const powerSaverSlider = document.getElementById('powerSaverSlider');

        function setIcon(event: CustomEvent) {
            let below = "", above = "", off = "";
            const slider = event.target as ScrollBar;
            switch (slider) {
                case mediaSlider:
                    below = '<i class="material-icons">&#xE04D;</i>';
                    above = '<i class="material-icons">&#xE050;</i>';
                    off = '<i class="material-icons">&#xE04F;</i>';
                    break;
                case alarmSlider:
                    below = above = '<i class="material-icons">&#xE855;</i>';
                    off = '<i class="material-icons">&#xE857;</i>';
                    break;
                case volumeSlider:
                    below = '<i class="material-icons">&#xE7F5;</i>';
                    above = '<i class="material-icons">&#xE7F4;</i>';
                    off = '<i class="material-icons">&#xE7F6;</i>';
                    break;
            }

            if (!slider.previousElementSibling) { return }

            if (slider.value === slider.min) {
                slider.previousElementSibling.innerHTML = off;
            }
            else if (slider.value || 0 < (slider.max || 0) / 2) {
                slider.previousElementSibling.innerHTML = below;
            }
            else {
                slider.previousElementSibling.innerHTML = above;
            }
        }
        function setBatteryLevel(event: Event) {
            const slider = <ScrollBar>event.target;
            if (slider === lowBatterySlider && document.getElementById('lowBatteryAlert')) {
                document.getElementById('lowBatteryAlert')!.textContent = slider.value?.toString() || '';
            }
            else {
                if (document.getElementById('powerSaver')) {
                    document.getElementById('powerSaver')!.textContent = slider.value?.toString() || '';
                }
            }
        }
        mediaSlider?.addEventListener('change', setIcon as EventListener);
        alarmSlider?.addEventListener('change', setIcon as EventListener);
        volumeSlider?.addEventListener('change', setIcon as EventListener);
        lowBatterySlider?.addEventListener('change', setBatteryLevel);
        powerSaverSlider?.addEventListener('change', setBatteryLevel);


    }
}

Boot the app with bootstrapApplication from src/main.ts and an ApplicationConfig in src/app/app.config.ts as generated by the CLI.

5 Template (standalone)

Use your markup in src/app/app.html (or inline template). Bind properties and events on smart-scroll-bar as needed:

 <section>
  <div>
    <h2>Scrollbars let users to select values by moving the scrollbar thumb.</h2>
    <div class="module">
      <p>Scrollbars are ideal components for adjusting settings that reflect intensity
        levels, such as volume, brightness, or color saturation.</p>
    </div>
  </div>
</section>
<section id="continuousSliders">
  <h2>Continuous scrollbar</h2>
  <div class="module">
    <p>Use continuous scrollbars for subjective settings that do not require
      a specific value for the user to make meaningful adjustments.</p>
  </div>
  <div class="module continuousSliderLight">
    <table>
      <tr>
        <td>
          <p>Normal</p>
        </td>
      </tr>
      <tr>
        <td>
          <smart-scroll-bar #scrollbar></smart-scroll-bar>
        </td>
      </tr>
      <tr>
        <td>
          <smart-scroll-bar #scrollbar2 [max]="100" [value]="50"></smart-scroll-bar>
        </td>
      </tr>
      <tr>
        <td>
          <smart-scroll-bar #scrollbar3 [max]="100" [value]="100"></smart-scroll-bar>
        </td>
      </tr>
      <tr>
        <td>
          <p>Disabled</p>
        </td>
      </tr>
      <tr>
        <td>
          <smart-scroll-bar #scrollbar4 [disabled]="true" [max]="100"></smart-scroll-bar>
        </td>
      </tr>
      <tr>
        <td>
          <smart-scroll-bar #scrollbar5 [disabled]="true" [max]="100" [value]="50"></smart-scroll-bar>
        </td>
      </tr>
      <tr>
        <td>
          <smart-scroll-bar #scrollbar6 [disabled]="true" [max]="100" [value]="100"></smart-scroll-bar>
        </td>
      </tr>
    </table>
  </div>
</section>
<section id="verticalSliders">
  <h2>Orientation</h2>
  <div class="module">
    <p>smartScrollBar can be horizontal or vertical depending on the orientation
      property.</p>
  </div>
  <div class="module">
    <div>
      <smart-scroll-bar #scrollbar7 [max]="100" [value]="50"></smart-scroll-bar>
      <br/>
      <br/>
      <smart-scroll-bar #scrollbar8 orientation="vertical" [max]="100" [value]="75"></smart-scroll-bar>
    </div>
    <br/>
    <p>Vertical scrollbars</p>
  </div>
</section>
<section id="demoSliders">
  <h2>Demo</h2>
  <div class="module">
    <p>ScrollBars are controls that are used for adjusting values precisely.</p>
  </div>
  <div class="module media-controls">
    <div>
      <h2>Volumes</h2>
      <div>
        <h3>Media volume</h3>
        <div id="mediaControl" class="controls"> <i class="material-icons">&#xE04D;</i>
          <smart-scroll-bar #scrollbar9 id="mediaSlider" [max]="100" [value]="25"></smart-scroll-bar>
        </div>
      </div>
      <div>
        <h3>Alarm volume</h3>
        <div id="alarmControl" class="controls"> <i class="material-icons">&#xE855;</i>
          <smart-scroll-bar #scrollbar10 id="alarmSlider" [max]="100" [value]="50"></smart-scroll-bar>
        </div>
      </div>
      <div>
        <h3>Ring volume</h3>
        <div id="ringControl" class="controls"> <i class="material-icons">&#xE7F4;</i>
          <smart-scroll-bar #scrollbar11 id="volumeSlider" [max]="100" [value]="75"></smart-scroll-bar>
        </div>
      </div>
    </div>
  </div>
  <div class="module power-controls">
    <div>
      <h2>Battery Saver Mode</h2>
      <div>
        <h3>Low battery alert on <b id="lowBatteryAlert">15</b> %</h3>
        <div id="mediaControl" class="controls"> <i class="material-icons">&#xE8B2;</i>
          <smart-scroll-bar #scrollbar12 id="lowBatterySlider" [max]="100" [value]="15" scale-type="integer">
          </smart-scroll-bar>
        </div>
      </div>
      <div>
        <h3>Power saver mode active on <b id="powerSaver">50</b>%</h3>
        <div id="alarmControl" class="controls"> <i class="material-icons">&#xE19C;</i>
          <smart-scroll-bar #scrollbar13 id="powerSaverSlider" [max]="100" [value]="50" scale-type="integer">
          </smart-scroll-bar>
        </div>
      </div>
    </div>
  </div>
</section>

6 NgModule bootstrap (also supported)

Same npm package and angular.json styles as steps 1-2. Put ScrollBarModule on your NgModule.imports instead of @Component.imports, and bootstrap with bootstrapModule(AppModule).

The demo sources bundled for this widget use standalone only (there is no app.module.ts in that folder). NgModule is fully supported: put ScrollBarModule from smart-webcomponents-angular/scrollbar on NgModule.imports, make your root component non-standalone (remove standalone: true and move widget modules from @Component.imports to the module), and bootstrap with platformBrowserDynamic().bootstrapModule(AppModule).

Minimal main.ts + app.module.ts pairing (adjust paths to match your CLI layout):

src/main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule).catch((err) => console.error(err));

src/app/app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ScrollBarModule } from 'smart-webcomponents-angular/scrollbar';

@NgModule({
	declarations: [ AppComponent ],
	imports: [ BrowserModule, ScrollBarModule ],
	bootstrap: [ AppComponent ]
})
export class AppModule { }

Reuse the template and class logic from steps 4-5 in AppComponent, configured for declarations + NgModule.imports instead of a standalone @Component.

Run

ng serve or npm start - then open http://localhost:4200/.

Smart UI for Angular - full documentation

Accessibility

The ScrollBar component follows WAI-ARIA best practices:

  • Keyboard navigation - Tab, Arrow keys, Enter, and Escape are supported
  • ARIA roles - Appropriate roles and labels are applied automatically
  • Focus management - Visible focus indicators for keyboard users
  • Screen readers - State changes are announced to assistive technology
  • High contrast - Supports Windows High Contrast Mode and forced colors

For custom labeling, set aria-label or aria-labelledby attributes on the component.

Live demos

Supported stacks: Smart UI targets Angular 17+, React 18+, Vue 3+, Node 18 LTS, and evergreen browsers; pin exact package versions to your org policy.