-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to have seperate html and css files when building a web component #1022
Comments
The only way we could support this is the HTML and CSS didn't have expressions. I'm not sure who that would be useful for. |
I have some observations that might help on this. Basically, this is already possible, with a couple caveats. Major caveat is that CSS and HTML files aren't importable modules (yet). So without some sort of front end tooling to turn those into JS/TS, a pure HTML or CSS file cannot be imported. CSS is easy, though. I prefer not going through front-end tooling and not using TS, so I create a file in my component folder called mycomponent.css.js. An example file can look like:
This can then be imported right into your component like so:
If you DO use front end tooling, you can create a plugin script in Babel or Webpack, or whatever you're using to wrap up an existing CSS file as the above JS. HTML is different though. Justin just chimed in with the basic problem as I was writing this. I've separated out my HTML as you're suggesting, just to see if I like it. And it's OK-ish. As Justin says, you'll likely want expressions in your HTML rather than just basic markup. I've done this in a mycomponent.html.js by exporting a function that accepts the component scope:
It feels a bit weird, but I guess I like the separation (for now). I can then use it in LitElement like so:
Hope that helps, if you really want to explore this |
Having templates in .html files would require both some way to import HTML, like HTML Modules, and a HTML-based template which is tracked in lit/lit#867 For CSS, we're waiting on CSS Modules, but until then you can use this rollup plugin And as @bengfarrell mentions, since all this is just JS right now you can totally split templates and inlined CSS into as many files as you want. Since this is tracked in other places, I'll close this issue here. Hope the pointers help. |
If you want to import lit-html into your lit-element from an external .html file, you can use this Rollup Plugin. |
@bengfarrell @justinfagnani I think I have found an improvement to the approach above to have the HTML contents in a separate file, which while not perfect, seems fairly satisfactory (it has worked for cases I've tried so far, but have not exhaustively tried complex cases). Here is how it would look in TypeScript (with explanations in comments) // my_element.html.ts file
import {html} from 'lit/lit.min.js'; // Or from wherever you import Lit from.
// Import the `MyElement` type (leveraging `import type` feature for clarity).
// This import is stripped by TS compiler, and therefore there are no runtime circular dependencies.
import type {MyElement} from './my_element.js';
// Use the "this: ..." TS annotation to be able to use `this` within the function below
// which makes it look as if getHtml was actually part of the `MyElement` class.
export function getHtml(this: MyElement) {
return html`
<div>${this.someText_}</div>
<input type="file" @change=${this.onChange_} />
`; The file above can be easily auto-generated by a build step from a Then here is how this can be called from // my_element.ts file
import {LitElement} from 'lit/lit.min.js'; // Or from wherever you import Lit from.
import {getCss} from './my_element.css.js'; // Can be generated from `my_element.css`
import {getHtml} from './my_element.html.js'; // Can be generated from `my_element.html`
export class MyElement extends LitElement {
...
static override get styles() {
return getCss();
}
override render() {
return getHtml.bind(this)();
}
// Use `protected` instead of `private` so that `getHtml()` satisfies TS visibility checks (error TS2341).
// This is not ideal, but better than making it public.
protected someText_: string;
protected onChange_() {...}
} The above allows declaring a web component in 3 separate (The |
Description
When working on more complex components, it is nice to be able to have seperate files for logic (js/ts), structure (html), and styling (css/scss/etc).
Angular.io has a good approach to this, in that you are able to write an all-in-one-file component, or split out the html and css.
Reasoning
The ability to split out html and css is helpful for beginner/intermediate coders, who may find javascript/typescript overwhelming. It is also helpful for people writing more advanced components, who find the one-file approach becomes unwieldy.
Examples
Below is an example of using multiple files to build the component:
Folder structure could be like so:
Acceptance criteria
Allow people writing web components with LitElement to split out their html and css from the javascript/typescript file.
The text was updated successfully, but these errors were encountered: