Search code examples
cssstenciljsflatpickr

How to use Flatpickr in Stenciljs components?


Flatpickr input field is not showing up in the stencil component with proper css. I added the flatpickr date input field in a newly created (using stencil cli) app. No other settings or configs are changed.

import { Component, h } from '@stencil/core';
import flatpickr from 'flatpickr';


@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {

  private element: HTMLInputElement;


  componentDidLoad() {
    
    flatpickr(this.element, {
      
    });
  }

  render() {
    return (
      <div>
        <input ref={el => this.element = el} type="text" id="flatpickr" />
      </div>
    )
  }
}

Solution

  • I'm guessing the problem is with the styling since the code you posted looks correct.

    Flatpickr appends the calendar to the body element by default and since CSS is encapsulated when ShadowDOM is enabled (shadow: true) the styles in my-component.css won't affect it.

    I see three options:

    1. Append to different element

    You can set a different parent for the calendar (your component or any element in it)

    import { Component, Element, h } from '@stencil/core';
    // ...
    export class MyComponent {
      @Element() el: HTMLElement;
    
      private element: HTMLInputElement;
    
      componentDidLoad() {
        flatpickr(this.element, {
          appendTo: this.el,
        });
      }
    
      render() {
        return (
          <div>
            <input ref={el => this.element = el} type="text" id="flatpickr" />
          </div>
        )
      }
    }
    

    And import the styles in the CSS (my-component.css):

    @import '~flatpickr/dist/flatpickr.min.css';
    

    2. Include the Flatpickr CSS globally. Include the CSS in your HTML head or any global CSS file.

    3. Disable ShadowDOM Set shadow: false to allow the styles in my-component.css to affect elements outside your component and import the CSS in my-component.css (same as in Option 1.).