Not Another To Do App

Getting your hands dirty and feet wet with Open Web Component Recommendations…sort of: Part 8

westbrook
6 min readFeb 27, 2019
May all your to do lists be short, if not empty! How better to give you time to think of the next great thing to do?

Welcome to “Not Another To Do App”, an overly lengthy review of making one of the smallest application every developer ends up writing at some point or other. If you’re here to read up on a specific technique to writing apps or have made your way from a previous installation, then likely your in the right place and should read on! If not, it’s possible you want to start from the beginning so you to can know all of our characters’ back stories

If you’ve made it this far, why quit now?

Separate Things Early, Often, and Only as Needed

Photo by Simon Rae on Unsplash

Sometimes a little distance is a good thing.

Thanks to ES modules, it’s easy to put a little extra distance between things in your code base, so easy that it’s also easy to put a little too much distance into your code base. When you have too much distance in your code, it’s hard to comprehend how, where, or why something is happening, but when you have just enough, you can be unbothered by concerns that are of little importance to the task at hand. This story is best told in my To Do app code through the two main approaches I’ve taken to including styles in components.

For context, let’s make sure everyone’s up-to-date on the static styles property of LitElement. Here we’re able to deliver an array of CSSResults to our element that will be prepared as Constructable Stylesheet Object to be a adopted by our custom elements when available, or to be delivered as <style/> elements inside of the shadow DOM in contexts where this API is not available. This means that rather than each instance of your custom element receiving its own copy of its CSS rules and then relying on the browser to try and decide when to deduplicate them internally, you are explicitly telling the browser that this set of rules will be applied across multiple instances; skipping the heuristics and getting right to the benefits of deduplication even faster. These benefits include a faster boot up time for your end users, and not just because there’s less CSS on the page to parse, an easier debugging process for your fellow developers, as editing the styles of one element with dev tools will effects all instances of it, and more. Many benefits are still being actively researched as Constructable Stylesheets is a fairly new API.

To take advantage of these capabilities, and to focus the code included directly in the classes for my custom elements, I often start straight away by separating my styles from my functional/template code. This would look something like:

// custom-element-styles.jsimport { css } from 'lit-element';export const styles = css`
:host {
/* Styles for my custom element... */
}
/* Styles for the remaining content of its Shadow DOM... */
`;
// custom-element.jsimport { styles } from './custom-element-styles.js';// ...static get styles() {
return [
styles,
];
}

The generated code for open-wc’s Starter App did not do this. By default it’s generated static styles getter outlined styles directly, a la:

static get styles() {
return [
css`
:host {
/* Styles for my custom element... */
}
/* Styles for the remaining content of its Shadow DOM */
`,
];
}

This did mean that when I had a good amount of styles in a component that I was doing some manual work to separate the styles as outlined above, however it did mean that in cases where there was only a few lines of CSS, I had a smaller file footprint by component. (No added files to ensure :host { display: block; } made it into an element.) It also meant that in some cases where I might not have thought all the way through the compositional possibilities of my styles I was given an extra touch point to do so. This happened in src/to-do.js who’s static styles getter looks like the following:

import { toDoButton } from './shared-styles.js';// ...static get styles() {
return [
css`
:host {
display: block;
}
div {
border-top: 1px solid;
padding-left: 5px;
white-space: pre-wrap;
}
`,
toDoButton,
];
}

Yes, the toDoButton import is a stylesheet that is shared between multiple components. I ended up choosing not to separate the to-do element specific styles into their own file, but having the toDoButton styles separated as such allows them to be shared between the to-do and to-do-write elements, the effect of which you can see below:

Those buttons certainly look the same, right?

This same concept can be taken one step further to share not just whole sheets, but lists of specific rules for individual elements. Included in the src/shared-styles.js list of exports is formElementFocus and formElementHover:

export const formElementFocus = css`
outline: none;
background-image:
linear-gradient(
to top,
#0077FF 0px,
#0077FF 2px,
transparent 2px,
transparent 100%
);
`;
export const formElementHover = css`
background-image:
linear-gradient(
to top,
currentColor 0px,
currentColor 2px,
transparent 2px,
transparent 100%
);
`;

These styles are mixed both into the button rules included in toDoButton but also are applied to the textarea in to-do-write. LitElement and lit-html open the door to these sorts of techniques and many more yet to be fully explored. Drop a comment below with ways are you separating, sharing, and composing functionality/styles/etc. to the benefit of your applications. Judiciously leveraging opportunities like the ones above and those shared in the comments below to separate your code (or not) can give you a broad pallet of options when it comes to composing features to new ends.

The Short Game

As voted on by a plurality of people with opinions on such topics that are both forced to see my tweets in their Twitter feed and had a free minute this last week, a 9000+ word article is a no, no.

So, it is with the deepest reverence to you my dear reader that I’ve broken the ongoing conversations into a measly ten sections. Congratulations, you’re nearing the end of the eighth! There’s only two more to go, can you make it? You can make it. Push, push! Get those last two reps in.

Special thanks to the team at Open Web Components for the great set of tools and recommendations that they’ve been putting together to support the ever growing community of engineers and companies bringing high quality web components into the industry. Visit them on GitHub and create and issue, submit a PR, or fork a repo to get in on the action!

--

--