A simple SCSS watcher with autoprefixer.
- Use Lit + SASS to build Web Components.
- Leverage ES6 module features to enable easy adoption of import-attributes for CSS module scripts.
- Keep it simple and independent of any bundler such as rollup, parcel, webpack.
// I don't want to use SASS directly in my code
import styles from './my-component-style.scss' 😟
- my-component-styles.scss
:host {
display: block;
color: #{'${unsafeCSS(tokens.colors.primary)}'};
@at-root #{&}([variant=large]) {
letter-spacing: 3px;
}
}
p {
background-color: #{'${unsafeCSS(tokens.colors.secondary)}'};
:host([variant='large']) & {
padding: calc(#{'${unsafeCSS(tokens.spaces.xlarge)}'} + 16px);
}
}
- my-component-styles.css.js
import {css, unsafeCSS} from 'lit';
import * as tokens from 'my-design-system-tokens';
export const styles = css`
:host {
display: block;
color: ${unsafeCSS(tokens.colors.primary)};
}
:host([variant='large']) {
letter-spacing: 3px;
}
p {
background-color: ${unsafeCSS(tokens.colors.secondary)};
}
:host([variant='large']) p {
padding: calc(${unsafeCSS(tokens.spaces.xlarge)} + 16px);
}
`;
- my-component.js
import {html, LitElement} from 'lit';
import { styles } from './my-component-styles.css.js';
class MyComponent extends LitElement {
static get styles() {
return [styles]
}
}
Or just, compile .scss files to .css file and then use CSS module scripts
import {html, LitElement} from 'lit';
import styles from './my-component-styles.css' with { type: 'css' };
class MyComponent extends LitElement {
static get styles() {
return [styles]
}
}
The first time a default template will be used to create a style file
// sass-template.tmpl
import {css} from 'lit';
export const styles = css`<% content %>`;
// my-component.scss
:host {
display: block;
color: desaturate(#ad141e, 20%);
}
my-component.scss --> my-component-styles.css.js
or without suffix
my-component.scss --> my-component.css.js
Following changes in the scss file (my-component.scss)
will update only the content between the css``;
template literal in .css.js file
// from original template
import {css} from 'lit';
// new content added later, it will not be deleted when updating scss file
import * as tokens from 'my-design-system-tokens';
export const styles = css`
// only this part will be modified
// new css from scss file
`;
npm i -D sass-style-template
Here is an example of using Vite + concurrently in the package scripts:
// package.json
"scripts": {
"start": "concurrently -k -r \"npm:sass:watch\" \"npm:vite\"",
"vite": "vite",
"sass:watch": "sass-style-template"
}
sass-style-template
// commander options
version(pkg.version, '-v, --version', 'show version number')
.option('-s, --marker-start <string>', 'start replace position')
.option('-e, --marker-end <string>', 'end replace position')
.option('-g, --custom-glob <string>', 'string pattern to be matched')
.option('-c, --css-file', 'generate a CSS file instead of JS or TS')
.option('-wo, --wo-suffix', 'without suffix string `-styles`')
.option('-j, --js-file <string>', 'file extension')
.option('-d, --destination <string>', 'location of the output file');
// package.json
"scripts": {
"start": "concurrently -k -r \"npm:sass:watch\" \"npm:vite\"",
"vite": "vite",
"sass:watch": "sass-style-template -j ts"
}
sass-template.tmpl
import {css}from 'lit';
export const styles = css`<% content %>`;
Custom Template
Creating a custom template file in the root directory with the name sass-template.tmpl
// Example: sass-template.tmpl
// https://github.com/material-components/material-web/blob/main/scripts/css-to-ts.ts
/**
* @license
* Copyright 2024 XXX LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {css} from 'lit';
export const styles = css`<% content %>`;
start replace position :
const styles = css`
end replace position :
`; export { styles as default };
pattern to be matched :
./*.scss, ./src/**/*.scss
generate css file instead of using template :
undefined
without suffix string -styles :
undefined
file extension :
js
location of the output file :
undefined
Scaffold a new Lit component with SASS using:
Free Software.