0

I'm using lit.dev to try to set up some Web Components.

However, I also want to use Bootstrap as a jumping off point for my styles, and take advantage of the themeing, variables, and mixins they provide.

I'm able to define a simple web component using Lit without much fuss, but I'm having trouble incorporating my .scss styles.

I was able to use the syntax !!loader-name!loader-name!./myFile.scss in my JavaScript import to get it to work, but this seems hacky. I'm also not sure what this syntax is called or what it is doing, if anyone can help clarify that.

My code:

// myComponent.ts

import {LitElement, css, html, unsafeCSS} from 'lit';
import {customElement, property} from 'lit/decorators.js';

import 'bootstrap'
import style from '!!css-loader!sass-loader!./myComponent.scss';
    
@customElement('my-component')
export class NavItem extends LitElement {

    static styles = css`${ unsafeCSS( style ) }`;

    render() {
        `
        return html`<p>Some Content</p>`
    }
}

// myComponent.scss

@use "../../assets/styles/style";

// Custom SCSS Code below...

// assets/styles/style.scss

@import "~bootstrap/scss/bootstrap";

I'm using Storybook, here is my webpack config in main.js:

module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    {
      name: '@storybook/preset-scss',
      options: {
        cssLoaderOptions: {
          modules      : {
            mode: 'local'
          },
          importLoaders: 2
        },
      },
    },
    "storybook-color-picker",
    ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }],
  ],
  babel: async (options) => {
    Object.assign(options.plugins.find((plugin) => plugin[0].includes('plugin-proposal-decorators'))[1], {
      decoratorsBeforeExport: true,
      legacy: false
    })
    return options;
  },
  "framework": "@storybook/web-components",
  "staticDirs": ['../stories/assets']
}

Everything renders correctly, but I'm not really sure what is happening on the webpack side of things. I think what is happening is that webpack is converting my SCSS file into a string, and I am able to read that string with unsafeCSS()

My question is: Is there a better way for me to consume SCSS in Lit components?

user3183717
  • 4,427
  • 6
  • 20
  • 42
  • It's probably not the smartest idea to use web components and to wish for Bootstrap to style that. One of the basic ideas of web components is style encapsulation, which means none of your outside Bootstrap styles will be available inside any of your web components (except inherited properties). It's probably even worse of an idea to try to use web components with a tool on top (like lit.dev) without properly digging into native web components first. None of the widely available CSS frameworks are properly suited to use in web components. – connexo Apr 02 '22 at 13:51
  • Good to know. I want to use Web Components for encapsulation like you say as well as namespacing, but at the same time a CSS/SCSS framework is attractive for avoiding reinventing the wheel as well as keeping my styles DRY. To clarify, my code posted is "working", it just seems like it's not the best approach to achieve what I'm going for, and I don't understand some of the syntax for *why* it's working (namely the `import from '!!loader ... ' ` line). Though there's probably stuff happening in the ShadowDOM I don't fully understand that is also less than ideal in terms of performance. – user3183717 Apr 04 '22 at 15:47
  • That import with the loaders prepended tells your webpack how to process the import. You should be able to do the same via your webpack.config.js. – connexo Apr 04 '22 at 15:58

0 Answers0