1

I've created a new project using the stencil component starter. Inside my component I'm using an external JS nouislider, which injects HTML elements into my div (this.slider ref):

...
componentDidLoad() {
  noUiSlider.create(this.slider, {
    start: [20, 80],
    range: {
      'min': 0,
      'max': 100
    }
  })
}
...

I've copied the slider's CSS into my-component.css and rewrote everything with :host selectors for the shadow dom:

:host(.my-component) .noUi-target {
    position: relative;
    direction: ltr
}

Everything works fine on Chrome/Firefox but the slider styles are not working on IE11/Edge because Stencil appends a helper sc-my-component class to every element that I have inside the render method and generates CSS rules like so:

.my-component.sc-my-component-h .noUi-target.sc-my-component {
  position: relative;
  direction: ltr
}

but the injected nouislider child HTML elements don't have the helper classes on them. I have an ugly fix for this case atm:

...
componentDidLoad() {
  noUiSlider.create(this.slider, {
    start: [20, 80],
    range: {
      'min': 0,
      'max': 100
    }
  })
  this.slider.querySelectorAll('div').forEach((child)=>{
    child.classList.add('sc-my-component')
  })
}
...

I'm appending the helper classes after the slider is created (the slider generates child divs only). Is there a better way to tell Stencil that I'm injecting elements inside lifecycle methods and that it needs to recognize those elements when CSS rules are being generated?

htmn
  • 1,505
  • 2
  • 15
  • 26
  • From the [browser suppot page](https://stenciljs.com/docs/browser-support) of Stencil, it seems that we need polyfills to support Shadow Dom in IE and Edge. You could refer to [this page](https://github.com/ionic-team/stencil#internet-explorer-11) about adding polyfills for IE 11 and adding [Custom Elements v1](https://github.com/webcomponents/polyfills/tree/master/packages/custom-elements) polyfill for Edge to see if it helps. – Yu Zhou Mar 04 '20 at 07:36

2 Answers2

0

This is not an answer to your question, nevertheless this could also be interesting for you:

We are currently working on the same topic (StencilJS, shadow: true, noUiSlider) and encountered the problem, that the slider's touch events are not working correctly in shadowDOM on mobile devices. We found a solution for this and already created a PR (https://github.com/leongersen/noUiSlider/pull/1060).

smk90
  • 1
  • Thanks a lot for the PR! I also had a problem with this, so for now I ended up using the [native](https://stackoverflow.com/a/60560815/3528132) `` and making it compatible for all the browsers that Stencil supports. Works for my case, I only needed a simple slider with min, max and step values. – htmn Mar 10 '20 at 18:06
0

I too had problems using nouislider in StencilJS but just managed to make it work.

my-slider.scss

 @import '~nouislider/distribute/nouislider.css';

 :host {
     padding: 50px 30px;
     display: block;
 }

my-slider.tsx

import { Component, h, Prop, Event, EventEmitter } from '@stencil/core';
import noUiSlider from "nouislider";


@Component({
    tag: 'skim-slider',
    styleUrl: 'skim-slider.scss',
    shadow: true
})
export class SkimSlider {

    @Prop() min!: number;
    @Prop() max!: number;

    private slider: HTMLElement;

    @Event() update: EventEmitter;

    componentDidLoad() {
        const slider = noUiSlider.create(this.slider, {
            start: [this.min, this.max],
            tooltips: [true, true],
            range: {
                'min': this.min,
                'max': this.max
            }
        });
        slider.on('change', (value) => this.update.emit(value));
    }

    render() {
        return (
            <div ref={e => this.slider = e}></div>
        );
    }
}

The trick that did it for me was 'display: block'

  • I don't see how `display: block;` solves the problem of adding the scope class name to dynamically created elements... – kraftwer1 Sep 07 '20 at 09:46