<?xml version="1.0" encoding="UTF-8" ?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
      <channel>
      <atom:link href="http://component.kitchen/feeds/blog.xml" rel="self" type="application/rss+xml"/>
      <title>Component Kitchen</title>
      <description>Reviews of notable web components and other thoughts from the staff at Component Kitchen</description>
      <link>http://component.kitchen</link>
      
    <item>
      <title>Building a Storybook-like demo browser with web components — a much simpler way to get most of the benefits</title>
      <pubDate>Mon, 02 Nov 2020 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/building-a-storybook-like-demo-browser-with-web-components-a-much-simpler-way-to-get-most-of-the-benefits</link>
      <guid>http://component.kitchen/blog/posts/building-a-storybook-like-demo-browser-with-web-components-a-much-simpler-way-to-get-most-of-the-benefits</guid>
      <description><![CDATA[
      <p>I recently tried <a href="https://storybook.js.org/">Storybook</a>, a popular tool for browsing the demos and documentation for a UI component library. I think Storybook offers a good <em>user</em> experience, but its <em>developer</em> experience entails complexity out of proportion to its benefits. I tried creating a simpler web component library browser using web components, and am happy with the result.</p>
<h1>Storybook: The good parts</h1>
<p>Storybook is a good idea. It’s helpful to be able to quickly browse a component library and see the range of what each component can do.</p>
<figure>
  <a href="/static/20241020005925/images/blog/Storybook.png">
    <img src="/static/20241020005925/images/blog/Storybook.png" style="max-width: 100%;">
  </a>
</figure>

<p>Storybook offers useful features like:</p>
<ul>
<li>Top-level UI for browsing stories.</li>
<li>Automated construction of an index of stories: given a project that contains story definition files, Storybook will generate a hierarchical outline of the stories defined in those files.</li>
<li>Router that updates the page URL to deep-link to the currently-selected story, making it easy to share links to specific demos.</li>
<li>Search facility that filters the index to those stories whose titles contain the desired text.</li>
<li>Miscellaneous tools: zoom in/out, change background color, change viewport width to preview mobile device results, maximize the demo viewport, open demo in a new window, copy the current URL for sharing.</li>
<li>Inline view of the source code used to create the adjacent demo.</li>
<li>Property inspector panel (“Controls”) that lets the user dynamically change the properties of a demo component.</li>
<li>API documentation generation.</li>
<li>An add-on ecosystem.</li>
</ul>
<h1>How to define a demo written in HTML? Hmm…</h1>
<p>My own experiments with Storybook did not pan out, and I found it too heavy for the relatively simple problem I was trying to solve. (You can find my notes from that experience in an appendix following this post.)</p>
<p>For me, the crucial turning point came when I was trying to define my first story demo in Storybook. Since my project is creating plain web components, I just had a bit of regular HTML I wanted to use for a story.</p>
<p>But to define my HTML demo in a common Storybook configuration, I had to create a markdown document of some flavor I’d never seen before (“.mdx”), and then put something like this in it:</p>
<pre><code>```js
export function MyElement() {
  return html`&lt;my-element&gt;Hello, world.&lt;/my-element&gt;`;
}
```
</code></pre><p>Here we&#39;ve got HTML inside of a lit-html JavaScript template literal inside of a JavaScript function inside of a JavaScript code block inside of a markdown document.</p>
<p>Whew! All that to display some HTML.</p>
<p>Huh. If only web browsers gave us some native way to write HTML…</p>
<p>Oh, right — <em>they do!</em> It’s called HTML.</p>
<p>What I want to write is an .html file that includes the demo as plain HTML:</p>
<pre><code class="lang-html">&lt;my-element&gt;Hello, world.&lt;/my-element&gt;
</code></pre>
<h1>A web component library browser made of web components</h1>
<p>Stepping back, the Storybook application runtime UI is actually not that complex. There are certain useful UI elements that appear on Storybook pages, like the story index and the “View code” buttons. The web already provides an easy, standard way to implement reusable UI elements: web components.</p>
<p>I built a simple component library browser that achieves perhaps 60% of what I want out of Storybook, but in a more straightforward fashion using web components. It&#39;s meant for local development, but I&#39;ve quickly posted an unbundled version of that if you want to see the <a href="https://component.kitchen/demos/">Elix web component library demos</a>.</p>
<p>The first iteration closely followed the Storybook UI:</p>
<figure>
  <a href="/static/20241020005925/images/blog/Story browser with Storybook styles.png">
    <img src="/static/20241020005925/images/blog/Story browser with Storybook styles.png" style="max-width: 100%;">
  </a>
</figure>

<p>Building this with web components, and generally using the web platform more directly, makes it possible to do much (not all) of what Storybook does much more simply and flexibly.</p>
<ul>
<li>Demo/documentation pages are plain .html files. You can write these however you want, and serve them with any web server you want.</li>
<li>A <code>&lt;story-browser&gt;</code> component on the index page handles the top-level UI pattern: navigation is shown on the left, and the demo page is shown on the right in an <code>&lt;iframe&gt;</code>.</li>
<li>You define the set of demos by placing a handwritten list of plain <code>&lt;a&gt;</code> links as children inside the <code>&lt;story-browser&gt;</code> component. Since HTML is the composition medium, you can write whatever HTML you want there; you&#39;re not limited to links.</li>
<li>The <code>&lt;story-browser&gt;</code> component includes a tiny router that picks off the path from the URL and hands that to the iframe.</li>
<li>Once a demo is loaded, the story browser component extracts the demo page title and shows that as the document title in the browser&#39;s title bar. This extracts maximum value out of existing HTML metadata.</li>
<li>The component also highlights the current demo in the navigation index by applying a CSS class you can style however you want.</li>
<li>Like the Elix components, the story browser component itself contains no aesthetic styling. Instead, you can style the interior shadow parts of that component using standard CSS <code>::part</code> syntax. (See a different styling example below.)</li>
<li>Because you define the demos in plain .html files, you can always load the demo pages directly to cut out the story-browsing UI. That minimizes the code that might confound your debugging of the component itself. As a shortcut, I added a little close box on the navigation pane that navigates you to the current demo as a top-level page.</li>
<li>Because this is just HTML, all the native HTML features work. You can Command-click on links to open them in a new window, the links are fully accessible, etc.</li>
<li>The existing <a href="https://component.kitchen/elix">Elix documentation site</a> already has a way of inlining the HTML demos into component documentation, and I could leave all that infrastructure intact. The same demos can be used in both places.</li>
<li>For another web component library, I created a simple <code>&lt;story-demo&gt;</code> web component that can be used to wrap an individual demo. This <code>&lt;story-demo&gt;</code> component shows the demo, and also extracts the demo markup (i.e., its own light DOM content) and renders that markup as viewable code. This addresses Storybook&#39;s &quot;Show Code&quot; feature, without any need for build-time tooling. (I&#39;m not using that <code>&lt;story-demo&gt;</code> component in the Elix demos yet.)</li>
<li>These web components for browsing stories are written in plain JavaScript that requires no tooling and no build step.</li>
<li>I happened to write the story components in Elix, which has no dependencies of its own.</li>
<li>Out of curiosity, I rewrote the <code>&lt;story-browser&gt;</code> component in <a href="https://gist.github.com/JanMiksovsky/6cc2d7289804132717c0cbd57c5dd917">vanilla JavaScript with zero dependencies</a>. Minified (but not gzipped), this component was 2050 <em>bytes</em> in size. This is contrast to the hundreds of megs of dependencies pulled in by a straightforward Storybook installation. The web component is just not doing very much, which is exactly the point.</li>
</ul>
<p>Since there&#39;s not much going on here, there&#39;s very little new that someone has to learn to use it. If someone needs to be taught how to do something in HTML — then they&#39;re learning something useful for the rest of their career! The HTML pages they create with this approach are as future-proof tech as one can ask for, and are simple enough to work until the heat death of the universe.</p>
<p>I eventually changed the page styles to get a plainer look which I felt put more attention on the demos:</p>
<figure>
  <a href="/static/20241020005925/images/blog/Story browser.png">
    <img src="/static/20241020005925/images/blog/Story browser.png" style="max-width: 100%;">
  </a>
</figure>

<h1>What I left out</h1>
<p>Here are some of the Storybook features I did <em>not</em> implement:</p>
<ul>
<li>Built-in browser features. Every browser already has tools like Zoom In/Out and Share Link.</li>
<li>Generating a hierarchical index of demos. Even for the large collection of components in the Elix project, it&#39;s just not that hard to keep a handwritten list of links up to date. Handwritten HTML preserves a huge range of freedom. On the rare happy occasion where someone is adding a new demo, their brain can insert the link into its proper position in the alphabetical hierarchy. If the Elix project ever decides to programmatically generate the demo index, that could be done in a minimally-invasive fashion via a simple build script that generated the links in some static form that could be referenced by the <code>&lt;story-browser&gt;</code> component.</li>
<li>Search. This would be nice to have at some point, and wouldn&#39;t be particularly hard. That would be a nice web component on its own!</li>
<li>Story files. The Storybook server can be viewed as a kind of templating language for translating stories into HTML files. This can help avoid the boilerplate that is a necessary part of working with loose HTML files. That said, boilerplate is not necessarily a terrible thing. Each of the loose HTML demo pages in Elix&#39;s demos folder contains some identical boilerplate which, very occasionally, must be tweaked. Doing so at design time is easy enough via a find-and-replace operation in any modern code editor. That feels much, much simpler than introducing a templating system.</li>
<li>Run-time UI controls to let a user manipulate component property values in the browser. This might be the nicest Storybook feature to add, but I&#39;d prefer to wait until there&#39;s a standard way for having a component project describe a component&#39;s API. In the meantime, if you&#39;re already the kind of developer who can create a web component, then it&#39;s probably not challenging for you to manually create demos with controls that adjust component properties. And any run-time component-editing UIs could be nicely packaged up as web components.</li>
<li>Generating API documentation. The Elix project already has a way of generating documentation for its external developer site, so the project didn&#39;t need that.</li>
</ul>
<p>Defining the key story browsing UI in web components lets you maintain complete control of the top-level pages and project infrastructure. The separate aspects of this approach are simple, small, loosely-coupled pieces that can easily be replaced as needs change.</p>
<p>It&#39;d be pretty interesting to see this approach built out into an ecosystem of web components and other simple parts which work well together. That could ultimately comprise a compelling, web-oriented alternative to Storybook.</p>
<h1>Conclusion</h1>
<p>A component library browser like Storybook is a useful tool. After developing the initial story browsing components for the Elix library, I discovered small UI regressions in a couple of demos, simply because it was easier for me to quickly experience all the demos in action.</p>
<p>But I think the benefits of a component library browser can be achieved in ways that work with the grain of the web, squeezing every advantage out of solid technology you already know well.</p>
<p>&nbsp;</p>
<hr>

<h3>Appendix: Notes on trying Storybook</h3>
<p>My goal in writing the above post was not to focus on Storybook, but on addressing what it does in a simpler way. From what I can see online, many people love Storybook. If that&#39;s you, that&#39;s great! I&#39;m glad you&#39;ve found a tool that meets your needs.</p>
<p>If you&#39;re <em>considering</em> adopting Storybook, and are interested in knowing ahead of time what its downsides might be, I&#39;m including my notes from my experiments with it here. Your Mileage May Vary.</p>
<ol>
<li>Storybook appears to have been originally designed to browse React component libraries. It shares with React an approach that covers up much of the browser platform with proprietary JavaScript abstractions in the name of developer ergonomics. I am personally skeptical of that approach.</li>
<li>Storybook is a full-blown application server in its own right that must be accommodated inside the host project.</li>
<li>Installing and configuring the Storybook application <em>in an existing project</em> is a non-trivial task.</li>
<li>Various project generators exist that can pre-populate a project with the required files. These all assume that you don&#39;t want to understand how the resulting application actually works. They create a lot of files, tell you how to start the application, and then you’re on your own.</li>
<li>The results of running one of these project generators are, in my experience, rigid and brittle. Attempting to diverge from the generated project is likely to break the Storybook application in ways which are difficult to diagnose or resolve.</li>
<li>Storybook is still focused primarily on React development. There are project generators aimed at web component developers, but these don’t yet feel like first-class citizens of the Storybook ecosystem.</li>
<li>To the extent Storybook does support web component development, it focuses on frameworks like Polymer/lit-element rather than plainer JavaScript web component development.</li>
<li>The extensive toolchain imposed by Storybook, and the run-time environment of the Storybook UI, can complicate debugging. When you&#39;re trying to debug a UI element, any other UI code on the page can make it harder to isolate the problem. So while Storybook may make it easier for designers and other developers to browse your component, it can get in the way of letting you actually create those components in the first place.</li>
<li>Storybook forces use of a build process, even if the underlying web components don’t need a build process. Even for a minimal web component project, Storybook builds are slow.</li>
<li>Storybook adds a set of huge set of files. Depending on which starting point you use, the configuration can be massive.</li>
<li>Storybook has an extensive set of configuration options, add-ons, etc. It’s probably possible to get whatever UI you want in a Storybook application. However, the <em>way</em> you configure UI in Storybook will be substantially different than how you would create the exact same UI in an application of your own.</li>
<li>In other words, learning how to do UI inside of a Storybook app isn’t teaching you anything about building app UI outside of Storybook. When the day comes that you decide to present your component library in any other way — or work on literally anything else — your Storybook knowledge will not help you.</li>
<li>Storybook appears aimed first at local developer use, and only secondarily at the task of making documentation for internal or external consumers of component libraries. Many organizations creating UI components need both.</li>
</ol>
<p>Stepping back, Storybook is essentially a complete CMS (Content Management System). It&#39;s reinventing CMS infrastructure with the presumption that browsing web component libraries is a special task that deserves its own ecosystem. I question that premise.</p>
<p>Even if the premise were true, companies that provide web component libraries <em>already have a CMS</em> for everything else they do. Storybook isn’t large enough to encompass an entire corporate site, and it’s doubtful that companies would want to switch their developer site CMS just to be able to offer a prebuilt web component library browsing UI.</p>
<p>So if your company is using Storybook and ever decides to make its components available to external developers, you will have to reconcile your internal and external documentation platforms. You will need to either: a) shoehorn Storybook into your developer site, b) reimplement the Storybook functionality in the context of your existing developer site so people can browse the same demos there, or c) rewrite all your demos and documentation in whatever form your existing site needs, and then try to keep those in sync going forward. None of those options is attractive.</p>
<p>Perhaps the most puzzling thing to me is that, for a project designed to showcase UI component libraries, Storybook itself is not presented as a collection of UI components. It’s built internally from components, presumably React components, and it looks like the project is beginning to make that UI componentry available to developers. But components are still not the dominant paradigm for working with Storybook.</p>
<p>I spent half a day trying to get Storybook working in the context of an existing web component project, with an eye towards someday using it to document the general-purpose components in the <a href="https://component.kitchen/elix">Elix web component library</a>.</p>
<ul>
<li>I tried several different Storybook application generators, none of which worked out of the box in the context of my existing project.</li>
<li>The web component project I had in mind uses TypeScript, which complicates Storybook configuration.</li>
<li>That project uses rollup for bundling, which also complicates configuration. Most Storybook projects and documentation document the use of webpack.</li>
<li>I was eventually able to find an example of a Storybook configuration using TypeScript and rollup, but it was still very hard to configure Storybook inside the context of an existing application. Wrangling a tool like Storybook into a complex, existing project is next to impossible unless you understand a great deal about the tool. From the documentation, I could not easily form an accurate model of how Storybook performs its core functions.</li>
<li>I ultimately had to create a new project from scratch so just to get something I could play with.</li>
<li>The node_modules folder of the new project was 240MB in size. The size of node_modules isn&#39;t the main metric to use in evaluating tools, but I think its order of magnitude can be a useful proxy for complexity. However you slice it, 100s of megabytes of dependencies suggests that this is a complex answer to what seems like a simple problem. The web component approach above is smaller in size by 5 orders of magnitude.</li>
<li>I was forced to use much, much more technology than I wanted. Among other things, the particular Storybook configuration I could get to work wanted me to create story demos using lit-html. I don&#39;t use lit-html, and I had no intention of adopting it just to be able to get my web components rendering in Storybook. I could not easily find documentation on how to create demos in plain JavaScript or HTML.</li>
<li>A colleague who loves Storybook and is much cleverer than I am eventually pointed me at their own Storybook project, which was better suited to plain web component development. It is wonderful to see that such a thing is possible. But I remain wary of a tool where my primary use case requires sacred knowledge instead of being the tool&#39;s primary use case.</li>
</ul>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Unsurprising code and magic — optimizing for the first time vs the nth time</title>
      <pubDate>Mon, 09 Mar 2020 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/unsurprising-code-and-magic-optimizing-for-the-first-time-vs-the-nth-time</link>
      <guid>http://component.kitchen/blog/posts/unsurprising-code-and-magic-optimizing-for-the-first-time-vs-the-nth-time</guid>
      <description><![CDATA[
      <p>I’ve read some recent back-and-forth on Twitter regarding whether “magic” in a framework or library is something to be avoided or sought. We’ve spent a fair amount of time over the past year rewriting the core of the <a href="https://elix.org">Elix</a> web components project to remove what we felt were magical aspects. I wanted to write down some reasoning for that, both to better understand my own instincts, and also as a way of explaining those changes in Elix.</p>
<h2>Writing for the 1st or nth time</h2>
<p>Dealing with code to solve a problem more than once invokes two opposing forces in tension: 1) how much effort someone needs to invest to understand, read, or write something the first time and 2) the effort someone needs to expend to understand, read, or write that same something for the nth time.</p>
<p>We could represent the possible resolutions of this tension on a spectrum, where the left end represents optimizing for the first time and the right end represents optimizing for the nth time:</p>
<center>Optimize for first time ⟷ Optimize for nth time</center>

<p>The <a href="https://en.m.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of Least Astonishment</a>, also known as the Principle of Least Surprise, suggests that “a component of a system should behave in a way that most users will expect it to behave; the behavior should not astonish or surprise users.” This property sounds highly relevant to the left side of the spectrum. We could characterize that end as “straightforward” or “unsurprising”; it also tends to be “flexible”. A negative characterization might be “verbose”.</p>
<p>On the other end, positive characterizations of the right end of that spectrum might be “concise” and “efficient”; negative characterizations might be “surprising” or “hard to learn”, and possibly “inflexible”.</p>
<p>Programmers evidently disagree on a definition for “magic”, but when I find code I personally consider to be magic, it’s at the right end of this spectrum.</p>
<h2>A coding tour of this spectrum</h2>
<p>Let’s walk through some examples of how an identical bit of functionality might be expressed at different points along this spectrum, working our way from left (first time, unsurprising) to right (nth time, potentially very surprising).</p>
<p>Suppose we have a class <code>Foo</code> that wants to log a message “Hello” in its constructor, and the output should be “Foo: Hello”. (Let’s take it as a given that we want to create a class; if all we really want to do is log a message, we obviously don’t need a class.)</p>
<h2>Solution 1</h2>
<p>A completely straightforward solution at the far left end of the spectrum:</p>
<pre><code class="lang-js">class Foo {
  constructor() {
    console.log(&quot;Foo: Hello&quot;);
  }
}
</code></pre>
<p>To a JavaScript developer, there is zero surprise in this code: it’s all standard JavaScript syntax and a single call to a well-known web platform API to log a string. When they run this code, the resulting console message will be 100% expected. This code is also completely flexible: if the developer wants to change the message, or log two messages, or whatever, they have the freedom to do so.</p>
<p>In this trivial example, we could easily decide we want to stay on this unsurprising side of the continuum, and ask everyone on our project writing one of these classes to copy-and-paste this boilerplate into their code. That’s an eminently reasonable answer.</p>
<h2>Solution 2</h2>
<p>But maybe our little logging task gets more complex, and the amount of boilerplate creeps up to a few lines, or a dozen. In that case, we might want to factor things out. We want to trade off a tiny bit of conceptual load for brevity. We begin to consider how much support we want to give ourselves for writing this code for the nth time. We feel tugged along to the right of this spectrum.</p>
<p>If logging begins to entail some complexity, we could create a utility function to log our message:</p>
<pre><code class="lang-js">import log from &quot;./log.js&quot;;

class Foo {
  constructor() {
    log(&quot;Foo: Hello&quot;);
  }
}
</code></pre>
<p>This has the potential to be ever-so-slightly surprising to a new project member. They’ll be told to use the boilerplate, but they can’t be completely sure what <code>log</code> is going to do unless they read the source. We’re relying here on the obviousness of the library function name “log” to eliminate or reduce surprise. If we choose our name well, a dev will be able to imagine what the API will do. In the above case, seeing a console message will not be surprising.</p>
<h2>Solution 3</h2>
<p>There may come a point where we have other requirements for our classes, and see the introduction of a number of other API methods our devs should remember to call. We could introduce a bit of framework for these classes in the form of a base class to provide those APIs:</p>
<pre><code class="lang-js">import Base from &quot;./Base.js&quot;;

class Foo extends Base {
  constructor() {
    super();
    this.log(&quot;Foo: Hello&quot;);
  }
}
</code></pre>
<p>The functionality is equivalent — although we’ve introduced a potential for a great deal more surprise because the constructor needs to call <code>super</code>. That could be helpful; there may be useful initialization the <code>Base</code> superclass can provide. Significantly, some of that useful functionality could be added to <code>Base</code> in the future, and the <code>Foo</code> class here would benefit <em>even if its code were left unchanged</em>.</p>
<p>The tradeoff is that our class author now has a bit of framework under their feet, and may be a little surprised what it does, especially if that behavior changes underneath them without notice.</p>
<h2>Solution 4</h2>
<p>If devs on our project occasionally forget to call <code>this.log()</code>, one recourse would be to move the logging call to the superclass, and have the subclass pass the message-to-be-logged to the <code>super</code> constructor:</p>
<pre><code class="lang-js">import Base from &quot;./Base.js&quot;;

class Foo extends Base {
  constructor() {
    super(&quot;Foo: Hello&quot;);
  }
}
</code></pre>
<p>If we’re using a type-checking system like TypeScript, we can define the signature of the <code>Base</code> class constructor such that the message is required. In that way, if the dev forgets to pass a message, or forgets to define a constructor entirely, the type-checker will produce a compile-time error. That should serve as an effective reminder.</p>
<p>That’s a powerful degree of enforcement — but note that we’ve lost some of the clarity of our code. That string parameter to the <code>super</code> constructor has no obvious identity or purpose. When the superclass logs that message to the console, that could easily surprise the developer.</p>
<p>Another point worth noting is that our solution is now less flexible. The downside of requiring a string parameter in the constructor is that the developer must always supply a string. If they don’t want to log a message, or want to log two messages, etc., they’ll have a harder time figuring out the best way to do so.</p>
<h2>Solution 5</h2>
<p>We could restore some clarity by introducing a property which the base class constructor will retrieve from the subclass:</p>
<pre><code class="lang-js">import Base from &quot;./Base.js&quot;;

class Foo extends Base {
  get message() {
    return &quot;Foo: Hello&quot;;
  }
}
</code></pre>
<p>Although the purpose of the string is now a bit clearer — it’s a message of some kind — its involvement in the class is quite unclear. From the above, it’s not apparent whether the <code>message</code> code gets called at all.</p>
<p>The <code>message</code> property is essentially a new lifecycle method defined by the <code>Base</code> class. That’s a powerful technique, but the timing and behavior of a lifecycle method are opaque unless one reads the documentation. It’s unclear, for example, when that property will be retrieved, whether it might be retrieved once or multiple times, whether it should return the same value each time, whether the value will be cached, etc.</p>
<h2>Solution 6</h2>
<p>One thing we may notice as our team copies-and-pastes this boilerplate is that people may occasionally forget to update the name of the template class “Foo” in the message string. To address that, we could have the Base class itself obtain the class name from the subclass using reflection, e.g., by retrieving <code>this.constructor.name</code>.</p>
<pre><code class="lang-js">import Base from &quot;./Base.js&quot;;

class Foo extends Base {
  get message() {
    return &quot;Hello&quot;;
  }
}
</code></pre>
<p>This is more concise, but when the class logs “Foo: Hello”, it may take the dev a minute to figure out where the “Foo” part came from. That’s possibly surprising.</p>
<p>What will be <em>extremely</em> surprising is compiling or minimizing this class and discovering that it logs something like “a: Hello”. Build tools may transform source code, including class names, so the class <code>Foo</code> might be renamed <code>a</code> for brevity. This interference between library abstraction and build tools can often be baffling, especially if you’re familiar with only one layer or portion of a complex system.</p>
<h2>Solution 7</h2>
<p>If our team is writing dozens of these classes, we might decide to optimize for brevity even further. We might decide to use still-unstandardized JavaScript decorators, say:</p>
<pre><code class="lang-js">import Base from &quot;./Base.js&quot;;

@message(&quot;Hello&quot;)
class Foo extends Base {}
</code></pre>
<p>This is quite concise. In exchange, it’s also quite limited. For one thing, since decorators are not yet standard JavaScript (as of this writing), we’re forcing the project to use a transpiler to process the decorator.</p>
<p>For another thing, depending on how it’s implemented, the decorator may run with different timing than the earlier <code>message</code> getter. The decorator is also more constrained than a handwritten property getter. Depending on the size of our project, we might decide that such constraints are beneficial — or we might discover that they place significant limitations on a developer trying to handle edge cases.</p>
<p><em>[Update: @pmdartus pointed out that the <code>message</code> decorator would have to be imported from somewhere.]</em></p>
<h2>Solution 8</h2>
<p>Suppose our team is now writing hundreds of these classes. Maybe those classes are now directly related to our company’s core business, and we make money for every class we write!</p>
<p>We could create a domain-specific language just to crank these classes out. We could, say, define a JSON format, and put the following in <code>Foo.json</code>:</p>
<pre><code class="lang-json">{
  &quot;message&quot;: &quot;Hello&quot;
}
</code></pre>
<p>And then have a build tool consume this format to generate a class with the name and message we want. That’s extremely efficient, but it’s getting pretty hard to tell from the above what’s going to happen. This also requires a new developer to install and learn a proprietary tool, which is going to drive up the time required to write their first class.</p>
<p>And the result is now quite rigid: since there’s no place here for the dev to contribute code, there’s no ability for them to accommodate unusual situations.</p>
<h2>Solution 9</h2>
<p>Why stop there? Let’s define a new file format that contains nothing but the message we want to log, and take the class name from the name of the file. We create a new file called <code>Foo</code> and put the message into it:</p>
<pre><code>Hello
</code></pre><p>We compile this to generate a class, run that, and see “Foo: Hello” in the console. Was that expected?</p>
<p>We’re working at a theoretical edge now, as every bit of information is tuned to our task. We’ve got a system that’s highly optimized for our needs. You may have a different definition for “magic”, but this solution feels pretty magic to me.</p>
<p>This solution is probably quite surprising to the uninitiated. The line of “code” above certainly looks simple, but it’s impossible to guess what it will do until you run it.</p>
<p>The solution would be extremely efficient for teams that need to crank out these classes, but the solution is also completely rigid. It can’t do anything other than what it’s designed to do.</p>
<h2>Visualizing this trade-off</h2>
<p>We can do some simplistic analysis of these solutions. For starters, while code size doesn’t equate directly to nth time efficiency, it’s a reasonable proxy. We could assume that having to write less code for the nth occurrence means being more efficient over the long term.</p>
<p>It’s rather more difficult to represent the on-boarding work required to be able to read or write the code the first time, which gets to the very appeal of the left end of the spectrum. For the sake of argument, I imagined an exponential increase in the time required to get a new developer on board: the minutes required to read docs, install and learn build tools, ask questions when things don’t work, etc.</p>
<p><img src="/static/20241020005925/images/blog/Graph of code size and onboard time.png" style="max-width: 100%;"></p>
<p>This representation doesn’t capture everything.</p>
<ul>
<li>This doesn’t reflect the very conditions that drove our solution away from the original, simplest solution. We imagined that the amount of boilerplate required for a class would grow in size, which would inflate the size of the solutions at the left end of the graph.</li>
<li>We also imagined having to write many more classes, which would multiply the code size required for all solutions.</li>
<li>There’s no representation of solution flexibility here. It’s unclear how that could be represented: perhaps an assessment across multiple classes at how much they differ from each other, and some subjective measure of how important those differences are to the success of the project. However we measure it, flexibility is higher on the left and lower on the right.</li>
</ul>
<p>This entire example is contrived, but surely there are correlations at work like this whenever we’re resolving the 1st time/nth time tension.</p>
<p>Significantly, that tension applies to reading and understanding code, not just writing and maintaining it. A solution at the left end of the spectrum might entail more code then one at the right end, but a new developer should be able to more readily understand what code at the left end does and how it actually works.</p>
<p>I think it’s interesting to consider this spectrum through some analytical lens. Surely we could take a more data-driven approach to assessing where we are — and deciding where we want to be — on this spectrum.</p>
<h2>Reflection</h2>
<p>Positions along this spectrum are not objectively good or bad — it depends on what you’re trying to achieve and optimize for.</p>
<p>In the case of the Elix project, we want to optimize for: a) a large audience of professional web developers that can quickly understand the code, and b) a high degree of flexibility. We want people to build a wide range of solutions with the project’s web components, so we prefer to preserve flexibility and possibly sacrifice nth time efficiency. In other words, we deliberately target the left end of this spectrum.</p>
<p>As a case in point, we recently <a href="https://github.com/elix/elix/releases/tag/11.0.0">deprecated an Elix helper function</a> that manipulated a web component template in a particular way. The helper allowed for efficiency, but was novel, and we ultimately felt that it wasn’t all that much more efficient than calling the underlying DOM API directly. We’d prefer to just encourage developers to call a DOM API they already know extremely well. We may someday feel that we understand the problem space better, and decide to better support nth time use by adding back such a helper, but for now we’re happy to keep the Elix code unsurprising.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Supporting both automatic and manual registration of custom elements</title>
      <pubDate>Mon, 07 Oct 2019 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/supporting-both-automatic-and-manual-registration-of-custom-elements</link>
      <guid>http://component.kitchen/blog/posts/supporting-both-automatic-and-manual-registration-of-custom-elements</guid>
      <description><![CDATA[
      <p>The latest <a href="http://component.kitchen/elix">Elix</a> 8.0 release now lets you control how the Elix components are registered as custom elements. This post provides a summary of the complex topic of registering elements, then describes how Elix 8.0 addresses those complexities.</p>
<h2>Background: Why you need to register components as custom elements</h2>
<p>The browser standard for <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements">Custom Elements</a> lets you create your own HTML elements in two steps: 1) create a class that inherits from <code>HTMLElement</code>, and 2) register that class with the browser using a unique tag name. You can then instantiate the class:</p>
<pre><code class="lang-js">class MyElement extends HTMLElement {}            // Step 1: create class
customElements.define(&#39;my-element&#39;, MyElement);   // Step 2: register class

const myElement = new MyElement();                // Ready for use
</code></pre>
<p>The registered tag name (above, <code>my-element</code>) gives the browser a way to represent instances of the element in the DOM, where all element nodes must have a tag (a.k.a. <code>localName</code>). That tag lets the browser know how it should represent the node in HTML representations, such as in the <code>innerHTML</code> of some containing element. The requirement that a class only gets registered <em>once</em> ensures a clear mapping from DOM to HTML.</p>
<p>That said, the fact that each class must be registered once — and only once — creates a burden for component users. It would be great if, instead, you could define components like the ones in the Elix library in one step:</p>
<pre><code class="lang-js">import Carousel from &#39;elix/src/Carousel.js&#39;;    // Import class
const carousel = new Carousel();                // Use class
</code></pre>
<p>but this will throw if the element class hasn’t been registered.</p>
<p><em>Aside: the thrown exception is &quot;Illegal constructor” in Chrome/Edge/Firefox, and &quot;new.target is not a valid custom element constructor” in Safari. I find both of those wordings to be extremely unhelpful. The problem has nothing to do with your constructor, but with your failure to invoke <code>customElements.define</code>. I don&#39;t hit that exception very often, but every time I do, I waste time looking for the problem in the wrong place before I finally remember why that exception occurs.</em></p>
<p>Registration can be particularly bothersome if you yourself instantiate components using only constructors. Most of the code we&#39;ve written that creates components happens to do so through their constructors. We&#39;re never actually using the components&#39; tags, so it&#39;s a chore to have to worry about them. We wish the browser would just generate a unique tag for any component class that&#39;s instantiated without registration. (Someone else has proposed support for <a href="https://github.com/w3c/webcomponents/issues/842">anonymous custom elements</a>, and while I think that proposal is very likely to be shot down, I&#39;ve come to think it would be nice to have.)</p>
<h2>Auto-registering component modules</h2>
<p>To avoid the hassle of registering every component, Elix components in releases prior to 8.0 followed a common auto-registration pattern. Each component class was defined in a separate JavaScript module; the default export of each module was the corresponding component class. When you imported one of those modules, you obtained a reference to that class and <em>as a side effect</em> that class was registered with the browser.</p>
<p>For example, the <code>Carousel</code> class in Elix 7.0 was defined in a module <code>/src/Carousel.js</code> that conceptually looked like this:</p>
<pre><code class="lang-js">// Define and export the class.
export default class Carousel extends HTMLElement { ... }

// Register the class as a side-effect.
customElements.define(&#39;elix-carousel&#39;, Carousel);
</code></pre>
<p>So if you imported that module like this:</p>
<pre><code class="lang-js">import Carousel from &#39;elix/src/Carousel.js&#39;;
</code></pre>
<p>the <code>import</code> would return the <a href="http://component.kitchen/elix/Carousel">Carousel</a> component class <em>and</em> as a side effect register the <code>Carousel</code> class with the tag <code>elix-carousel</code>.</p>
<p>That was rather convenient, especially as it let you load a module with a <code>script</code> tag and then immediately use that component entirely in HTML, without having to write any JavaScript:</p>
<pre><code class="lang-html">&lt;script type=&quot;module&quot; src=&quot;./node_modules/elix/src/Carousel.js&quot;&gt;&lt;/script&gt;
&lt;elix-carousel&gt;
  &lt;!-- Carousel items such as img elements go here. --&gt;
  &lt;img src=&quot;image1.jpg&quot;&gt;
  &lt;img src=&quot;image2.jpg&quot;&gt;
  &lt;img src=&quot;image3.jpg&quot;&gt;
&lt;/elix-carousel&gt;
</code></pre>
<h2>Problems with auto-registering components</h2>
<p>But while auto-registering components are convenient, they lead to some problems:</p>
<ol>
<li>It seems like a bad idea to have importing a module make changes to global state like the custom element registry. At the very least, it can be surprising.</li>
<li>Given a component module, there&#39;s currently no standard way of predicting what tag name will be used to register that component as a custom element. Likewise, given a defined component class, there&#39;s no way of asking the browser whether that class has already been registered and, if so, what tag was used to register it. (An <a href="https://github.com/w3c/webcomponents/issues/566">open issue</a> tracks whether a new API should be added to find out the tag which which a class was registered.)</li>
<li>Forcing the use of a specific tag name creates an undesirable point of entanglement between a project and a component. Imagine that you&#39;re working on the FooBar project and would like to use the Elix Carousel component. You&#39;d like the flexibility to swap out which carousel you&#39;re using at some later point in time. But if Elix Carousel registers itself as &quot;elix-carousel&quot;, then you need to bake that tag everywhere into your HTML. It&#39;s be better if you could register the Elix Carousel as &quot;foo-bar-carousel&quot;, and use <em>that</em> in your HTML so that you can more easily migrate between carousel implementations.</li>
<li>It doesn&#39;t allow multiple component versions to be loaded at the same time. People who work on big projects know that it can be extremely difficult to force every team to use the exact same version of a library. As a result, the lack of support for multiple versions can quickly become a deal-breaker for any UI component model. This is a particularly critical issue for small, general-purpose components (like buttons, combo boxes, and context menus) that might make their way into many larger components in a single big project.</li>
<li>It doesn&#39;t allow the same component to be used in multiple bundles. Even when two parts of your project are using the same component, it&#39;s possible that your project&#39;s bundling architecture will make it challenging to actually reference the same instance of the component module. If that module gets bundled into two different packages, they can&#39;t both be loaded. Arguably that just means you need a better bundling strategy, but it&#39;s nevertheless unfortunate that a limitation of the low-level <code>customElements</code> DOM API is forcing high-level constraints on how you build your application.</li>
</ol>
<p>One complicating factor with duplicate element registration is that there&#39;s bad locality of reference. Imagine you&#39;re working on a big project, and manage to trigger a situation in which a component is trying to register itself twice. The second attempt to register the class will throw an exception — but depending on the load order of the modules, that new code might happen to get loaded <em>first</em>. If that happens, the exception will be thrown by the <em>old</em> code when it tries to load later. That&#39;s really surprising! “This old code worked fine before. I changed something else far away in this new file, and yet I somehow managed to break the previously-working old code.”</p>
<h2>Anticipating scoped custom element registries</h2>
<p>The proposal for <a href="https://github.com/w3c/webcomponents/issues/716">scoped custom element registries</a> will let you register a class with a tag that&#39;s local to your own code. That will definitely be a huge help for the versioning/bundling conflicts described above.</p>
<p>When that feature arrives, auto-registering components could be a minor nuisance, because an auto-registered component might get registered <em>twice</em>: once when the module auto-registers in the global custom element namespace, and a second time when your code registers the class in a scoped custom element registry. If you consistently use scoped registries, registrations in the global registry are unnecessary, and just present an opportunity for potential problems.</p>
<p>If a component library like Elix wants to be ready for scoped custom element registries, it&#39;s worth figuring out how to move away from having all components auto-register themselves.</p>
<h2>Elix component modules, now in two flavors: normal and auto-registering</h2>
<p>Given the wide variety of situations and architectures in which web components may be useful, Elix 8.0 supports both the convenience of auto-registration and the freedom to control registration yourself. To this end, all Elix component modules now come in <strong>two</strong> flavors:</p>
<ul>
<li>The modules in the project&#39;s <code>/src</code> folder now only export a component class, and do <em>not</em> register that class as a custom element. You have to register it yourself. These <code>/src</code> modules are intended for use in apps that have some complexity, and where you want complete control over your components.</li>
<li>The modules in the project&#39;s new <code>/define</code> folder export the corresponding class <em>and</em> register that class as a custom element. Example: <code>elix/define/Carousel.js</code> exports the <code>Carousel</code> class and registers it with the tag <code>elix-carousel</code>. The tag name is always the prefix <code>elix-</code> followed by the class name in kebab case, so <code>ComboBox</code> becomes <code>elix-combo-box</code>. These <code>/define</code> modules are a convenient way to use components in straightforward apps where you&#39;re more concerned about getting things done than having complete control, and the constraints of auto-registration are acceptable.</li>
</ul>
<p>This is, unfortunately, a breaking change for people that use Elix components in their projects. Generally speaking, if they want to preserve the previous auto-registering behavior, they need to replace <code>/src</code> in their component <code>import</code> paths with <code>/define</code>. The other modules in the library — for the extensive set of component mixins and helpers — aren&#39;t implicated in component registration, so still exist only in the <code>/src</code> folder as before. If you are migrating an Elix project, see the <a href="https://github.com/elix/elix/releases/tag/8.0.0">release notes</a> for details on migrating to 8.0.</p>
<p>Likewise, the pure HTML use of an Elix component should now reference the <code>/define</code> modules, like so:</p>
<pre><code class="lang-html">&lt;script type=&quot;module&quot; src=&quot;./node_modules/elix/define/Carousel.js&quot;&gt;&lt;/script&gt;
&lt;elix-carousel&gt;
  &lt;!-- Carousel items such as img elements go here. --&gt;
&lt;/elix-carousel&gt;
</code></pre>
<p>These <code>/define</code> modules each simply import the corresponding <code>/src</code> module, derive a trivial subclass, export that, and register it. So the source for <code>/define/Carousel.js</code> is:</p>
<pre><code class="lang-js">import Carousel from &#39;../src/Carousel.js&#39;;
export default class ElixCarousel extends Carousel {}
customElements.define(&#39;elix-carousel&#39;, ElixCarousel);
</code></pre>
<p>Why does this code derive a trivial subclass before registering it? Read on...</p>
<h2>Registering components with your own custom element tag names</h2>
<p>In any case where you are importing a component from a module, it seems like a good practice to <em>not</em> assume you are the only one who will ever want to register that component. If you try to do the obvious thing:</p>
<pre><code class="lang-js">// Naive approach
import Carousel from &#39;elix/src/Carousel.js&#39;;
customElements.define(&#39;my-carousel&#39;, Carousel);
</code></pre>
<p>that will run — but then you are effectively declaring that you will always be the only one who will ever want to register that class.</p>
<p>That assumption could someday cause problems. If someone working in a different part of your project (or maybe you yourself, later) also tries to register <code>Carousel</code> as a component class, then one of you will lose the registration race, and end up trying to register a class that&#39;s already been registered. As noted earlier, that will throw an exception whose poor locality of reference may make it hard to diagnose.</p>
<p>So a reasonable defensive pattern might be to always define a trivial subclass and register that:</p>
<pre><code class="lang-js">// Defensive approach, lets other people register Carousel too
import Carousel from &#39;elix/src/Carousel.js&#39;;
class MyCarousel extends Carousel {}
customElements.define(&#39;my-carousel&#39;, MyCarousel);
</code></pre>
<p>If you compare this with the code in the previous section, you&#39;ll see this is, in fact, the technique used by the Elix auto-registering components. That means you can decide to register the Elix <code>Carousel</code> as <code>my-carousel</code> <em>and</em> still let someone else import the <code>elix-carousel</code> auto-registering component from the Elix <code>/define</code> folder. Since both are registering trivial subclasses, those two subclasses can be registered in the global custom element registry without triggering exceptions.</p>
<p>If everyone on your project does the same with the components they import, you should always be able register a custom element class using the tag name you want.</p>
<p>We can use the same technique to load different versions of the same Elix component. We&#39;ve posted a <a href="https://github.com/elix/multiple-version-example">sample</a> showing an Elix 7.0 component and an Elix 8.0 component running side-by-side.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Hiding internal framework methods and properties from web component APIs</title>
      <pubDate>Mon, 16 Sep 2019 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/hiding-internal-framework-methods-and-properties-from-web-component-apis</link>
      <guid>http://component.kitchen/blog/posts/hiding-internal-framework-methods-and-properties-from-web-component-apis</guid>
      <description><![CDATA[
      <p>We&#39;ve made breaking changes in the new <a href="http://component.kitchen/elix">Elix 7.0.0</a> to solidify our component APIs. Specifically, our components no longer expose internal methods or properties with string names.</p>
<p>As usual, we&#39;re much less concerned with promoting our own library as a general-purpose component framework than we are in delivering great web components. We&#39;re documenting the thinking behind this change in this post for the benefit of anyone creating components with an eye towards reusability outside their organization.</p>
<h2>A component&#39;s framework should be an invisible implementation detail</h2>
<p>We try to write all our components so that they conform to a high quality bar. We use the native HTML elements as a reference point to measure how robust and flexible our components should be. We call that approach the <a href="https://github.com/webcomponents/gold-standard/wiki">Gold Standard checklist for web components</a>.</p>
<p>To meet that standard, we&#39;ve concluded that it&#39;s important for a web component to expose only its officially supported public API. That&#39;s what the native HTML elements do! So that&#39;s what we want to do too.</p>
<p>But like most web component frameworks today, Elix components previously exposed a number of internal methods like <code>render</code> and internal properties like <code>state</code>. Virtually all component libraries today do the same thing, exposing a substantial number of methods and properties which are only ever intended to be invoked internally.</p>
<p>In hindsight, exposing framework internals that way (even prefixed with an underscore, etc.) seems like a bad idea:</p>
<ol>
<li>Component users might decide to hack around component limitations by directly invoking internal methods or properties. The framework implicitly becomes part of the component&#39;s public API, whether or not that&#39;s what the component authors intended.</li>
<li>The framework used to create a component should be an invisible implementation detail. If a component author decides to someday change the framework in which they create a given component, they should be able to do so without any fear that they&#39;re going to break someone who — rightly or wrongly — decided to depend on inadvertently-exposed component internals.</li>
<li>Exposing framework details makes a custom element feel kludgey compared to native HTML elements. This is a softer issue, but might nevertheless contribute to a lack of confidence in the quality of a component. If native elements don&#39;t expose their details, we don&#39;t want our components to do that either.</li>
</ol>
<p>Deliberately exposing only those members that belong in the public API is good practice for any library. To date, the fact that component authors haven&#39;t worried about exposing framework internals most likely indicates that authors have been primarily focused on using their own components than on sharing them. But if web components are to find general reuse in a wide audience, authors should carefully review exactly what is visible in a component&#39;s public API.</p>
<h2>Hardening our component APIs</h2>
<p>With the above in mind, we&#39;ve made breaking changes in Elix to better hide all internal methods and properties.</p>
<p>Elix has long used <code>Symbol</code> keys instead of strings to identify various internal members that one mixin or class may need to invoke in another mixin or class. Using symbols that way hides those methods and properties from the debug console&#39;s auto-complete list. Those symbols are still accessible via <code>Object.getOwnPropertySymbols</code>, but someone has to work harder to do that. Symbols also avoid potential name conflicts if a component user wants to extend a custom element with their own data or methods.</p>
<p>We&#39;re expanding this use of <code>Symbol</code> keys to better hide all methods and properties which are meant for internal use only.</p>
<ul>
<li>All internal operations, like the <code>setState</code> or <code>render</code> methods, and the <code>state</code> property, are now behind symbols.</li>
<li>We&#39;ve renamed our collection of <code>Symbol</code> keys from <code>symbols.js</code> (which focused on the data type) to <code>internal.js</code> (which focuses on the intended purpose). So an element accesses its <code>state</code> via <code>this[internal.state]</code>.</li>
<li>We&#39;ve renamed our shorthand function that looks up shadow elements by ID. Previously, you could write <code>this.$.foo</code> to get a reference to a shadow element with the ID &quot;foo&quot;. The equivalent new code is <code>this[internal.ids].foo</code>.</li>
</ul>
<p>A simple example component in Elix 6.0 and earlier exposed some component internals with string names:</p>
<pre><code class="lang-js">import * as symbols from &#39;elix/src/symbols.js&#39;;
import * as template from &#39;elix/src/template.js&#39;;
import ReactiveElement from &#39;elix/src/ReactiveElement.js&#39;;

// Create a native web component with reactive behavior.
class IncrementDecrement extends ReactiveElement {

  componentDidMount() {
    super.componentDidMount();
    this.$.decrement.addEventListener(&#39;click&#39;, () =&gt; {
      this.value--;
    });
    this.$.increment.addEventListener(&#39;click&#39;, () =&gt; {
      this.value++;
    });
  }

  // This property becomes the value of this.state at constructor time.
  get defaultState() {
    return Object.assign(super.defaultState, {
      value: 0
    });
  }

  // Render the current state to the DOM.
  [symbols.render](changed) {
    super[symbols.render](changed);
    if (changed.value) {
      this.$.value.textContent = this.state.value;
    }
  }

  // This template is cloned to create the shadow tree for a new element.
  get [symbols.template]() {
    return template.html`
      &lt;button id=&quot;decrement&quot;&gt;-&lt;/button&gt;
      &lt;span id=&quot;value&quot;&gt;&lt;/span&gt;
      &lt;button id=&quot;increment&quot;&gt;+&lt;/button&gt;
    `;
  }

  // Provide a public property that gets/sets state.
  get value() {
    return this.state.value;
  }
  set value(value) {
    this.setState({ value });
  }

}
</code></pre>
<p>In Elix 7.0, all internals are now identified with <code>Symbol</code> keys obtained from <code>internal.js</code>, so the above example now looks like:</p>
<pre><code class="lang-js">import * as internal from &#39;elix/src/internal.js&#39;;
import * as template from &#39;elix/src/template.js&#39;;
import ReactiveElement from &#39;elix/src/ReactiveElement.js&#39;;

// Create a native web component with reactive behavior.
class IncrementDecrement extends ReactiveElement {

  [internal.componentDidMount]() {
    super[internal.componentDidMount]();
    this[internal.ids].decrement.addEventListener(&#39;click&#39;, () =&gt; {
      this.value--;
    });
    this[internal.ids].increment.addEventListener(&#39;click&#39;, () =&gt; {
      this.value++;
    });
  }

  // This sets the component&#39;s initial state at constructor time.
  get [internal.defaultState]() {
    return Object.assign(super[internal.defaultState], {
      value: 0
    });
  }

  // Render the current state to the DOM.
  [internal.render](changed) {
    super[internal.render](changed);
    if (changed.value) {
      this[internal.ids].value.textContent = this[internal.state].value;
    }
  }

  // This template is cloned to create the shadow tree for a new element.
  get [internal.template]() {
    return template.html`
      &lt;button id=&quot;decrement&quot;&gt;-&lt;/button&gt;
      &lt;span id=&quot;value&quot;&gt;&lt;/span&gt;
      &lt;button id=&quot;increment&quot;&gt;+&lt;/button&gt;
    `;
  }

  // Provide a public property that gets/sets state.
  get value() {
    return this[internal.state].value;
  }
  set value(value) {
    this[internal.setState]({ value });
  }

}
</code></pre>
<p>In addition to better hiding component implementation details, we really like that the above class definition makes clear that the component has only <em>one</em> public member: the <code>value</code> property. Everything else is an implementation detail of interest to the component author only.</p>
<p>Even though JavaScript engines are gaining support for private methods and properties, we can&#39;t use those for our purposes, because private members are only accessible within the class that defines them. We need a mixin or class somewhere along the class hierarchy to be able to invoke a member defined elsewhere along the hierarchy. In other words, what we really want are <code>protected</code> members, but those aren&#39;t coming to JavaScript soon, if ever.</p>
<h2>Debugging</h2>
<p>Since state is an internal matter, a component&#39;s state is now hidden behind a <code>Symbol</code>. By design, that makes it much harder to access! But when debugging, it&#39;s really helpful to be able to inspect component state easily.</p>
<p>To facilitate debugging, Elix now looks to see if the current page has a URL parameter, <code>elixdebug=true</code>. If found, then Elix components will expose a string-valued <code>state</code> property as before. If the page is opened without that parameter, the <code>state</code> property disappears again.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Should the Elix project maintain React versions of its general-purpose UI components?</title>
      <pubDate>Mon, 10 Jun 2019 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/should-the-elix-project-maintain-react-versions-of-its-general-purpose-ui-components</link>
      <guid>http://component.kitchen/blog/posts/should-the-elix-project-maintain-react-versions-of-its-general-purpose-ui-components</guid>
      <description><![CDATA[
      <p>We&#39;ve been looking at how to make the <a href="http://component.kitchen/elix">Elix web component library</a> easier to use in a React application. We recently posted a <a href="https://github.com/elix/react-example">React example</a> to show using an Elix web component in a simple React app, but we can do more.</p>
<h1>HTML custom elements don&#39;t feel quite at home in React today</h1>
<p>As noted on <a href="https://custom-elements-everywhere.com/#react">Custom Elements Everywhere</a>, React currently has some well-known issues interacting with custom elements:</p>
<ul>
<li>Properties passed to HTML elements, including custom elements, get passed as strings. This makes it hard to pass complex properties like objects and arrays.</li>
<li>Listening to events raised by custom elements requires a somewhat awkward workaround.</li>
</ul>
<p>Based on our experience, I&#39;d also add a third issue:</p>
<ul>
<li>Custom elements have to be referenced by their string tag name. E.g., the Elix <a href="https://component.kitchen/elix/Carousel">Carousel</a> must be referenced as the string <code>elix-carousel</code> instead of the class <code>Carousel</code>.</li>
</ul>
<p>That&#39;s unfortunate. React components are referenced by class, and the inability to do the same with custom element classes makes them feel alien in the context of React. It also makes it harder to do proper linting and type-checking.</p>
<p>To use a web component in React today, you do something like the following:</p>
<pre><code class="lang-jsx">// In custom-element.js
export default class MyCustomElement extends HTMLElement {}
customElements.define(&#39;my-custom-element&#39;, MyCustomElement);

// In app.jsx
import React from &#39;react&#39;;
import MyCustomElement from &#39;./custom-element.js&#39;;

class App extends React.Component {
  render() {
    return &lt;my-custom-element&gt;&lt;/my-custom-element&gt;;
  }
}
</code></pre>
<p>The <code>import MyCustomElement</code> statement will generate a lint error complaining that <code>MyCustomElement</code> is unused, because it can&#39;t know that the string name <code>my-custom-element</code> is an indirect reference to the <code>MyCustomElement</code> class.</p>
<p>You could suppress the error by dropping the class name from the import:</p>
<pre><code class="lang-jsx">import &#39;./custom-element.js&#39;;
</code></pre>
<p>But that simply masks the problem: there&#39;s no type-safe way to confirm the JavaScript code in the React app is interacting correctly with the custom element class.</p>
<p>It&#39;d be preferable to refer to HTML custom elements by class just like one can with React component classes. Specifically, it&#39;d be nice if JSX and the underlying <code>React.createElement</code> could be extended to accept any subclass of the standard <code>HTMLElement</code> base class:</p>
<pre><code class="lang-jsx">// In custom-element.js
export default class MyCustomElement extends HTMLElement {}
customElements.define(&#39;my-custom-element&#39;, MyCustomElement);

// In app.jsx
import React from &#39;react&#39;;
import MyCustomElement from &#39;./custom-element.js&#39;;

class App extends React.Component {
  render() {
    return &lt;MyCustomElement&gt;&lt;/MyCustomElement&gt;; // This would be nice!
  }
}
</code></pre>
<p>This would open up type safety and the attendant edit-time benefits of features like auto-complete and inline documentation.</p>
<h1>Trying out React versions of the Elix web components</h1>
<p>In the meantime, we&#39;re considering maintaining <a href="https://github.com/elix/elix-react">React versions of the Elix web components</a> that address some of the interop issues mentioned above. They let you listen to custom events raised by an Elix component using the standard React <code>on</code> syntax. They also let you set properties using React-standard camelCase property names instead of hyphenated attribute names. (However, properties still only accept types that can be coerced to and from strings.)</p>
<p>Example:</p>
<pre><code class="lang-jsx">import React from &#39;react&#39;;
import ListBox from &#39;elix-react/src/ListBox.jsx&#39;;

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      selectedIndex: 0
    };
    this.selectedIndexChanged = this.selectedIndexChanged.bind(this);
  }

  render() {
    return (
      &lt;ListBox
        onSelectedIndexChanged={this.selectedIndexChanged}
        selectedIndex={this.state.selectedIndex}
      &gt;&lt;/ListBox&gt;
    );
  }

  selectedIndexChanged(detail) {
    const { selectedIndex } = detail;
    this.setState({ selectedIndex });
  }

}
</code></pre>
<p>Here&#39;s a simple <a href="https://elix.github.io/elix-react/demos/listAndCarousel.html">demo of a React app using the React Elix components</a>. This shows a React version of an Elix <a href="http://component.kitchen/elix/ListBox">ListBox</a> synchronized with an Elix <a href="http://component.kitchen/elix/Carousel">Carousel</a>.</p>
<p>As with the regular Elix web components, the React versions provide full keyboard, mouse, touch, and trackpad support, plus ARIA accessibility.</p>
<p>We&#39;re trying to decide if we should maintain the React versions of the Elix components on an ongoing basis. If that would be interesting to you, please tweet to the Elix project at <a href="https://twitter.com/ElixElements">@ElixElements</a>.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>A simple state-based recalc engine for web components</title>
      <pubDate>Tue, 28 May 2019 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/a-simple-state-based-recalc-engine-for-web-components</link>
      <guid>http://component.kitchen/blog/posts/a-simple-state-based-recalc-engine-for-web-components</guid>
      <description><![CDATA[
      <p>We recently released <a href="https://github.com/elix/elix/releases/tag/6.0.0">Elix 6.0</a>. This includes a simple state-based recalc engine that lets our components know what they should update when their internal state changes.</p>
<p>We were inspired by Rich Harris&#39; <a href="https://www.youtube.com/watch?v=AdNJ3fydeao">Rethinking Reactivity</a> talk on version 3 of the <a href="https://svelte.dev/">Svelte</a> framework, which advances the idea of building user interface components upon a spreadsheet-like recalc engine. Significantly, the recalc engine supports forward references — when one piece of data changes, the engine can efficiently determine what else must be recalculated. Svelte entails a complete toolchain that we&#39;re not ready to adopt, but we like the idea of recalc as a useful service for web components.</p>
<p>As it turns out, Elix already had much of what we need to build a recalc engine, and it was relatively straightforward to expand that to form a new core for our Elix components. We worked this into a core Elix mixin called <a href="http://component.kitchen/elix/ReactiveMixin">ReactiveMixin</a>, which can now let a component know exactly what state has actually changed since the last render. This in turn lets the component efficiently decide what it needs to update in the DOM.</p>
<h2>The smallest amount of framework we can get away with</h2>
<p>As we&#39;ve noted before, it&#39;s <a href="http://component.kitchen/blog/posts/nobody-writes-production-web-components-in-vanilla-js-so-using-a-framework-makes-total-sense">not practical to write a production component library without any shared code</a>. Writing web components requires enough boilerplate that most people end up using a framework, even if it&#39;s just a tiny framework they wrote themselves.</p>
<p>Elix has had to develop its own core library so that we can create reliable, polished, general-purpose web components. Our framework happens to be composed of JavaScript mixins. We don&#39;t particularly care to push this framework on other people, but we do discuss it from time to time in case the work we&#39;ve done can help write their own framework-level code better.</p>
<p>We only ask a few things of our framework:</p>
<ul>
<li><strong>Support a functional-reactive programming model.</strong> We want to represent a component&#39;s current state with a single immutable state object. When a request is made to change the state, the component should be told to render that new state to the DOM. This is handled by <a href="http://component.kitchen/elix/ReactiveMixin">ReactiveMixin</a>. This is the part of our framework that now contains a small recalc engine.</li>
<li><strong>Populate a Shadow DOM tree with an HTML template.</strong> A template is a convenient way to express a component&#39;s subelements, and copying a template into a shadow tree is handled by <a href="http://component.kitchen/elix/ShadowTemplateMixin">ShadowTemplateMixin</a>.</li>
<li><strong>Let HTML authors set HTML attributes on our components.</strong> When a <code>foo-bar</code> attribute is set, we want to invoke a corresponding <code>fooBar</code> property setter. That&#39;s the job of <a href="http://component.kitchen/elix/AttributeMarshallingMixin">AttributeMarshallingMixin</a>.</li>
</ul>
<p>The second and third things are boring but necessary; the first part is the only interesting bit. For convenience, all three of these mixins are bundled together in a base class, <a href="http://component.kitchen/elix/ReactiveElement">ReactiveElement</a>. But each piece is usable separately.</p>
<h2>Example</h2>
<p>A simple increment/decrement web component in Elix 6.0 looks like this:</p>
<pre><code class="lang-js">import { ReactiveElement, symbols, template } from &quot;elix&quot;;

class IncrementDecrement extends ReactiveElement {

  componentDidMount() {
    super.componentDidMount();
    this.$.decrement.addEventListener(&#39;click&#39;, () =&gt; {
      this.value--;
    });
    this.$.increment.addEventListener(&#39;click&#39;, () =&gt; {
      this.value++;
    });
  }

  // This property becomes the value of this.state at constructor time.
  get defaultState() {
    return Object.assign(super.defaultState, {
      value: 0
    });
  }

  // Render the current state to the DOM.
  [symbols.render](changed) {
    super[symbols.render](changed);
    if (changed.value) {
      this.$.valueSpan.textContent = this.state.value;
    }
  }

  // Define the initial contents of the component&#39;s Shadow DOM subtree.
  get [symbols.template]() {
    return template.html`
      &lt;button id=&quot;decrement&quot;&gt;-&lt;/button&gt;
      &lt;span id=&quot;valueSpan&quot;&gt;&lt;/span&gt;
      &lt;button id=&quot;increment&quot;&gt;+&lt;/button&gt;
    `;
  }

  // Provide a public property that gets/sets the value state.
  // If an HTML author sets a &quot;value&quot; attribute, it will invoke this setter.
  get value() {
    return this.state.value;
  }
  set value(value) {
    this.setState({ value });
  }

}
</code></pre>
<p><a href="http://component.kitchen/demos/reactiveElementExample.html">Live demo</a></p>
<p>The interesting new bit in Elix 6.0 shows up in the method identified by <code>symbols.render</code>. That method is invoked when the component&#39;s state changes. (Aside: We identify internal methods with <code>Symbol</code> instances to avoid name collisions with other component code.)</p>
<p>The render method now gets a parameter, <code>changed</code>, that has Boolean values indicating which state members have changed since the last render. If <code>changed.value</code> is true, then <code>this.state.value</code> contains a new value, so the render method knows it should display the new value in the DOM as the span&#39;s <code>textContent</code>.</p>
<h2>Computed state</h2>
<p>In simple cases, a computed property can be recalculated each time it&#39;s requested. But a number of Elix components have computed state that is expensive to recalculate. In those cases, we can define a rule in our recalc engine that indicates how to recalculate a given state member when other state members change.</p>
<p>A toy example might look like:</p>
<pre><code class="lang-js">class TestElement extends ReactiveMixin(HTMLElement) {

  get defaultState() {
    const result = Object.assign(super.defaultState, {
      a: 0
    });

    // When state.a changes, set state.b to be equal to state.a + 1
    result.onChange(&#39;a&#39;, state =&gt; ({
      b: state.a + 1
    }));

    return result;
  }

}
</code></pre>
<p>The <code>onChange</code> handler is associated with the component&#39;s state object, and runs whenever <code>state.a</code> changes. That handler returns an object containing any computed updates that should be applied to the state. Here it returns an object with a new value for <code>state.b</code>.</p>
<p>A more realistic example comes up in <a href="http://component.kitchen/elix/SingleSelectionMixin">SingleSelectionMixin</a>, which maintains a <code>selectedIndex</code> state member used to track which item in a list of <code>items</code> is currently selected. If the <code>items</code> array changes, we want to ensure that the <code>selectedIndex</code> state still falls with the bounds of that array.</p>
<pre><code class="lang-js">function SingleSelectionMixin(Base) {
  return class SingleSelection extends Base {

    get defaultState() {
      const state = Object.assign(super.defaultState, {
        selectedIndex: -1
      });

      // Ask to be notified when state.items changes.
      result.onChange(&#39;items&#39;, state =&gt; {
        // Force selectedIndex state within the bounds of -1 (no selection)
        // to the length of items - 1.
        const { items, selectedIndex } = state;
        const length = items.length;
        const boundedIndex = Math.max(Math.min(selectedIndex, length-1), -1);
        return {
          selectedIndex: boundedIndex
        };
      });

      return result;
    }

  };
}
</code></pre>
<p>Defining a rule like this to keep an index within bounds is an important ingredient in allowing us to factor our complex components into constituent mixins. It lets one mixin or class update an aspect of state without having to know about all the secondary effects that will have.</p>
<p>You can see this recalculation of state in action if you open a demo like the one for <a href="http://component.kitchen/demos/carousel.html">Carousel</a> and invoke the debug console. If you use the debugger to remove one of the carousel&#39;s images from the DOM, the <code>Carousel</code> will recalculate which item should now be selected. If the last image is selected in the carousel and you remove that image, the above code will ensure that the <em>new</em> last image becomes the selected one.</p>
<p>This isn&#39;t just an abstract experiment. This kind of resiliency is called for in the Gold Standard Checklist for Web Components criteria for <a href="https://github.com/webcomponents/gold-standard/wiki/Content-Changes">Content Changes</a>. Such resiliency is exactly the kind of quality that custom elements will need to deliver to be as reliable and flexible as the native HTML elements. The simple recalc engine in our Elix 6.0 core makes it easier for us to deliver that level of quality.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>A history of the HTML slot element</title>
      <pubDate>Mon, 08 Apr 2019 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/a-history-of-the-html-slot-element</link>
      <guid>http://component.kitchen/blog/posts/a-history-of-the-html-slot-element</guid>
      <description><![CDATA[
      <p>To me, the story behind the standard HTML 
<a href="https://www.google.com/url?q=https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot&amp;sa=D&amp;ust=1554399746448000"><code>&lt;slot&gt;</code></a>
element illustrates the complexity of producing standards, the importance of talking with people face-to-face, and the value of compromise.</p>
<p>Like any standard, the <code>&lt;slot&gt;</code> element didn’t just appear out of thin air. It emerged out of a contentious discussion in which people fought hard for the position they thought was best. In the particular case of that element, it’s possible that a fairly small point of disagreement might have prevented the larger web components technology from reaching the level of support it now has.</p>
<p>I wanted to write down some of that <code>&lt;slot&gt;</code> history while I can still recall or reconstruct the details and much of the original content is still publicly visible. This is just my perspective on the events. The other people involved surely recall the events differently, but I’ve done my best to be as objective, complete, and accurate as I can.</p>
<h2>2011: Shadow DOM v0 and <code>&lt;content&gt;</code></h2>
<p>As I understand it, people at Google including Dimitri Glazkov and Alex Russell began drafting the ideas that became known as web components in 2010 and early 2011. In various posts during 2010–11 on the
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/&amp;sa=D&amp;ust=1554399746450000">W3C public-webapps mailing list</a>,
Dimitri laid out early thinking on web components. He summarized the state of that work in a January 2011 blog post,
<a href="https://www.google.com/url?q=https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/&amp;sa=D&amp;ust=1554399746450000">What the Heck is Shadow DOM?</a></p>
<p>At the end of the year, Dimitri posted an updated summary,
<a href="https://www.google.com/url?q=http://web.archive.org/web/20111217001628/https://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html%23shadow-dom-section&amp;sa=D&amp;ust=1554399746450000">Web Components Explained</a>.
That summary roughly describes what eventually became known as Shadow DOM v0, which includes several key differences from the final Shadow DOM v1 standard. Among those differences was a proposed
<a href="https://www.google.com/url?q=https://developer.mozilla.org/en-US/docs/Web/HTML/Element/content&amp;sa=D&amp;ust=1554399746451000"><code>&lt;content&gt;</code></a>
element for indicating where light DOM nodes should rendered inside a shadow tree and which nodes should be rendered.</p>
<p>Example: if an element has a Shadow DOM tree that contains</p>
<pre><code class="lang-html">Hello, &lt;content&gt;&lt;/content&gt;!
</code></pre>
<p>and that element’s <em>light</em> DOM content is the text “world”, then what the user sees is</p>
<pre><code>Hello, world!
</code></pre><p>The proposed definition of the <code>&lt;content&gt;</code> element allowed the developer to specify which light DOM nodes should be included by using a CSS selector:</p>
<pre><code class="lang-html">&lt;content select=&quot;img&quot;&gt;&lt;/content&gt;
</code></pre>
<p>The above would arrange for that <code>&lt;content&gt;</code> element to show the <code>&lt;img&gt;</code> elements in the light DOM.</p>
<p>Google 
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2011AprJun/1345.html&amp;sa=D&amp;ust=1554399746453000">landed experimental Shadow DOM v0 support</a>
in Chrome around June 2011, including support for <code>&lt;content&gt;</code>.</p>
<p>The strongest reaction to Google’s early web component proposals came from Apple. Apple’s Maciej Stachowiak
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2011AprJun/1364.html&amp;sa=D&amp;ust=1554399746454000">posted</a>
several objections to the API, including that the API didn’t provide robust encapsulation. Later posts from Maciej indicate support for the general idea of Shadow DOM, but not the v0 API.</p>
<h2>2012</h2>
<p>I first came across web components in early 2012, and wrote a
<a href="https://www.google.com/url?q=https://miksovsky.blogs.com/flowstate/2012/03/snapping-together-a-skyscraper.html&amp;sa=D&amp;ust=1554399746455000">blog post about web components</a>
that March. At the time, I was working on an open source component library based on jQuery, and was excited by the prospect of a native UI component model for the web.</p>
<p>On the other hand, I was concerned it might take a long time for web components to reach broad adoption across the major browsers. By 2012, the iPhone had become a major point of access to the web, and it was not clear whether Apple would ever implement support for Shadow DOM v0. Shadow DOM was already proving extremely difficult to polyfill. Without native Shadow DOM available on Mobile Safari, developers might avoid the technology altogether, and it might never take off.</p>
<p>Google’s strategy seemed to be: once web developers discovered the benefits of using web components in Google Chrome, those developers would pressure Apple to support the technology too. It’s impossible to say whether that strategy would have worked. We can note that Apple has declined to implement other web standards (e.g., web animations), and those decisions have almost certainly dissuaded developers from adopting those technologies. <em>[Note added on April 22, 2019: Apple did release initial production support for web animations last month in Safari 12.1.]</em></p>
<p>I had my own misgivings about the initial Shadow DOM design, particularly that
<a href="https://www.google.com/url?q=https://blog.quickui.org/2012/07/02/web-component-properties/&amp;sa=D&amp;ust=1554399746456000">CSS selectors might be poorly suited for selecting light DOM nodes</a>:</p>
<blockquote>
<p><em>The tool given to the developer for [selecting light DOM nodes] is CSS selectors, which at first glance seems powerful. Unfortunately, it’s also a recipe for inconsistency. Every developer will have the freedom—and chore—to approach this problem their own way, guaranteeing the emergence of a handful of different strategies, plus a number of truly bizarre solutions. …</em></p>
<p><em>It’s as if you were programming in a system where functions could only accept a single array. As it turns out, we already have a good, common example of such a system: command line applications. … [Using CSS selectors] leaves devs without a consistent way to refer to component properties by name, thereby leaving the door wide open for inconsistency.</em></p>
</blockquote>
<p>Instead, I was hoping that the spec could be modified to support named insertion points to which light DOM nodes could be assigned by name.</p>
<h2>2013: Apple concerns about complexity/performance</h2>
<p>Apple posts from spring 2013 show <a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0387.html&amp;sa=D&amp;ust=1554399746458000">concerns about the complexity of the Shadow DOM API</a>. Tess O’Connor from Apple wrote:</p>
<blockquote>
<p><em>While I&#39;m very enthusiastic about Shadow DOM in the abstract, I think things have gotten really complex, and I&#39;d like to seriously propose that we simplify the feature for 1.0, and defer some complexity to the next level… I think we can address most of the use cases of shadow DOM while seriously reducing the complexity of the feature by making one change: What if we only allowed one insertion point in the shadow DOM?</em></p>
</blockquote>
<p>Tess is saying that, if a shadow tree could only have one <code>&lt;content&gt;</code> element, there’d be no need to support CSS selectors on it. That would make it much easier for Apple and other vendors to implement and ship Shadow DOM. That in turn would let the browser vendors gain feedback from early adopters before attempting to add more complex features.</p>
<p>Tess’ comments were echoed by Apple colleague Ryosuke Niwa, who voiced
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2013AprJun/0470.html&amp;sa=D&amp;ust=1554399746460000">concerns about the performance</a>
of a <code>&lt;content&gt;</code> element with CSS selectors. In later conversations with me, Ryosuke also spoke of his desire to avoid adding unnecessary complications to HTML and the DOM, because such broadly-supported specs dictate that any complexity has to be supported for the rest of time. He referenced this reluctance in the linked post:</p>
<blockquote>
<p><em>I don&#39;t want to introduce a feature that imposes such a high maintenance cost without knowing for sure that they&#39;re absolutely necessary.</em></p>
</blockquote>
<p>In 2013, I was investing my own time in an
<a href="https://www.google.com/url?q=https://github.com/janmiksovsky/quetzal&amp;sa=D&amp;ust=1554399746461000">experimental library of general-purpose web components</a>.
Those experiments revealed some limitations of the <code>&lt;content&gt;</code> element, such as
<a href="https://www.google.com/url?q=https://blog.quickui.org/2013/06/11/puzzle-define-html-custom-element-subclasses-that-can-fill-in-base-class-insertion-points/&amp;sa=D&amp;ust=1554399746461000">challenges subclassing web components</a>.
By that point, I was using the term
<a href="https://www.google.com/url?q=https://blog.quickui.org/2013/11/08/filling-slots-in-shadow/&amp;sa=D&amp;ust=1554399746461000">“slot” as a friendlier-sounding synonym</a> for the spec’s use of “insertion point”.</p>
<h2>2014</h2>
<p>Ryosuke, it turned out, was also interested in
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2014AprJun/0151.html&amp;sa=D&amp;ust=1554399746462000">supporting subclassing web components</a>.
Towards that end, he also thought it would be useful for a web component class to identify insertion points by name. That would make it easier for a subclass to override or extend what appeared in that insertion point. Overall, he was keenly interested in simplifying the Shadow DOM specification, e.g., by dropping support for multiple shadow roots on a single element.</p>
<p>For these reasons and others, Apple continued to show little interest in implementing Shadow DOM v0 in WebKit.</p>
<h2>2015: Shuttle diplomacy</h2>
<p>While Google was moving towards shipping Shadow DOM v0 in production Chrome, Apple remained adamant about not supporting that spec. Ryosuke described the situation this way: “Shadow DOM as currently spec&#39;ed is broken and won&#39;t adequately address the use cases we care about.”</p>
<p>From the outside, Google and Apple both seemed to be talking at each other without much progress. This impasse concerned me, because I was hoping to use web components as the basis for a component-oriented consulting practice at my startup,
<a href="https://www.google.com/url?q=https://component.kitchen&amp;sa=D&amp;ust=1554399746464000">Component Kitchen</a>.</p>
<p>At the same time, I felt there was room for a compromise that would reduce the complexity that concerned Apple, while still allowing Google to achieve much of its original vision.</p>
<p>The W3C WebApps working group was scheduled to hold a F2F (Face-to-Face meeting) in Mountain View, CA, on April 24. To me that meeting seemed like a good opportunity to make a compromise, and I wanted to do what I could to make that happen.</p>
<p>I began to wonder if conducting Shadow DOM discussions mostly online was reducing the potential for compromise. In February, I shared this thought with Dimitri, who had previously introduced me to Ryosuke via email. I reached out to Ryosuke and asked if he’d be interested in meeting. Ryosuke agreed and invited Tess to join as well.</p>
<p>The hope I expressed to Dimitri in email was that <em>“Ryosuke and I [could] work as a tiny team... come to agreement on something, and then jointly propose that for consideration at the F2F [web components face-to-face meeting] in April.”</em></p>
<h3>April 3: Meeting with Apple</h3>
<p>I met with Ryosuke and Tess at a conference room I rented for the morning in Palo Alto, not far from Apple’s headquarters. Our discussion was productive.</p>
<p>I proposed that we simplify the <code>&lt;content&gt;</code> element design to use a simple name instead of a CSS selector, and Ryosuke and Tess felt this would be a good step forward. For the sake of differentiating the proposed design from Shadow DOM v0, I wrote “slot” on the whiteboard as a working name. I offered to write up the new design as a joint proposal from Apple and Component Kitchen, and Ryosuke and Tess agreed.</p>
<p>Having the discussion in person — and not in the tightly-constrained medium of a mailing list — made an enormous difference. It was also helpful to ask Apple basic questions about their opinions and goals (<em>What do you want? What’s important to you?</em>) rather than constraining discussion to feedback on another company’s proposal (<em>Why won’t you adopt this design?</em>).</p>
<h3>April 21: Draft proposal</h3>
<p>With feedback from Ryosuke and Tess, I posted a joint
<a href="https://www.google.com/url?q=https://github.com/w3c/webcomponents/wiki/Proposal-for-changes-to-manage-Shadow-DOM-content-distribution/641b524e633678c2b25e7cb8ba31005350f36c9d&amp;sa=D&amp;ust=1554399746466000">draft proposal</a>
on GitHub, and Ryosuke
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0184.html&amp;sa=D&amp;ust=1554399746466000">shared the proposal on the webapps mailing list</a>.
The proposal suggested several changes to Shadow DOM, including a new “syntax for named insertion points”:</p>
<blockquote>
<p><em>In this proposal, the attribute for defining the name is called “slot”. The word “slot” is used both in the name of an attribute on the <code>&lt;content&gt;</code> element, and as an attribute (content-slot) for designating the insertion point to which an element should be distributed. The word “slot” should just be considered a placeholder. it could just as easily be called “name”, “parameter”, “insertion-point”, or something similar. We should focus first on the intent of the proposal and, if it seems interesting, only then tackle naming.</em></p>
</blockquote>
<p>Eventually, the <code>&lt;content&gt;</code> element would be
<a href="https://www.google.com/url?q=https://www.w3.org/Bugs/Public/show_bug.cgi?id%3D28561&amp;sa=D&amp;ust=1554399746468000">renamed</a>
<code>&lt;slot&gt;</code>, and the syntax <code>&lt;content slot=&quot;foo&quot;&gt;</code> was replaced with <code>&lt;slot name=&quot;foo&quot;&gt;</code>.</p>
<p>This definition of <code>&lt;slot&gt;</code> was intentionally simpler than the definition of <code>&lt;content&gt;</code>. Where <code>&lt;content&gt;</code> could specify a CSS selector, nodes could only be assigned to a <code>&lt;slot&gt;</code> by name.</p>
<p>Maciej
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0225.html&amp;sa=D&amp;ust=1554399746468000">summarized Apple’s positions on Shadow DOM v0</a>,
including their desire to adopt the slot proposal. In email, Dimitri indicated that he was circulating the ideas at Google:</p>
<blockquote>
<p><em>I just pre-flighted the ideas... and we don&#39;t hate them! :)</em></p>
<p><em>Actually, the slot-based thing was received positively. It&#39;s something that would also definitely reduce the complexity of the code.</em></p>
</blockquote>
<p>These were good words to hear. Still, Google is a big company comprised of individuals with their own opinions. Given Google’s considerable investment in Shadow DOM v0, many Googlers were still committed to pushing forward with that design.</p>
<p>Coincidentally, at this time my company was doing contract work for Google. To the extent that Google didn’t like the compromise proposal I had worked out with Apple, that disagreement was complicating our business relationship.</p>
<h3>April 24: W3C WebApps Face-to-Face</h3>
<p>This was a critical meeting. Beforehand, Dimitri summarized the
<a href="https://www.google.com/url?q=https://github.com/w3c/webcomponents/wiki/Shadow-DOM:-Contentious-Bits&amp;sa=D&amp;ust=1554399746470000">Contentious Bits</a>
of the Shadow DOM spec that included all the points on which Apple disagreed with Google. The <code>&lt;slot&gt;</code> proposal was listed under the question of removing support for multiple shadow roots.</p>
<p>This was my first W3C meeting, so I didn’t have other meetings to compare it to, but to me the discussion seemed fairly tense. Dimitri deftly and diplomatically started the meeting off on a positive note — by getting agreement on points that were not contentious or had been previously negotiated. He also began with an important concession, indicating that he would drop his original design that called for multiple shadow roots. From the meeting
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/att-0307/24-minutes.html&amp;sa=D&amp;ust=1554399746471000">minutes</a>:</p>
<blockquote>
<p><em>This [multiple shadow roots] has been a big sticking point for the Shadow DOM spec. I was the one arguing for it. ... I think most usage isn’t that good, so I am okay with removing it.</em></p>
</blockquote>
<p>That said, there was contention on whether the <code>&lt;slot&gt;</code> proposal was an adequate way to address the scenarios originally intended for multiple shadow roots.</p>
<figure>
  <img src="/static/20241020005925/images/blog/Web Components F2F 2015.jpg">
  <figcaption>
    Whiteboard discussion at the April 2015 F2F. From left to right: Ryosuke Niwa (Apple), Anne van Kesteren (Mozilla), Hayato Ito (Google), Travis Leithead (Microsoft), Dimitri Glazkov (Google)
  </figcaption>
</figure>

<p>Throughout the day, Ryosuke and Maciej argued Apple’s positions. Although I don’t see it captured in the minutes, I recall Ryosuke making it clear that the alternative to a negotiated agreement was that Apple would not implement Shadow DOM v0.</p>
<p>Google, for its part, was not enthusiastic about redesigning the <code>&lt;content&gt;</code> element. To keep track of the browser vendor positions on the points of contention, during the meeting I put together a spreadsheet tracking a
<a href="https://www.google.com/url?q=https://docs.google.com/spreadsheets/d/15rIpbH8uoiT4soB5WpLAI-geJgHf03wlgtlyUoJ_NuU/edit?usp%3Dsharing&amp;sa=D&amp;ust=1554399746473000">Summary of positions on contentious bits of Shadow DOM</a>.
At the end of the day, the score for the <code>&lt;slot&gt;</code> proposal looked like:</p>
<blockquote>
<p><em>Slots Proposal</em></p>
<p><em>Apple: Proposed it / Mozilla: Like it / Microsoft: Like it / Google: Opposed</em></p>
</blockquote>
<p>Still, substantial progress had been made during the F2F meeting towards addressing Apple’s concerns. From this meeting on, Apple seemed fully committed to resolving its remaining differences. Ryosuke and Dimitri left the meeting with a plan to meet again to discuss some of those. And Dimitri seemed very encouraged by Apple’s renewed level of interest in implementing Shadow DOM.</p>
<h3>May 15</h3>
<p>A few weeks later, Scott Miles at Google posted a surprising message on the webapps mailing list, with the subject:
<a href="https://www.google.com/url?q=https://lists.w3.org/Archives/Public/public-webapps/2015AprJun/0649.html&amp;sa=D&amp;ust=1554399746474000">How about let&#39;s go with slots?</a></p>
<blockquote>
<p><em>We think the ‘slot’ proposal can work… We would like for the working group to focus on writing the spec for the declarative ‘slot’ proposal.</em></p>
</blockquote>
<p>Google was indicating their acceptance of Apple’s desire to replace <code>&lt;content&gt;</code> with <code>&lt;slot&gt;</code> in order to secure Apple’s support of the Shadow DOM standard in WebKit.</p>
<p>While I don’t have specific knowledge of Google’s internal deliberations, it seems likely that Dimitri played an important role in shifting Google’s position on this point. He had been apprehensive about the possibility Apple might walk away from the table again. If that happened, the Shadow DOM specification, and web components as an general idea, might founder and never receive significant adoption.</p>
<p>In contrast, yielding on this relatively small point would keep Apple not only involved, but emotionally invested in a successful outcome. Reaching a compromise was worth more in the long run that the specific merits of the competing <code>&lt;content&gt;</code> and <code>&lt;slot&gt;</code> designs.</p>
<p><em>[Note added on April 22, 2019: Ryosuke commented that, “I don’t think we ever really considered ‘walking away’ from implementing web components per se. We just felt that what was being proposed (v0 APIs) were the wrong primitives... Fundamentally, Apple’s WebKit team always liked the basic idea of web components... I think the large part of contention was really miscommunications.”]</em></p>
<h2>Aftermath</h2>
<p>In the months after the April F2F, Apple and Google were reconciled their remaining differences. The Shadow DOM spec was rewritten as v1, which included the <code>&lt;slot&gt;</code> element as the way light DOM nodes would get displayed within a shadow tree. Ryosuke at Apple and Hayato Ito at Google began implementing Shadow DOM v1 support in WebKit and Blink, respectively.</p>
<p>In October 2015, initial 
<a href="https://www.google.com/url?q=https://webkit.org/blog/4096/introducing-shadow-dom-api/&amp;sa=D&amp;ust=1554399746476000">Shadow DOM v1 support showed up in nightly WebKit builds</a>.
If I recall correctly, that shipped in production Safari sometime around June 2016. Google appears to have
<a href="https://www.google.com/url?q=https://groups.google.com/a/chromium.org/forum/%23!topic/blink-dev/zrZRD2ls5tw&amp;sa=D&amp;ust=1554399746476000">shipped Shadow DOM v1 in Chrome</a>
around the same time.</p>
<p>Support from other vendors was slower to come. Mozilla finally
<a href="https://www.google.com/url?q=https://www.mozilla.org/en-US/firefox/63.0/releasenotes/&amp;sa=D&amp;ust=1554399746477000">shipped Shadow DOM v1 in Firefox</a>
in October 2018. That same month, Microsoft publicly indicated that they had finally begun implementing Shadow DOM v1 in their EdgeHTML engine, but it’s unclear how much progress they ever made towards that end.</p>
<p>In December 2018, Microsoft announced that they were abandoning EdgeHTML in favor of using the same Chromium engine used by Chrome, so they’ll pick up Shadow DOM v1 by default. When Microsoft releases a Chromium-based version of Edge (presumably later this year), all major browsers will finally support Shadow DOM v1.</p>
<h2>Retrospective</h2>
<p>Web components are still a fairly new technology, so it’s a little early to assess the strengths and weaknesses of Shadow DOM v1 across a broad range of products. I can at least say that, having now led the open
<a href="https://www.google.com/url?q=https://component.kitchen/elix&amp;sa=D&amp;ust=1554399746478000">Elix web component library</a>
for several years, the <code>&lt;slot&gt;</code> design has met the Elix project’s needs to date. The project has yet to encounter the need for the sort of flexibility and complexity entailed by the original <code>&lt;content&gt;</code> element design. So as a technical solution, I think that <code>&lt;slot&gt;</code> has worked out fine so far.</p>
<p>Looking back, I think the <code>&lt;slot&gt;</code> proposal achieved what it meant to. It produced a fairly small shift in the definition of a standard but minor HTML element, and was rather unimportant on its own. But it nevertheless represented a breakthrough in the discussion. It renewed Apple’s interest in implementing Shadow DOM and the related Custom Elements specification, and ultimately ensured Apple’s support for Shadow DOM on the critical Mobile Safari web browser. While <code>&lt;slot&gt;</code> was just a small piece of a complex set of negotiations, I believe that, without agreement on that one point, it’s likely Apple would have not gone forward with Shadow DOM support.</p>
<p>At the same time, the <code>&lt;slot&gt;</code> compromise allowed Google to preserve much of their Shadow DOM investment and deliver Shadow DOM v1 support in a timely manner. In the grander scheme of things, it let Dimitri, Alex, and other farsighted visionaries at Google achieve their goal of finally giving the web a native UI component model. And for that, I think, we can all be grateful.</p>
<p>On a larger scale, it’s remarkable to consider that HTML has something like 100 standard elements, and each of them has a range of features. CSS and JavaScript are similarly complex. When we’re developing for the web, we take these standard elements and features as facts on the ground. For all we know or care, they’ve always been there — but all of them likely hold their own equally complex histories about how they came to be.</p>
<p><em>Special thanks to Dimitri Glazkov and Ryosuke Niwa for reviewing drafts of this post.</em></p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Building a great combo box component is so much trickier than you'd think</title>
      <pubDate>Mon, 10 Dec 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/building-a-great-combo-box-component-is-so-much-trickier-than-youd-think</link>
      <guid>http://component.kitchen/blog/posts/building-a-great-combo-box-component-is-so-much-trickier-than-youd-think</guid>
      <description><![CDATA[
      <p>Combo boxes are <em>hard</em> to implement well. At the most abstract level, a combo box combines a text input with a button that can invoke a popup. The popup contains a list or other data-entry element:</p>
<figure>
  <img src="/static/20241020005925/images/blog/ComboBox.png">
</figure>

<p>But even this simple visual arrangement hides many complexities. A while ago we shared the challenges building a <a href="http://component.kitchen/blog/posts/building-a-great-menu-component-is-so-much-trickier-than-youd-think">great menu component</a>, so we thought we’d offer a similar look at the many issues faced as we added a new family of <a href="http://component.kitchen/elix/ComboBox">ComboBox</a> components to the Elix web components library.</p>
<h2>Keyboard focus challenges</h2>
<p>Keyboard focus proves to be one of the most challenging aspects of writing good general-purpose web components:</p>
<ul>
<li>The browser primitives for working with focus predate Shadow DOM, and there are still odd edge cases. In our work on ComboBox, we hit an issue that turned out to be a <a href="https://github.com/w3c/webcomponents/issues/773">bug</a> in both Chrome and Safari.</li>
<li>Keyboard focus and keyboard input are generally difficult to test in an automated way. Synthetic keyboard events rarely work in a manner that’s identical to real keyboard events triggered by user activity.</li>
<li>The imperative nature of the <code>focus()</code> method to set focus doesn’t mesh well with a contemporary functional-reactive approach to rendering UI. You have to apply focus after rendering (in <code>componentDidUpdate</code> or something like it), which can lead to timing issues.</li>
<li>Mobile focus behavior can differ from desktop focus behavior.</li>
</ul>
<p>Beyond these points, very similar UI patterns may call for focus to be handled quite differently, making it tricky to establish reusable baseline behavior.</p>
<h2>Where should the focus go in a combo box?</h2>
<p>Handling keyboard focus for a combo box is particularly hard, because there are multiple potentially focusable elements. For a combo box containing a list, we want to keep the keyboard focus on the text input element, but the user may also want keys to navigate selection in the list.</p>
<figure>
  <img src="/static/20241020005925/images/blog/AutoCompleteComboBox.png">
</figure>

<p>If the user presses the Left or Right arrow, they most likely want to move the insertion point to the left or right. However, if they press the Up or Down arrow, it’s reasonable to assume they want to move to the previous or next selection in the list.</p>
<p>Moreover, the user wants to seamlessly move back and forth between typing and navigating.</p>
<ul>
<li>If they type a few letters, then see the desired item appear in the list, they want to immediately press the Down arrow key to get there, without first having to tab to the list.</li>
<li>Likewise, if the user’s navigating the list, that populates the input field. When the input field holds a value the user wants to edit, they should be able to start typing immediately, without having to Shift+Tab to move the focus back to the input.</li>
</ul>
<p>Given these constraints, it seems best to always keep the keyboard focus on the input element. That means we need to listen for keystrokes that seem meant for the list (like Up, Down, Page Up, and Page Down) and tell the the list what to do via method calls. If the user clicks on the popup, we’ll let that click do whatever it would normally do (like select the clicked item), then ensure the focus is still on the input.</p>
<h2>Controlling the input and popup with the keyboard</h2>
<p>Keeping the focus on the input makes managing the popup harder. We usually want a popup to implicitly close if it loses focus, but in this case we won’t give the popup the focus at all.</p>
<p>We also face some odd challenges on mobile:</p>
<ul>
<li>In native apps, lightweight popups like combo boxes usually go away when the user resizes the window. But in Chrome for Android, moving the focus to the combo box will invoke the on-screen keyboard — which resizes the viewport, which closes our popup. We had to allow our underlying <a href="http://component.kitchen/elix/PopupModalityMixin">PopupModalityMixin</a> to optionally allow window resizing while a popup is open.</li>
<li>When Safari displays its on-screen keyboard, it doesn’t give the app any way of knowing that the keyboard’s open; the app still thinks the page hasn’t changed size. That means a combo box on Safari can’t automatically confine itself to the available real estate. A dropdown combo box on a mobile device isn’t a particularly common pattern, but it’s still disappointing that Safari can’t support it better.</li>
<li>If you tap the page background when a combo box is open, you probably want the combo box to close. That’s the natural analogue to clicking the page background to dismiss a combo box on a desktop browser. Chrome for Android does this correctly, but Safari appears to only put the keyboard away if you explicitly tap the keyboard’s Done button or tap some other focusable page element.</li>
</ul>
<h2>Auto-complete</h2>
<p>Auto-complete is a common feature in combo boxes with lists. That feature is useful in other contexts, too, so we’ve implemented auto-complete in an <a href="http://component.kitchen/elix/AutoCompleteInput">AutoCompleteInput</a> that we can use elsewhere.</p>
<p>Auto-complete presents its own challenges:</p>
<ul>
<li>Auto-complete should happen on keydown for the best response. But when the user types a key, we get an input’s <code>keydown</code> event <em>before</em> the input’s default behavior actually adds the key to the text. That makes it hard to know what text to use for auto-complete. We could try to speculatively construct the text, based on the current text, the current key being pressed, and the state of the insertion point and selection. But that’s not trivial, and forces us to reproduce native behavior.</li>
<li>A particularly weird issue we encountered was Chrome for Android, which mysteriously sends <code>keydown</code> events with <code>keyCode</code> equal to the magic value 229, regardless of what key was actually pressed. That’s really annoying, and effectively rules out doing anything useful on <code>keydown</code>.</li>
<li>Instead, we listen to the <code>input</code> event. That’s a safer option — the event is only generated after the new key has been reflected in the input’s <code>value</code> property.</li>
<li>However, the <code>input</code> event also behaves weirdly on mobile browsers. For example, the default Gboard keyboard on Android will send more than one input event for a single keypress! It’s hard to interpret what’s going on, but it seems related to Gboard’s own AutoComplete behavior. Maybe we can turn off Gboard’s AutoComplete behavior by setting the <code>autocomplete</code> attribute to <code>off</code>? “Hahaha, nope!” says Gboard. Other Android keyboards have their own quirks.</li>
<li>The bottom line is that mobile keyboards generally presume that the text in an input isn’t going to change underneath them <em>as the user’s typing</em>. When we try to append auto-completed text to the input during a keystroke, the on-screen keyboard gets really confused.</li>
<li>We eventually worked around these issues by debouncing <code>input</code> events and giving the input a chance to settle down before looking at the latest value. That creates timing problems, but seems the best we can do.</li>
<li>We also need to take pains to only try to auto-complete text if the user’s typing at the end of the input box.</li>
</ul>
<p>If we do manage to match the user’s input against a known list of text choices, we auto-complete the input text, and then leave the auto-completed portion of the text selected. If the user wants to enter something else, they can just keep typing, and that’ll automatically overwrite the selected (i.e., auto-completed) text.</p>
<h2>Accessibility</h2>
<p>We try as hard as we can to do an exemplary job supporting universal access in the Elix web components, including ARIA recommendations for combo boxes. A combo box, unfortunately, appears to hit the limits of what’s currently possible in web component accessibility.</p>
<ul>
<li>As with other kinds of wrapped input elements, it’s hard to have an <code>aria-label</code> on a complex component like our combo box. The app developer can only set <code>aria-label</code> on the outer combo box, because that’s all that’s visible to them. We can forward this value to the inner input element. But that means the DOM tree ends up with a <code>aria-label</code> on both the outer combo box and the inner input element. The screen reader sees that label twice in the accessibility tree, and so will confusingly read the label twice.</li>
<li>Many ARIA attributes take an ID reference, but ID references don’t work across the Shadow DOM boundary. If you try to set <code>aria-labelledby</code> on the outer ComboBox, and that gets delegated to the input hiding inside the ComboBox’s shadow, that input can’t find the corresponding label sitting outside in the light DOM.</li>
<li>A more complex example of the above issue is that, in theory, both the wrapping combo box and the inner input need a way to reference the list of choices: the ComboBox should set <code>aria-owns</code> and the input should set <code>aria-controls</code> and <code>aria-activedescendant</code>. But again, it’s impossible for elements in shadow to reference IDs in light DOM, or vice versa.</li>
</ul>
<p>For the time being, we do the best we can, and hope that the W3C <a href="https://wicg.github.io/aom/spec/">Accessibility Object Model</a> will open up the possibility of better accessibility.</p>
<h2>Making ComboBox as general-purpose as possible</h2>
<p>Our goal with ComboBox is to provide a solid general-purpose combo box class that can be used for any combination of a text input with a popup. The element featured in the combo box’s popup could be a list, or a calendar, or anything else.</p>
<p>To accommodate this level of flexibility, we’ve defined <em>roles</em> for our ComboBox family. Each role is filled by another component. For example, the base ComboBox class defines an <code>input</code> role that you can fill with any input-like element that should be shown in the combo box. By default, this role is filled with a standard <code>&lt;input&gt;</code> element, but you use other input elements in that role. Our <a href="http://component.kitchen/elix/AutoCompleteComboBox">AutoCompleteComboBox</a> uses the aforementioned AutoCompleteInput, letting a combo box easily pick up auto-complete support.</p>
<p>So a ComboBox is being defined as quite an abstract thing: it has an input-like element, a button to toggle the popup, and the popup itself. Everything else — auto-complete behavior, the use of a list in the popup, and so on — is defined in more specialized component classes.</p>
<p>That flexibility lets us quickly adapt the combo box pattern to new contexts. For example, we created a <a href="http://component.kitchen/elix/FilterListBox">FilterListBox</a> that filters its items to: a) show only those items that match a text query string, and b) highlights the matching portion of the item text. We can then drop that FilterListBox into the <code>list</code> role of a <a href="http://component.kitchen/elix/ListComboBox">ListComboBox</a> and, <em>voilà</em>, we get a combo box that can filter items as the user types:</p>
<figure>
  <img src="/static/20241020005925/images/blog/FilterComboBox.png">
</figure>

<p>Factoring UI this way lets each component do a great job at its appointed task. In this case, we can take address all the complexity of keyboard support in the generic ComboBox component. You can then use that foundation for great keyboard support in more specialized combo box components.</p>
<h2>Recombining components to implement new patterns</h2>
<p>One other benefit of factoring UI this way is that components can be readily recombined to create new variations. A UI pattern that’s become common in development tools is a “list with search”. This pattern lets you quickly open a file or select a command by typing the first few letters, then selecting the best match from a list. Here’s an example from Chrome dev tools:</p>
<figure>
  <img src="/static/20241020005925/images/blog/ChromeListWithSearch.png">
</figure>

<p>As you type into the input field, the list of files below is filtered to show only those whose names contain the text string. Moreover, the matching portion of the file name is highlighted.</p>
<p>We can quickly reproduce this general UI pattern as a web component by taking the AutoCompleteInput and FilterListBox described above, and wiring them together to create <a href="http://component.kitchen/elix/ListWithSearch">ListWithSearch</a>:</p>
<figure>
  <img src="/static/20241020005925/images/blog/ListWithSearch.png">
</figure>

<p>This is an in-place variation of the FilterComboBox we saw earlier. ListWithSearch is useful in cases where the user is completely focused on selecting an item from a large set. That task focus permits us to place the input and list <em>in situ</em>, instead of needing to save space by hiding the list behind the popup. The user can apprehend the purpose of the UI elements more quickly, and can complete their task in fewer steps.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Building a great menu component is so much trickier than you'd think</title>
      <pubDate>Wed, 11 Jul 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/building-a-great-menu-component-is-so-much-trickier-than-youd-think</link>
      <guid>http://component.kitchen/blog/posts/building-a-great-menu-component-is-so-much-trickier-than-youd-think</guid>
      <description><![CDATA[
      <p>We&#39;ve released v2.2 of the <a href="/elix">Elix</a> web components library, which includes some new components for menus:</p>
<ul>
<li><a href="/elix/PopupSource">PopupSource</a> for buttons that invoke any kind of popup</li>
<li><a href="/elix/MenuButton">MenuButton</a> for the common case of a button that invokes a menu</li>
<li><a href="/elix/Menu">Menu</a> which contains the collection of menu items</li>
<li><a href="/elix/DropdownList">DropdownList</a> for a <code>MenuButton</code> variation that&#39;s effectively a completely customizable <code>&lt;select&gt;</code> element.</li>
</ul>
<p>We want all these menu components to feel as polished and natural as native OS menus. Native menus have a number of subtle details, and getting the UI details right turns out to be outrageously complex. Menus are a good example of <a href="http://www.miksovsky.blogs.com/flowstate/2005/10/the_fractal_nat.html">the fractal nature of UI design</a>.</p>
<h2>Menu positioning</h2>
<p>Just to get started, we need to be able to position a menu with respect to a source button.</p>
<ul>
<li>On desktop, a menu should open on mouse <em>down</em>, not mouse up. This feels faster. It also, as described in more detail below, allows the user to possibly select a menu item in a single drag operation.</li>
<li>Only primary mousedown events should be considered. The menu should not appear on a right-click, since we want the user to still have access to the browser&#39;s own context menu.</li>
<li>The menu should appear in the desired direction if there&#39;s room in that direction. If there isn&#39;t <em>and</em> there&#39;s room in the opposite direction, it should appear in that opposite direction. But if there isn&#39;t room in that direction either, it&#39;s preferable to show the menu in the original direction and constrain its height. (This can force scrolling.) Note that OS menus can extend outside a source window&#39;s boundaries but web components, like all HTML elements, are not allowed to extend outside the document viewport.</li>
<li>The calculation of whether the menu will fit can&#39;t happen until the menu has actually rendered (many factors can influence the layout of the menu), but we don&#39;t want to let the menu be visible until we know which direction we want to use. So we layout the menu once while its invisible, see if it fits, move it to the desired position, then render it again to make it visible.</li>
<li>Calculations of whether the menu fits in a particular direction are affected by the scroll position of the document.</li>
<li>To complicate things, we&#39;ll want to put the keyboard focus in the menu — but moving the keyboard focus can cause scrolling as a side effect. (This is especially true in Safari, whose <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus">focus</a> method doesn&#39;t yet support the <code>focusOptions</code> parameter.) So we&#39;ll have to complete all our menu layout and rendering before we try to move the focus into the menu.</li>
</ul>
<p>Because these positioning rules generally apply to all popups invoked from buttons — not just menus, but also things like combo boxes — we&#39;ve enshrined responsibility for position popups relative to a source button in a general-purpose <a href="/elix/PopupSource">PopupSource</a> class.</p>
<h2>Two ways of selecting a menu command with a mouse</h2>
<p>Most people have probably never noticed there are two different ways of using a mouse to select an item from an OS menu:</p>
<figure>
  <img src="/static/20241020005925/images/blog/Menu Selection.png">
</figure>

<p>Nearly every web menu handles only the first method: selecting a menu item in two clicks. But both macOS and Windows support selecting menu items in a drag operation, which can feel faster and more responsive. If you&#39;re reading this on a laptop, try using your mouse/trackpad now to select a browser menu command using both approaches. Observe the different feel of the two approaches. Which do you normally use?</p>
<p>(I seem to recall that the original Mac OS supported only menu selection with a drag, while Windows supported both methods. Windows generally had better keyboard support for menu navigation, and once Windows engineers allowed the user to pop up a menu with the keyboard and keep it open, it was probably easy for them to support the two-click method.)</p>
<p>The two-click method is trivial to implement, but if we want to achieve the same usability of an OS menu, we&#39;ll want to also support the drag method. That&#39;s hard to do, which is probably why most web apps don&#39;t support it. (The various Google Suite apps are a notable exception.) A few of the more interesting problems:</p>
<ul>
<li>If the user mouses down, then moves the mouse away from the menu button and its associated menu, and then releases the mouse over the page background, the menu should be dismissed.</li>
<li>Once the user drags into the menu with the mouse down, we want to automatically select the menu item underneath the mouse. However, those item can&#39;t get mouse events yet — the user still has the mouse down, so all mouse events are still targeted at the button that invoked the menu. We&#39;ll need to listen to <code>mousemove</code> on the menu button and do our own hit-testing to figure out whether the user is currently dragging the mouse over a menu item — and, if so, select that item.</li>
<li>If the user mouses down and then moves the mouse completely off the page, our menu button component will never receive a <code>mouseup</code> event. So we&#39;ll need to listen to <code>mouseup</code> events on the <code>document</code> too.</li>
<li>If the user mouses down, then releases the mouse over interior menu padding or a disabled item like a menu separator, the menu should also be dismissed.</li>
<li>However, if the user opens the menu with a click (in the two-click approach), a subsequent click on interior menu padding or a menu separator should be <em>absorbed</em> and not close the menu.</li>
</ul>
<p>This is all hard, but still doable, so we&#39;re giving it our best shot. If you&#39;re on a laptop, try opening our <a href="https://component.kitchen/demos/menuButton.html">MenuButton demo</a> and confirming that the menu component feels like an OS menu.</p>
<p>For completeness, I should point out that many web menus also handle an additional means of selecting a menu item with a mouse: the menu opens on <em>hover</em>, after which the user only needs to click once on the desired menu item. I hesitate to mention that approach, however. It&#39;s my personal belief that hover menus are a usability disaster: they invariably appear when they&#39;re not wanted, and disappear when they <em>are</em> wanted. The hover approach does have a distinct advantage, in that it lets the top-level menu heading itself serve as a clickable link. But I think that advantage comes at a steep usability cost.</p>
<h2>Menus on mobile</h2>
<p>Our two-click approach for menus should generally work on mobile devices, with some minor changes. Generally speaking, mobile menus appear when a tap <em>ends</em> and force use of the two-click method described above. To ensure the menu responds instantaneously, we must <a href="https://webkit.org/blog/5610/more-responsive-tapping-on-ios/">enable fast-tap behavior</a> by applying the CSS <code>touch-action: manipulation</code> to the relevant elements.</p>
<p>If reading this on your phone, try opening our <a href="https://component.kitchen/demos/menuButton.html">MenuButton demo</a> and tap around. The menu should both appear and disappear as soon as you complete a tap.</p>
<h2>Keyboard support and accessibility</h2>
<p>As with all Elix components, we strive for excellent keyboard support. This benefits all users that want to use a keyboard and improves universal accessibility.</p>
<p>We allow users to invoke a menu button by pressing Space. The user can navigate the items in the resulting <code>Menu</code> with the full set of keyboard navigation keys supported by <a href="/elix/KeyboardDirectionMixin">KeyboardDirectionMixin</a>, <a href="/elix/KeyboardPagedSelectionMixin">KeyboardPagedSelectionMixin</a>, and <a href="/elix/KeyboardPrefixSelectionMixin">KeyboardPrefixSelectionMixin</a>. Without writing any new code, those mixins give <code>Menu</code> support for Up/Down keys, Page Up/Page Down keys, Home/End keys, and prefix selection (e.g., type &quot;Z&quot; to select &quot;Zoom&quot;).</p>
<p>In making our menu components accessible via ARIA, we were helped by this excellent Inclusive Components article on <a href="https://inclusive-components.design/menus-menu-buttons/">Menus &amp; Menu Buttons</a>. The whole Inclusive Components series is worth a read.</p>
<p>While our <code>Menu</code> component generally behaves like our <a href="/elix/ListBox">ListBox</a>, the accessibility rules for menus are different than lists. The <code>role</code> attributes involved are different, for one thing. Another way in which menu accessibility is different than that for lists is that the overall list element can take the keyboard focus, whereas the browser expects a menu to put the keyboard focus on an individual menu item.</p>
<p>Happily, our <a href="https://component.kitchen/elix/mixins">mixin-based approach to components</a> was hugely helpful in letting us create a <code>Menu</code> component that worked <em>mostly</em> like our <code>ListBox</code> component, but with some differences. Rather than subclassing <code>ListBox</code> or creating a common base class (as we might have in a traditional class hierarchy), we simply copied over the set of mixins <code>ListBox</code> was using, dropped the ones we didn&#39;t need, and then created an <a href="/elix/AriaMenuMixin">AriaMenuMixin</a> for menus to replace the <a href="/elix/AriaListMixin">AriaListMixin</a> which <code>ListBox</code> needs. We end up with a <code>Menu</code> that cleanly shares 90% of the code from <code>ListBox</code> without any class hierarchy entanglements.</p>
<h2>Customizability</h2>
<p>For styling and general customizability, all these menus components have replaceable parts. So you can use a <code>MenuButton</code>, but swap out the elements it uses by default with our own custom elements. You could:</p>
<ul>
<li>Have your menus show a semi-opaque backdrop over the page that&#39;s themed with your brand color.</li>
<li>Change the popup (menu) portion so that the menu animates in with a sliding effect.</li>
<li>Replace the <code>Menu</code> that contains the menu items with an element that lays out items as pie slices instead of the usual vertical orientation.</li>
</ul>
<h2>Bonus: a customizable select element</h2>
<p>With our <code>MenuButton</code> component in hand, it was easy to create a <a href="/elix/DropdownList">DropdownList</a> variation that shows the selected value as the menu button&#39;s label. When the user makes a selection from the menu, the button label updates to match.</p>
<p>This effectively lets you use <code>DropdownList</code> as a customizable version of the built-in HTML <code>&lt;select&gt;</code> element. The native <code>&lt;select&gt;</code> can only cope with text choices, but <code>DropdownList</code> can handle arbitrary content — including custom elements, of course — as content in both the menu button and the menu items. See this <a href="/demos/colorDropdownList.html">customized dropdown list demo</a> for an example.</p>
<p>Interestingly, the native <code>&lt;select&gt;</code> is a place where some users may use the drag-to-select method to make a selection — even if they&#39;re the type of user that normally selects from an app&#39;s menu bar using the two-click method. In other words, all the work we did to build a menu button with great mouse support <em>also</em> makes it possible for us to deliver a dropdown list (<code>&lt;select&gt;</code>) with great mouse support.</p>
<h2>These details are a pain!</h2>
<p>Getting all these details correct takes far too much time. Which is precisely why no app team should try to build a menu component from scratch! The only sane way to achieve OS-quality menu components for web apps is to share code — to pour the attention of an open component library community into menu components that everyone can use. <em>That</em> is why Elix exists.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Creating software in 2028 is so amazing now that we build with reusable UI components!</title>
      <pubDate>Mon, 14 May 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/creating-software-in-2028-is-so-amazing-now-that-we-build-with-reusable-ui-components</link>
      <guid>http://component.kitchen/blog/posts/creating-software-in-2028-is-so-amazing-now-that-we-build-with-reusable-ui-components</guid>
      <description><![CDATA[
      <p><em>We’re getting much closer to a world where we can create sophisticated applications from widely reusable, general-purpose user interface components. We’re still not there — it might be another 5–10 years before that world comes to pass. But we can imagine what software development will be like once that&#39;s happened.</em></p>
<figure>
  <img src="/static/20241020005925/images/blog/Retro-Futurism.jpg">
</figure>

<p>Here in the year 2028, we’re lucky to share enormous public collections of reusable components implementing every user interface pattern under the sun. Every old-school UI technique you can think of — menus, carousels, shopping carts, Pull to Refresh, plus all the cool stuff that was invented in the 2020s — <em>everything</em> you need is already coded for you!</p>
<p>Just think of how good we have it now:</p>
<ul>
<li><p><em>Designers and devs readily adopt common UI patterns without hesitation.</em> They never wonder how hard it will be for the team to implement a pre-existing UI, because they can always find a rock-solid implementation of it in the comprehensive component libraries.</p>
</li>
<li><p><em>We see constant experimentation.</em> Because switching to a different pattern is trivial, designers play with and test multiple ideas before settling on a solution.</p>
</li>
<li><p><em>Visual design tools let us work with palettes of UI patterns.</em> These days, it goes without saying that designers and developers collaborate directly on the same artifacts that define an app. But it wasn&#39;t that long ago that designers would create static design images or limited prototypes, and developers would laboriously translate those to running code. (Honest, they really had to do that!) These days, our design tools can edit the front end definition directly. Not only that, they provide integrated access to catalogs of UI patterns as components. Adding or modifying complex interactions can now be accomplished through drag-and-drop. That shift dramatically accelerated development, further encouraged experimentation, and generally made designing a blast.</p>
</li>
<li><p><em>You see a lot more variation in common patterns</em> than one saw in the 2010s. It used to that variation came about almost accidentally because people had to implement patterns from scratch. Now designers and devs create variations when they want to. They can extensively customize generic components or build new variations that reuse substantial behavior from existing generic components. Even complex patterns can be adapted to new contexts and still retain much of their reusable value.</p>
</li>
<li><p><em>We’ve seen a burst of domain-specific innovation.</em> Because teams no longer waste time reinventing wheels, they now focus primarily on their business domain’s specific challenges and their app’s unique value. We&#39;ve also seen the introduction of large domain-specific pattern libraries for specific industries. The apps we use now are far, far better as a result.</p>
</li>
<li><p><em>Fewer people are required to design and implement basic UI.</em></p>
</li>
<li><p><em>You probably create UIs alongside many people with deep expertise in fields other than UI design.</em> Once working with UI building blocks became easy enough, more people could do it, which opened up the field to a huge number of new participants.</p>
</li>
<li><p><em>If you’re young, you may not even remember a time when companies had to build their product UI multiple times for different OS platforms.</em> What a colossal waste of time and money that was!</p>
</li>
<li><p><em>Good ideas now spread faster.</em> When the Thought Crystals user interface pattern first appeared in beta in April 2025, the creator contributed a solid reusable implementation, and it spread like wildfire. By May, the new pattern had completed displaced VR hamburger menus.</p>
</li>
<li><p><em>Common patterns have been extensively studied and documented.</em> For any given pattern, you can access a wealth of academic and industrial research about it: the precise circumstances where it is most useful, metrics showing where how and why it goes wrong, comprehensive galleries showing the pattern in actual use, and suggestions for best practices in specific contexts.</p>
</li>
<li><p><em>Coded patterns gave us all a consistent vocabulary</em> that reflected both user experience and developer implementation. Once we had real implementations of all the common patterns, everyone building apps could talk about UI the same way.</p>
</li>
<li><p><em>We rarely come across apps with terrible UI fundamentals.</em> Back in the day, one could hardly shop online without constantly tripping over aggravating menus, intrusive dialogs, and flaky carousels. Ignorant companies today still produce bad apps with bad designs, of course, but at least the fundamental interactions in those apps still meet a decent quality bar.</p>
</li>
<li><p><em>People with permanent or temporary disabilities have better experiences across the board.</em> At minimum, an app’s fundamental UI provides a higher baseline of reasonable interaction than one typically found in 2018.</p>
</li>
<li><p><em>Branded user experiences have become far more immersive.</em> Corporations customize UI in a deep way, far beyond theming fonts or colors. They adapt all aspects of interaction: the types and speeds of animated effects and sounds, the quality of voice dialogs, the tightly-focused microbrands for specific markets, and the general personality of a UI’s construction. Even boring apps today in 2028 exhibit the same degree of pizzazz as games did back in 2018.</p>
</li>
<li><p><em>You now design some aspects of your apps at a meta-level.</em> For certain UI problem domains, you can just specify the general parameters of the problem, and let the system make limited decisions about the best UI pattern for the situation. Sophisticated apps now use AI to track user behavior and adapt which patterns are used in real time.</p>
</li>
<li><p><em>While the component implementations in our universal pattern library have been rewritten several times over, the patterns themselves have proved quite durable.</em> While we now use much better frameworks that were available in 2018, the patterns themselves are timeless. When we saw major shifts in programming languages and techniques in the early 2020s and again in 2025, it was relatively easy to upgrade the patterns and the apps which depended on them.</p>
</li>
</ul>
<p>Isn’t user experience design in 2028 great? It&#39;s interesting to realize that all the benefits above were already possible 10 years ago — we just didn&#39;t realize it. All it took was for us to recognize the value of implementing common UI patterns as reusable components and start really sharing them.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Using JavaScript template literals with JSX for server-side rendering</title>
      <pubDate>Mon, 07 May 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/using-javascript-template-literals-with-jsx-for-server-side-rendering</link>
      <guid>http://component.kitchen/blog/posts/using-javascript-template-literals-with-jsx-for-server-side-rendering</guid>
      <description><![CDATA[
      <p>While updating our Component Kitchen site to incorporate the <a href="http://component.kitchen/elix">Elix</a> web component documentation, we replaced our server-side use of Preact with template literals for JSX. The result works well and could be applied in many situations, so we describe the solution here in case others are interested in trying it.</p>
<h2>Some pros and cons of JSX on the server</h2>
<p>Back in 2016, we decided to use <a href="http://component.kitchen/blog/posts/replacing-your-server-side-template-language-with-plain-javascript-functions">plain JavaScript functions to render page content</a>. We really liked that straightforward approach, but we eventually shifted to using JSX because the code was easier to read. The use of components as tags in JSX makes it easier to see how the page is being constructed, and code editors that apply syntax highlighting to HTML/JSX make it easier to spot simple mistakes (missing end quotes, etc.).</p>
<p>But using Preact on the server felt like more architecture than we needed. We&#39;d construct a component, render it immediately to a string, then throw it away. So Preact&#39;s support for lifecycle methods and incremental rendering were all extraneous. And using JSX in our Node code base added a compile step we wouldn&#39;t have otherwise needed. Finally, we had to go through some gyrations to asynchronously collect the data a page needed before we could tell Preact to render the content.</p>
<h2>Using template literals</h2>
<p>With the advent of template literal languages like hyperHTML and lit-html, we wanted to get back to the stripped-down simplicity of plain strings while incorporating the benefits of JSX legibility.</p>
<p>The result is a small template literal library we call <a href="https://github.com/componentkitchen/litJSX">litJSX</a>. It lets us concisely use JSX-like syntax in template literals that combine static content and dynamic content to create strings. All parsing is done at runtime; there&#39;s no build step. Parsing is fast, and because we&#39;re using template literals, parsing of the static content is only done once per unique template string.</p>
<pre><code class="lang-js">const jsxToTextWith = require(&#39;litjsx&#39;);
const html = jsxToTextWith({ Bold, Greet }); // Create custom template literal.

function Bold(props) {
  return html`&lt;b&gt;${props.children}&lt;/b&gt;`;
}

function Greet(props) {
  return html`
    &lt;span&gt;
      Hello,
      &lt;Bold&gt;${props.name}&lt;/Bold&gt;.
    &lt;/span&gt;
  `;
}

html`&lt;Greet name=&quot;world&quot;/&gt;`     // &lt;span&gt;Hello, &lt;b&gt;world&lt;/b&gt;.&lt;/span&gt;
</code></pre>
<p>Our components are all just JavaScript functions that take a properties object and return a string.</p>
<p>With any system along these lines, it&#39;s necessary to tell the template literal function what JavaScript class names it should expect to find in the strings we give it. Some JSX template literal libraries like <a href="https://github.com/trueadm/t7">t7</a> handle this by setting configuration options on the parser.</p>
<p>In our case, we designed litJSX as a generator of custom template literal functions. You feed it a set of classes, and it hands back a custom template literal that recognizes those classes.</p>
<p>The second line above creates a custom template literal called <code>html</code>. We tell it that if it sees the strings &quot;Bold&quot; or &quot;Greet&quot; in a tag, then it should invoke the JavaScript functions <code>Bold</code> and <code>Greet</code>, respectively.</p>
<p>Simply naming our template literal function &quot;html&quot; lets code editor extensions for syntax highlighting know they should parse and decorate the template contents as either HTML or JSX. So we get the design-time legibility and error-checking we were after.</p>
<h2>Server-side rendering</h2>
<p>On the server, we write our top-level page components as functions that accept an HTTP <code>request</code> object and use litJSX template literals to return a string result.</p>
<pre><code class="lang-js">const html = jsxToTextWith({ Greet });

function Greet(props) {
  return html`&lt;p&gt;Hello, ${props.name}&lt;/p&gt;`;
}

function GreetPage(request) {
  return html`
    &lt;!DOCTYPE html&gt;
    &lt;html&gt;
      &lt;body&gt;
        &lt;Greet name=&quot;${request.params.name}&quot;/&gt;
      &lt;/body&gt;
    &lt;/html&gt;
  `;
}

// The page at /greet/Jane returns HTML saying &quot;Hello, Jane.&quot;
app.get(&#39;/greet/:name&#39;, (request, response) =&gt; {
  const content = GreetPage(request);
  response.set(&#39;Content-Type&#39;, &#39;text/html&#39;);
  response.send(content);
});
</code></pre>
<h2>Asynchronous components</h2>
<p>Server-side pages often need to perform asynchronous work before they can return a response, so we designed litJSX to handle components which are async functions. If any component in the JSX is async (returns a <code>Promise</code>), the tagged template literal itself returns a <code>Promise</code> for the final, complete result. This lets you create <code>async</code> component functions and <code>await</code> the final template result.</p>
<pre><code class="lang-js">async function GreetUser(props) {
  const user = await getUser(props.id); // Some async function to get data
  return html`Hello, ${user.name}.`;
}

const html = jsxToTextWith({ GreetUser });
const userId = 1001; // Jane&#39;s user id
const text = await html`&lt;GreetUser id=&quot;${userId}&quot;/&gt;`; // Hello, Jane.
</code></pre>
<p>Such async components allow us to cleanly encapsulate the async work performed by specific pages on our site.</p>
<h2>Results</h2>
<p>We&#39;re now using litJSX to render our entire site. The words you&#39;re reading here have passed through a litJSX template literal! Our server code has gotten more concise and more clearly expresses our intentions, with very minimal library overhead and no build step. So far it&#39;s holding up well.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Elix v2.0 released with support for extensively customizable components</title>
      <pubDate>Mon, 16 Apr 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/elix-v20-released-with-support-for-extensively-customizable-components</link>
      <guid>http://component.kitchen/blog/posts/elix-v20-released-with-support-for-extensively-customizable-components</guid>
      <description><![CDATA[
      <p>Two months after releasing version 1.0 of <a href="/elix">Elix</a>, we&#39;re happy to announce version 2.0.</p>
<p>The main focus of this release is a <a href="/blog/posts/customizing-custom-elements-with-custom-elements">new paradigm for customizing components</a> in which complex component can expose internal elements as configurable properties. You can control the appearance and behavior of such a complex component by handing it <em>other</em> components it will use internally to fill various roles.</p>
<p>This paradigm lets us unify components that had previously been distinct, implementing them with reusable, shared code. For example, by default the Elix <a href="/elix/Carousel">Carousel</a> shows little dots along the bottom:</p>
<figure>
  <a href="/demos/carousel.html">
    <img src="/static/20241020005925/images/blog/Carousel.png">
  </a>
  <figcaption>(Tap/click for live demo)</figcaption>
</figure>

<p>We can override those dots and tell the carousel component to use thumbnails for that role instead, producing a new <a href="/elix/CarouselWithThumbnails">CarouselWithThumbnails</a> component:</p>
<figure>
  <a href="/demos/carouselWithThumbnails.html">
    <img src="/static/20241020005925/images/blog/CarouselWithThumbnails.png">
  </a>
</figure>

<p>As another example, the Elix <a href="/elix/Tabs">Tabs</a> supplies a default style with a classic rounded tab look:</p>
<figure>
  <a href="/demos/tabs.html">
    <img src="/static/20241020005925/images/blog/Tabs.png">
  </a>
</figure>

<p>It&#39;s easy enough to supply a custom button to fill that same tab button role, as in this <code>Tabs</code> instance used as the organizing navigation element in a mobile app:</p>
<figure>
  <a href="/demos/toolbarTabs.html">
    <img src="/static/20241020005925/images/blog/ToolbarTabs.png">
  </a>
</figure>

<p>If you click the image through to the live demo, you&#39;ll see that the main &quot;stage&quot; element for this navigation UI has also been changed. <code>Tabs</code> has a main stage that shows a single tab panel at a time. By default, <code>Tabs</code> uses a simple <a href="/elix/Modes">Modes</a> component as its stage. But this stage can be replaced with another element like <a href="/elix/SlidingStage">SlidingStage</a>, which not only adds a sliding transition, but also support for touch/trackpad gestures to move between tabs.</p>
<p>That&#39;s a level of customization far beyond what&#39;s feasible in CSS. By using one custom element as a parameter to another, we can efficiently create different expressions of fundamental UI patterns.</p>
<p>But as we built Elix 2.0, we realized we could take this idea of customization through custom elements as parameters a lot further.</p>
<h2>The mind-blowing part</h2>
<p>When viewed at the right level of abstraction, <em>all</em> of the component examples shown above <em>are the same component</em>. These carousels and tabbed UIs don&#39;t look alike, but at a logical level, these UI patterns both share core behavior:</p>
<ul>
<li>Both present a main stage showing a single item (an image or tab panel) at a time.</li>
<li>Both present a list of smaller proxies for those items (dots/thumbnails or tab buttons) that can be clicked to select the corresponding item on the main stage.</li>
<li>Both can be implemented so that they can generate a default set of such proxy elements for each corresponding item (i.e., a default dot/thumbnail for each image/panel).</li>
</ul>
<p>All of those parts — the stage, the list of proxy elements, the proxy elements themselves — are configurable via properties.</p>
<p>By separating logical roles and relationships from particular DOM representations, we can find new opportunties to efficiently reuse code. Elix 2.0 delivers the shared behavior for the UI patterns above in a new component called <a href="/elix/Explorer">Explorer</a>. That can be configured on a per-element basis, or subclassed to bake the customizations in, as with the component classes showcased above.</p>
<p>We&#39;ve applied the same configuration paradigm to the Elix set of overlay elements, so that <a href="/elix/Dialog">Dialog</a>, <a href="/elix/Drawer">Drawer</a>, and <a href="/elix/Popup">Popup</a> are all built around a configurable <a href="/elix/Overlay">Overlay</a> core. We expect we&#39;ll find opportunities to use this same pattern in many other places.</p>
<p>Building components around extensively configurable components like this means we can handle subtleties like accessibility and keyboard support in a consistent way, allowing us to deliver a higher-quality and more usable result. It also means that you can readily adapt Elix components for the unique needs of your application, including extensive possibilities for branding.</p>
<p>Read the full <a href="https://github.com/elix/elix/releases/tag/2.0.0">release notes for Elix 2.0</a>.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Using Elix to build a small and fast native-like PWA for mobile devices</title>
      <pubDate>Mon, 12 Mar 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/using-elix-to-build-a-small-and-fast-native-like-pwa-for-mobile-devices</link>
      <guid>http://component.kitchen/blog/posts/using-elix-to-build-a-small-and-fast-native-like-pwa-for-mobile-devices</guid>
      <description><![CDATA[
      <p>
I built <a href="https://memoui.com">Memoui</a>, a fast, small-payload scratch 
pad application with data persistence and offline
support using <a href="/elix">Elix</a> web components and mixins.
Thanks to service workers and seamless Android support for adding to the
device's home screen, the application has a native feel and user experience,
with the benefit of installing from a URL rather than an app store.
</p>
<p>
While working on a longer term PWA project, I wanted to deliver a more limited 
sample application so I could more quickly gain insights into the end-to-end 
patterns and pitfalls. What I ended up with is 
Memoui (/ˈmemwē/ 😉). This was incidentally a useful app for me, as I like having 
on my phone a means to write down or dictate something very quickly, without a 
care for network backup, accounts, etc. I’m also determined not to download and 
congest my device with native apps from the app stores. Memoui would be, and is, 
an app I’d actually use, no matter how simple it looks.
</p>

<img src="/static/20241020005925/images/blog/memoui-screen 300x533.png">

<p>
Beyond the functionality of the app, I had very specific learning and 
implementation objectives:

  <ul>
    <li>
      I wanted to leverage work I’d already begun on my larger project, making 
      use of my existing build and server side patterns.
    </li>
    <li>
      The front-end must be written almost exclusively with web components, and 
      specifically with Elix elements and mixins.
    </li>
    <li>
      The network experience is exclusively for download/install. No network 
      connection is required thereafter except for updates.
    </li>
    <li>
      Local device persistence of data. No accounts. No network backup. It’s a 
      scratch pad, after all.
    </li>
  </ul>
</p>

<p>
And, finally, I wanted to explore the subtleties involved in the full 
development lifecycle from conception to delivery as a proof of concept
project.
</p>

<p>
Thinking about the project in these terms, it was striking to me how similar 
this was to the early development of native iOS and Android applications where so 
many apps were designed to be installed and run independent from network 
connectivity. We’re not really talking about PWAs in this world, where you care 
about scalability to desktop browsers, or progressive enhancement. The target is 
a mobile device, and the subject is an application, pure and simple. It's not 
necessarily PWA; it’s more WAP &mdash; web app, period.
</p>

<p>
The result was a functional application delivered to a device through a URL, 
with an initial download size of about 90 KB, and the actual client code 
contributing about 23 KB, compressed. The application runs fully offline where 
service workers are supported, and makes use of:

  <ul>
    <li>
      <a href="/elix/Tabs">Elix Tabs</a> element
    </li>
    <li>
      <a href="/elix/Drawer">Elix Drawer</a> element
    </li>
    <li>
      <a href="/elix/ReactiveElement">Elix ReactiveElement</a>
      and its collection of mixins
    </li>
    <li>
      An IndexedDB database
    </li>
    <li>
      Service workers!
    </li>
    <li>
      A <a href="https://developer.mozilla.org/en-US/docs/Web/Manifest">web app manifest</a>
    </li>
    <li>
      Server-side Preact, minimally for routing and page hosting
    </li>
    <li>
      Webpack
    </li>
  </ul>
</p>

<p>
From a 
<a href="http://component.kitchen/blog/posts/a-compact-javascript-mixin-for-creating-native-web-components-in-frpreact-style">functional reactive programming</a>
perspective, Memoui follows the React pattern of components for UI interfaces, 
starting with componentization at the page level. Rather than incurring 
framework costs, Memoui takes advantage of its target device’s support for 
native web components. Everything of interest is a web component (modulo work 
I’d eventually do, server side, to eliminate even my minimal use of Preact for 
routing and master page framework). And all Memoui’s components are built with 
Elix.
</p>

<p>
Elix shines in that, even with its 1.0.0 release, it is a comprehensive library 
of valuable semantics, organized as mixins that work both synergistically with 
other mixins, or independently. Elix elements are mostly groupings of mixins.
While the Elix code base is growing in size and sophistication, Memoui’s 
download size remains anchored only to what it needs from Elix.
As an interesting comparison with building small Android APKs, 
<a href="http://engineering.khanacademy.org/posts/a-really-small-app.htm">read this great article</a>
by Charlie Marsh at Khan Academy.
</p>

<p>
I spent most of my time on the IndexedDB portion of Memoui, learning how best to 
organize the transaction-based persistence of its two datastores, and the data 
structure representing the tabbed (fixed) collection of notes and current tab 
state. If you look at the code, you’ll notice the strange name of the class 
managing the application state JSON, a result of my modeling Memoui against the 
similar needs of my more sophisticated app in progress whose UI centerpiece is 
an 
<a href="/elix/Carousel">Elix Carousel</a>
rather than Tabs.
</p>

<p>
I should mention this learning point. I grew unhappy with the data structure 
names, but they were tied into the schema of Memoui’s IndexedDB stores. Since I 
already had a small set of users, making a naming change 
would require adding support for the IndexedDB <code>onupgradeneeded</code> 
event, capturing the current persisted data, creating new versions of the 
store(s), populating those with the saved data, and blowing away the old stores. 
While this will be necessary work in future projects, I didn’t care to do so for 
Memoui. It’s a lesson in careful planning.
</p>

<p>
No application, even the simplest, is ever done and this exercise opens the door 
to endless improvements and changes based on learned insights. For now, I’m 
satisfied both with the learning exercise and with having a minimal app on my 
phone that, due to its speed and simplicity, I actually find myself using every 
day.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Customizing custom elements with... custom elements</title>
      <pubDate>Tue, 20 Feb 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/customizing-custom-elements-with-custom-elements</link>
      <guid>http://component.kitchen/blog/posts/customizing-custom-elements-with-custom-elements</guid>
      <description><![CDATA[
      <p>We’ve recently been trying a new way to let devs customize complex web components: <em>let a component accept parameters for the custom elements that should be used inside the component’s template</em>.</p>
<p>A while back we indicated that we noted that it’s hard to <a href="http://component.kitchen/blog/posts/styling-is-critical-to-web-component-reuse-but-may-prove-difficult-in-practice">style web components</a>, and that we’ve been using <a href="http://component.kitchen/blog/posts/our-current-best-answer-for-styling-reusable-components-subclassing">subclassing</a> as a partial solution. Using custom elements themselves as parameters to more complex components opens up new possibilities for styling, as well as interesting new possibilities for customizing behavior.</p>
<h2>Example</h2>
<p>Suppose we have a simple spin box:</p>
<p><img src="/static/20241020005925/images/blog/Spin Box.png"></p>
<p>This component has two <code>&lt;button&gt;</code> elements inside its shadow. Suppose we construct this shadow from a template defined by a string:</p>
<pre><code>const template = `
  &lt;span id=&quot;value&quot;&gt;&lt;/span&gt;
  &lt;button id=&quot;upButton&quot;&gt;▲&lt;/button&gt;
  &lt;button id=&quot;downButton&quot;&gt;▼&lt;/button&gt;
`;
</code></pre><p>How do we let a developer customize those buttons? As noted in the first post linked above, the whole point of Shadow DOM is to encapsulate styles, so we can’t directly style those buttons from the outside. And while there eventually be a standard way to style across a Shadow DOM boundary, that won’t be available any time soon.</p>
<p>But if we’re constructing the shadow from a string, we can simply let a dev insert whatever element they’d like as the “button” element in the above template.</p>
<h2>Exposing a component parameter to accept another custom element</h2>
<p>That’s easy to arrange. We define a <code>buttonTag</code> property that can be set on a spin box at any point before the component’s <code>connectedCallback</code> runs:</p>
<pre><code>const buttonTagKey = Symbol();

class SpinBox extends HTMLElement {

  constructor() {
    super();
    this.defaultButtonTag = &#39;button&#39;;
  }

  get buttonTag() {
    return this[buttonTagKey] || this.defaultButtonTag;
  }
  set buttonTag(buttonTag) {
    this[buttonTagKey] = buttonTag;
  }

  /* Plus rendering code, etc... */
}
</code></pre><p>The spin box component can then use this property as a parameter in its template, instead of hard-coding <code>&lt;button&gt;</code>:</p>
<pre><code>const template = `
  &lt;span id=&quot;value&quot;&gt;&lt;/span&gt;
  &lt;${this.buttonTag} id=&quot;upButton&quot;&gt;▲&lt;/${this.buttonTag}&gt;
  &lt;${this.buttonTag} id=&quot;downButton&quot;&gt;▼&lt;/${this.buttonTag}&gt;
`;
</code></pre><p>So by default the template looks like the original one above, and shows <code>button</code> elements for the arrows. But now you can pass a custom element tag to a spin box instance and ask that it be used instead.</p>
<p>A developer who wants to use custom buttons in this spin box starts by creating a standalone custom button by any means:</p>
<p><img src="/static/20241020005925/images/blog/Custom Button.png"></p>
<p>They register this as a custom element, then supply the name of the custom element to a spin box instance:</p>
<pre><code>&lt;spin-box button-tag=&quot;custom-button&quot;&gt;&lt;/spin-box&gt;
</code></pre><p>and the spin box will use that to construct a template that includes <code>custom-button</code>:</p>
<pre><code>&lt;span id=&quot;value&quot;&gt;&lt;/span&gt;
&lt;custom-button id=&quot;upButton&quot;&gt;▲&lt;/custom-button&gt;
&lt;custom-button id=&quot;downButton&quot;&gt;▼&lt;/custom-button&gt;
</code></pre><p>So the final spin box uses the developer’s custom button for the up and down arrow buttons:</p>
<p><img src="/static/20241020005925/images/blog/Spin Box Custom.png"></p>
<p><a href="http://jsbin.com/dikile/edit?html,output">Live demo</a></p>
<p>If the developer always wants to do this, they can create a spin box subclass that sets the default button element to <code>custom-button</code>:</p>
<pre><code>class CustomSpinBox extends HTMLElement {
  constructor() {
    super();
    this.defaultButtonTag = &#39;custom-button&#39;;
  }
}
</code></pre><h2>Advantages of making components customizable this way</h2>
<p>A developer who customizes a spin box component this way doesn&#39;t need to know everything about the internals of the spin box; they just make a button. (To create a good button, they can use the Elix <a href="/elix/WrappedStandardElement">WrappedStandardElement</a> utility class.) Because the spin box will use the button in the right place, the button will get the right positioning and have all the right event handlers to ensure interaction with the rest of the spin box.</p>
<p>This kind of indirection is roughly analogous to a function that accepts another function as a parameter. In this case, we’re creating a custom element that accepts another custom element as a parameter. Complex components can expose as many element parameters as necessary.</p>
<p>This approach works with any web component system that can cope with a tag name that’s specified at runtime. Elix components generally use string templates (as shown above), in which case parameterizing the template is a simple matter. While React components are not (generally) web components, React has long supported similar dynamic construction of a component tree, since a JSX tag name can be a JavaScript class, and that class can be supplied as a component parameter.</p>
<p>Because the core unit of customization is an element, it can do anything! For example, we can create a custom button element that generates <code>mousedown</code> events repeatedly when the user holds down the button. This lets someone customize the spin box in ways that go far beyond what the spin box’s creator can anticipate. (See the <a href="http://jsbin.com/dikile/edit?html,output">demo page</a> for an example.)</p>
<p>Summary:</p>
<ul>
<li>A dev doesn’t have to learn a new styling/theming system. They create their custom elements however they want: in plain JS, using Elix, Stencil, Polymer, whatever.</li>
<li>All the styling they want gets baked into their custom element, and will show up at the right point in the Shadow DOM. So this slips past all the challenges of styling components from the outside. At the same time, just as the Shadow DOM boundary prevents accidental style interference between the outer page and a component, it can likewise prevent accidental style interference between a complex component and any custom elements passed into it as parameters.</li>
<li>We don’t have to invent a new way of naming or registering these customizations: they’re just custom elements registered with <code>customElements.define()</code>.</li>
<li>Customization can go far beyond what’s possible with CSS Custom Properties, and even beyond what would be possible with the proposed <code>::part</code> and <code>::theme</code> syntax for CSS.</li>
<li>Customization can be done on a per-instance basis or by creating new classes.</li>
<li>All of this works in Shadow DOM v1 and Custom Elements v1. You can do this right now.</li>
</ul>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Elix general-purpose web component library releases v1.0.0</title>
      <pubDate>Fri, 09 Feb 2018 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/elix-general-purpose-web-component-library-releases-v100</link>
      <guid>http://component.kitchen/blog/posts/elix-general-purpose-web-component-library-releases-v100</guid>
      <description><![CDATA[
      <p>We&#39;re excited to announce that the <a href="/elix">Elix</a> project we lead has reached its v1.0.0 milestone.</p>
<p>This represents the culmination of over a year of work to create a great set of high-quality, general-purpose web components for common user interface patterns. These include:</p>
<ul>
<li><a href="/elix/SlidingCarousel">SlidingCarousel</a>: a full-featured carousel for images and other elements that includes navigation with touch, a mouse, a keyboard, or a trackpad, as well as accessibility support.</li>
<li><a href="/elix/Drawer">Drawer</a>: a panel that slides in to temporarily present navigation or other UI elements. Includes touch support to swipe the drawer away.</li>
<li><a href="/elix/Tabs">Tabs</a>: useful for classic tabbed UIs or configurable for such patterns as tabbed navigation toolbars.</li>
</ul>
<p>These components, and the others components in the initial Elix release, are all built from <a href="/elix/mixins">focused JavaScript mixins</a> that cover a wide range of basics, from a <a href="/elix/ReactiveMixin">lightweight React-like state rendering architecture</a> to <a href="/elix/TouchSwipeMixin">touch swipe gestures</a> to <a href="/elix/OverlayMixin">managing modal and modeless overlays</a>. Elix&#39;s mixin architecture is what lets the project manage the complexity and subtle details hiding behind seemingly simple components.</p>
<p>Beyond the project&#39;s technology, we&#39;re also proud to be managing the project with an open governance model that includes regular core team discussions and an open <a href="https://github.com/elix/rfcs">Request for Comments</a> process.</p>
<p>The project is already hard at work on its 2.0 release. A big focus for that release will be a system for thoroughly customizing the appearance and behavior of the key parts inside a component.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Our current best answer for styling reusable components: subclassing</title>
      <pubDate>Mon, 27 Nov 2017 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/our-current-best-answer-for-styling-reusable-components-subclassing</link>
      <guid>http://component.kitchen/blog/posts/our-current-best-answer-for-styling-reusable-components-subclassing</guid>
      <description><![CDATA[
      <p>Even though <a href="http://component.kitchen/blog/posts/styling-is-critical-to-web-component-reuse-but-may-prove-difficult-in-practice">styling reusable components is a hard problem</a>, the <a href="/elix">Elix</a> project needs a solution if it&#39;s to keep moving forward. The library&#39;s goal is to provide general-purpose components that can be styled/themed to meet customers&#39; needs. As far as we&#39;re aware, neither the web platform nor component frameworks give us the styling primitives we need. For now, Elix is tackling this styling challenge with subclassing.</p>
<h2>Asking a component what it wants to update</h2>
<p>To begin, our solution relies on the previously-discussed
<a href="http://component.kitchen/blog/posts/a-compact-javascript-mixin-for-creating-native-web-components-in-frpreact-style">ReactiveMixin</a>, to define components in a React-ish, functional-reactive style. That post includes a <a href="https://codepen.io/JanMiksovsky/pen/WLwjwL?editors=1010">live demo</a> of a canonical increment/decrement component created with <code>ReactiveMixin</code>. The source shows a <code>render</code> function that updates DOM whenever state changes.</p>
<p>Let&#39;s add custom styling and behavior to that increment/decrement component. We&#39;ll start by using an Elix mixin called <code>ShadowTemplateMixin</code> to populate the shadow with the same template we used before:</p>
<pre><code>  &lt;template id=&quot;template&quot;&gt;
    &lt;button id=&quot;decrement&quot;&gt;-&lt;/button&gt;
    &lt;span id=&quot;visibleValue&quot;&gt;&lt;/span&gt;
    &lt;button id=&quot;increment&quot;&gt;+&lt;/button&gt;
  &lt;/template&gt;
</code></pre><p>Now we&#39;ll make use of a new Elix mixin called <a href="/elix/RenderUpdatesMixin">RenderUpdatesMixin</a> that asks the component for a set of <em>updates</em> to apply during rendering. The mixin will then update the DOM as requested. The component supplies this <code>updates</code> object as a property, indicating the attributes, classes, styles, and other properties to update:</p>
<pre><code>  get updates() {
    return {
      style: {
        color: this.state.value &lt; 0 ? &#39;red&#39; : null
      },
      $: {
        visibleValue: {
          textContent: this.state.value
        }
      }
    };
  }
</code></pre><p>The top level keys of the <code>updates</code> object will be applied to the component&#39;s host element. Here, the <code>style</code> key says that the host element&#39;s <code>style.color</code> should be updated to <code>&#39;red&#39;</code> when the value is negative, and left unspecified otherwise. It&#39;s not shown above, but a component can also specify keys for <code>attributes</code> and <code>classes</code> to modify those aspects of the host element. Any keys that aren&#39;t special are treated as custom properties and set directly.</p>
<p>The <code>$</code> section contains updates that should be applied to elements in the component&#39;s shadow. When <code>ShadowTemplateMixin</code> sees a template element with an <code>id</code> like <code>&lt;span id=&quot;visibleValue&quot;&gt;&lt;/span&gt;</code>, it defines a reference <code>this.$.visibleValue</code> to point to that span. Here, the <code>updates</code> object is asking to update that span&#39;s <code>textContent</code> to the current number in <code>this.state.value</code>.</p>
<p>This <code>updates</code> getter is equivalent to the imperative:</p>
<pre><code>  [symbols.render]() {
    this.style.color = this.state.value &lt; 0 ? &#39;red&#39; : null;
    this.$.visibleValue.textContent = this.state.value;
  }
</code></pre><h2>A component interaction pipeline</h2>
<p>The use of <code>RenderUpdatesMixin</code> and other Elix mixins lets us construct a pipeline of sorts inside the component:</p>
<pre><code>  events → methods/properties → setState → render → updates → updated DOM
</code></pre><p>When the user clicks the &quot;+&quot; or &quot;-&quot; buttons:</p>
<ol>
<li>A <code>click</code> event fires, which…</li>
<li>sets the <code>value</code> property via a public API, which…</li>
<li>invokes <code>setState</code> to update <code>this.state.value</code>, which…</li>
<li>invokes an internal <code>symbols.render()</code> method that…</li>
<li>asks the component for the state-dependent <code>updates</code> it wants to make which…</li>
<li>get applied to the DOM.</li>
</ol>
<p>And, as a result, the user sees the visible value number go up or down.</p>
<p>The <code>updates</code> are applied via helper functions that make the underlying DOM API calls. There&#39;s no virtual DOM diff&#39;ing going on here, but the number of <code>updates</code> is generally small and targeted to the elements that are actually changing. For the time being, performance seems reasonable.</p>
<h2>Declarative formats as a last resort</h2>
<p>As an aside, I&#39;ve come to generally shy away from declarative formats like the <code>updates</code> object above. People like the concise nature of a declarative format for UI structure or behavior, and such a format can have a place in systems devs are willing to learn.</p>
<p>I think that learning cost is steep, so in code I want other people to use or contribute to, I try to avoid introducing declarative formats. Doing so is tantamount to shouting, <em>Whee! I&#39;ve invented a new domain-specific language for you to learn!</em> The syntax may be JavaScript, but the semantics are opaque — it&#39;s really a tiny interpreted language. Though my concise declarative language may be easy for _me_ to understand, it&#39;s impossible for <em>you</em> to know what effect it will have unless and until you&#39;re willing to learn my new language.</p>
<p>So I currently avoid declarative code unless it has some concrete advantages.</p>
<h2>Styling and specializing via subclasses</h2>
<p>That said, in this case defining <code>updates</code> as an object <em>does</em> offer a real advantage: the updates can be augmented by mixins and subclasses.</p>
<p>When we say we want to let customers style a reusable component, that&#39;s another way of saying we want to let people take existing code and specialize it. A component is just a class, and a traditional means to specialize a class is to create a subclass. So let&#39;s see how subclassing can work here.</p>
<p>Since the <code>updates</code> property sits on the prototype chain, it can be overridden by a mixin or subclass that wants to add or adjust <code>updates</code> for the current state. A mixin/subclass can invoke <code>super</code> to get the base <code>updates</code>, then modify as that base value as it sees fit. E.g., someone could create a custom version of the generic increment/decrement component above:</p>
<pre><code>  class CustomIncrementDecrement extends IncrementDecrement {

    get updates() {

      const base = super.updates;
      const baseColor = base.style &amp;&amp; base.style.color;
      // Pick a color if the base class didn&#39;t specify one.
      const color =  baseColor || (this.state.value &gt; 0 ? &#39;dodgerblue&#39; : null);

      // Merge updates on top of those defined by the base class. This lets us
      // preserve some of the base rendering, while adding our own styling and
      // some unique behavior.
      return merge(base, {
        style: {
          background: &#39;lightgray&#39;,
          color,
          &#39;font-family&#39;: &#39;Helvetica, Arial, sans-serif&#39;,
          &#39;font-weight&#39;: &#39;bold&#39;
        }
      });
    }

  }
</code></pre><p>Here the component indicates that its host element <code>style</code> should be updated with custom colors and fonts. Rather than focusing on CSS rule precedence, the prototype chain determines what <code>updates</code> apply — last writer wins. If you customize my class by subclassing it, your subclass has the last say.</p>
<p>This code relies on a <code>merge</code> helper that generally does a shallow merge, but goes deeper when merging the special keys <code>attributes</code>, <code>classes</code>, <code>style</code>, or <code>$</code>. The merging allows the updates cooperatively constructed by the base class, any mixins, and any subclasses to be efficiently computed and applied.</p>
<p>Applying such state-dependent styling is tricky in CSS: all state would first need to get rendered to the DOM as attributes, then CSS rules would have to be conditional on the presence of those attributes. Overriding such CSS rules requires carefully matching their precedence, otherwise customizations might be overly general or overly specific.</p>
<p>It&#39;s worth noting that mixins/subclasses can inspect the <code>updates</code> requested by the base class, and incorporate those values into their own calculations. In the sample above, the subclass provides a blue <code>color</code> for positive values, but leaves alone the red color the base class provides for negative values.</p>
<h2>Updating shadow parts</h2>
<p>The above code only customizes the host element, which we could do via CSS directly. What we&#39;re really after is a way to customize shadow parts: elements inside the shadow tree. Our customized increment/decrement component can do that through the <code>$</code> key described earlier:</p>
<pre><code>  get updates() {

    const base = super.updates;
    const baseColor = base.style &amp;&amp; base.style.color;
    const color =  baseColor || (this.state.value &gt; 0 ? &#39;dodgerblue&#39; : null);

    const buttonStyle = {
      background: &#39;#444&#39;,
      border: &#39;none&#39;,
      &#39;border-radius&#39;: 0
    };
    const decrementDisabled = this.state.value &lt;= -5;
    const incrementDisabled = this.state.value &gt;= 5;

    return merge(super.updates, {
      style: {
        background: &#39;lightgray&#39;,
        color,
        &#39;font-family&#39;: &#39;Helvetica, Arial, sans-serif&#39;,
        &#39;font-weight&#39;: &#39;bold&#39;
      },
      $: {
        decrement: {
          attributes: {
            disabled: decrementDisabled
          },
          style: merge(buttonStyle, {
            color: decrementDisabled ? &#39;gray&#39; : &#39;white&#39;
          })
        },
        increment: {
          attributes: {
            disabled: incrementDisabled
          },
          style: merge(buttonStyle, {
            color: incrementDisabled ? &#39;gray&#39; : &#39;white&#39;
          })
        }
      }
    });
  }
</code></pre><p><a href="http://jsbin.com/ginijus/edit?html,output">Live demo</a></p>
<p>Above we style the buttons with some base styling. We can also modify attributes or other properties. Here we arrange for the buttons to only allow input values between -5 and 5. (For completeness, we can also impose the same input bounds on the <code>value</code> property exposed in the public API.) We apply conditional styling to show the buttons differently when they&#39;re enabled or disabled.</p>
<h2>Mixins that update light and shadow DOM</h2>
<p>If you&#39;re reluctant to create a class hierarchy, you can do what Elix does and factor most of your code into <a href="/elix/mixins">functional mixins</a>. Mixins allow your code to be reused across classes, and permit a great deal of flexibility.</p>
<p>For example, I&#39;ve previously described how components often need to <a href="http://component.kitchen/blog/posts/your-web-components-with-shadow-dom-may-need-to-update-light-dom-too">update light DOM</a> to support ARIA attributes. To address that scenario, we&#39;ve factored out ARIA attribute handling for list-like components into a mixin called <a href="https://github.com/elix/elix/blob/master/src/AriaListMixin.js">AriaListMixin</a>. That mixin augments the component&#39;s <code>updates</code> getter to apply attributes like <code>role</code>, <code>aria-orientation</code>, and <code>aria-activedescendant</code>.</p>
<h2>Results</h2>
<p>We&#39;ve successfully applied this architecture to the current Elix component set. Using a declarative <code>updates</code> object makes the code very concise, which is good — but also makes the code opaque to outsiders, which is bad. The main win is that we now have a workable method for creating custom-themed versions of these general-purpose components. Significantly, the themed components are just custom elements that can be used by clients like any other web components.</p>
<p>If others come up with other ways to style general-purpose web components, we&#39;d be very interested. In the meantime, we at least have a way to keep moving forward.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Styling is critical to web component reuse, but may prove difficult in practice</title>
      <pubDate>Mon, 20 Nov 2017 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/styling-is-critical-to-web-component-reuse-but-may-prove-difficult-in-practice</link>
      <guid>http://component.kitchen/blog/posts/styling-is-critical-to-web-component-reuse-but-may-prove-difficult-in-practice</guid>
      <description><![CDATA[
      <p>The easiest way to create web components with a distinctive visual style is to bake that style directly into the components&#39; code. Most user interface components are designed to be used solely within the company creating them, in which case baking in styles may be acceptable. But anyone aspiring to create or consume reusable general-purpose web components will have to grapple with the fact that styling components is currently an unsolved problem.</p>
<p>That&#39;s worrisome. Most web components we&#39;ve seen have a built-in visual style so distinctive that, without modification, it would look out of place in an app with someone else&#39;s brand. Not being able to easily theme such a component limits its utility.</p>
<p>Suppose you&#39;re writing a hypothetical custom element called <code>reusable-component</code> and want to let other people style that element. Let&#39;s consider your options for doing so.</p>
<h2>Use CSS Custom Properties</h2>
<p>If you think someone wants to change the background color of your <code>reusable-component</code>, you can define its <code>background-color</code> style with a CSS Custom Property:</p>
<pre><code>  :host {
    background-color: var(--reusable-component-background-color);
  }
</code></pre><p>and your users can then style your component by defining that custom property:</p>
<pre><code>  :root {
    --reusable-component-background-color: blue;
  }
</code></pre><p>With the recent release of Edge 16, the above would now work in all modern browsers.</p>
<p>Unfortunately, this just doesn&#39;t scale well. It&#39;s a pain for you, who must define a new custom property for every CSS attribute someone might conceivably want to override. If your component has internal shadow parts — buttons, etc. — that your users might want to style, you have to define new custom properties for all the interesting CSS attibutes on all those parts. And this will be painful for your users, who have to learn a long new list of custom properties for every component they might want to style.</p>
<h2>Wait for CSS parts and themes</h2>
<p>To solve the above problem, there&#39;s a proposal for <a href="https://tabatkins.github.io/specs/css-shadow-parts/">CSS Shadow Parts</a> which would make it possible to expose designated internal parts as pseudo-elements that can be styled from the outside. This is similar to the way you can style certain native HTML elements in a non-standard way with certain pseudo-elements. For example, WebKit exposes the thumb (handle) of a scroll bar as a pseudo-element <code>::-webkit-scrollbar-thumb</code>, so you can write</p>
<pre><code>  ::-webkit-scrollbar-thumb {
    background: pink;
  }
</code></pre><p>to make scroll bar thumbs pink.</p>
<p>The CSS Shadow Parts spec would let you expose your component&#39;s internal parts for styling. If you had a commit button in the shadow of your <code>reusable-component</code>, you could expose it as a part:</p>
<pre><code>  &lt;button part=&quot;commit-button&quot;&gt;...&lt;/button&gt;
</code></pre><p>And someone can then write:</p>
<pre><code>  reusable-component::part(commit-button) {
    background: pink;
    border: 1px solid red;
    border-radius: 5px;
  }
</code></pre><p>to style the button. That&#39;s a more convenient way to achieve the same thing as CSS Custom Properties. There&#39;s less to document for your users and more flexibility. Your users can apply whatever styling they want without you needing to anticipate everything they might want to do.</p>
<p>There are some downsides, though, when it comes to reusing such a styled custom element.</p>
<h2>Wrapping reusable custom elements + styling</h2>
<p>One key advantage to giving your customer a custom element is that they end up with a single thing that produces a consistent result. But if your customer tries to style your <code>reusable-component</code>, they&#39;ll end up creating a new reuse problem for themselves. People at that company now have to deal with <em>two</em> separate things: 1) your original <code>reusable-component</code> definition, and 2) a stylesheeet with the company&#39;s styling for <code>reusable-component</code> and its parts. On their own, those two entities are independent, with no explicit relationship. Having to track and apply them correctly creates maintenance headaches.</p>
<p>Your customer could define a new <code>component-wrapper</code> element that wraps your original <code>reusable-component</code> and applies the desired styling:</p>
<pre><code>  &lt;template&gt;
    &lt;style&gt;
      reusable-component::part(commit-button) {
        background: pink;
        border: 1px solid red;
        border-radius: 5px;
      }
    &lt;/style&gt;
    &lt;reusable-component&gt;
      &lt;slot&gt;&lt;/slot&gt;
    &lt;/reusable-component&gt;
  &lt;/template&gt;
</code></pre><p>Then your customer can distribute this <code>component-wrapper</code> component internally, and everyone gets both your internal <code>reusable-component</code> and the correct styling in a nice package. (Even if <code>reusable-component</code> is actually defined elsewhere, <code>component-wrapper</code> can express that dependency, so the pieces are linked together.)</p>
<p>But this introduces new challenges:</p>
<ul>
<li>The wrapped component won&#39;t expose the same programmatic API as your original. Your customer will need to carefully reflect the inner component&#39;s API, which may be non-trivial.</li>
<li>Your <code>reusable-component</code> may have styling that&#39;s contingent upon CSS classes or attributes applied to the host element. Unfortunately, that host element is now sitting inside the shadow of the customer&#39;s <code>component-wrapper</code>. Again, the customer writing <code>component-wrapper</code> may have to carefully reflect any classes or attributes to the inner <code>reusable-component</code>. Even if they do that correctly, that may still end up with unexpected behavior.</li>
<li>The inner <code>reusable-component</code> needs to be styled to fill the host <code>component-wrapper</code>, so that if the latter is stretched, the former will be stretched to fit. That&#39;s not hard, but could easily be forgotten.</li>
<li>Certain layout differences will arise. If someone applies <code>padding</code> to the <code>component-wrapper</code>, that will apply to the wrapper, not within the inner <code>reusable-component</code> as they may intend. The customer could expose the inner <code>reusable-component</code> as a new <code>part</code> to address that, but that introduces complexity and conceptual overhead.</li>
<li>Both the element&#39;s tag and class identity will change. A <code>querySelector</code> that looks for <code>reusable-component</code> won&#39;t match <code>component-wrapper</code>. And an <code>instanceof ReusableComponent</code> check will fail when applied to an instance of <code>WrappedComponent</code>. The customer could potentially implement <code>Symbol.hasInstance</code> on their class, but that&#39;s getting complex. In general, it&#39;ll be real work for your customer to create <code>component-wrapper</code> as a drop-in replacement for your <code>reusable-component</code>.</li>
<li>Accessibility may be affected, as the wrapper may show up in the accessiblity tree unless measures are taken to avoid that. This can confuse things. My instinct would be to apply <code>role=&quot;none&quot;</code> to the wrapper to keep it out of the accessibility tree. But if <code>component-wrapper</code> is given a <code>tabindex</code>, a screen reader might get confused when keyboard focus moves to the component.</li>
</ul>
<p>Overall, without an easy repackaging mechanism for themed components, organizations may have difficulty adopting and styling components they acquire from elsewhere.</p>
<h2>Overriding styles can be complex</h2>
<p>It&#39;s been our experience that even general-purpose components can end up with complex styling. People tend to approach component styling/theming as if the components were completely static, but components have dynamic <em>state</em>. State is often implicated in styling. As an example, a native button that&#39;s <code>disabled</code> shows different styling than an enabled button. If someone isn&#39;t carefully considering the <code>:disabled</code> pseudo-class in their button styling, they may end up applying an enabled button appearance to a disabled button.</p>
<p>Web components can have complex internal states, resulting in correspondingly complex internal stylesheets. Overriding such styles will be a delicate matter. To look at some concrete examples, I looked through some internal stylesheets in web components we&#39;ve previously written. Here are some of the CSS selectors I found:</p>
<pre><code>  // From a carousel component
  :host(.overlayArrows) .navigationButton:hover:not(:disabled) { ... }

  // From a tabs component
  :host([generic=&quot;&quot;][tab-position=&quot;right&quot;]) .tab:not(:last-child) { ... }

  // From a toast component
  :host([from-edge=&quot;bottom-right&quot;].opened:not(.effect)) #overlayContent,
  :host([from-edge=&quot;bottom-right&quot;].effect.opening) #overlayContent { ... }
</code></pre><p>Each complex CSS selector in your component may create a challenge for your customer. If the tabs component above exposes an individual <code>tab</code> as a <code>part</code>, what about that <code>:not(:last-child)</code> bit? If your customer writes styles that target the tab part, what styling should apply to the last tab?</p>
<p>In general, even if you can expose an interesting internal part of the component for outside styling, your customer will need to be aware of a large number of conditions that may apply. They could easily end up writing rules that don&#39;t apply (because more specific conditions exist that take precedence) or apply when they shouldn&#39;t (they write rules that are too general).</p>
<p>This is not to say that the CSS Shadow Parts spec won&#39;t be a step forward — it will be — but rather to say that styling components with of normal complexity might turn out to be extremely challenging in practice.</p>
<p>(Aside: It goes without saying that, even if the browser vendors are excited about CSS Shadow Parts and the spec speeds through the standards process, it could still be a very long time until you can take advantage of them in all the browsers and devices you care about. And for what it&#39;s worth, polyfilling new CSS syntax is notoriously difficult to do well.)</p>
<h2>Inline styling</h2>
<p>Your customer trying to use your <code>reusable-component</code> might accomplish a certain degree of styling by applying inline styles to the component&#39;s host element (the top-level <code>&lt;reusable-component&gt;</code> instance sitting in the light DOM). Users of React and other FRP frameworks have found inline styling a powerful way to have a component apply styles to subelements. And more generally, inline styling is usually the easiest way to programmatically adjust an element&#39;s appearance regardless of framework.</p>
<p>However, there are serious challenges using inline styles with web components. Inline styles can&#39;t be used to style internal component parts. That will remain true even if and when the CSS Shadow Parts proposal is adopted, as that only addresses styling with stylesheets. And as noted above, components can have complex state. Writing inline styles for the host element that apply in all conditions is likely too blunt an instrument.</p>
<p>React and similar frameworks already struggle somewhat to deal with styling, but an increase in the presence of complex general-purpose components will make the issue more pressing.</p>
<h2>Other options?</h2>
<p>Given the above, we&#39;re not sure that either CSS Custom Properties, CSS Shadow Parts, or inline styling will be sufficent. We think those platform features are really interesting — it&#39;s just that they may not be enough for what we want to do. We want to create reusable web components that companies can easily brand for their applications, and we&#39;re unsure how to deliver that.</p>
<p>We&#39;re exploring alternative ideas for letting people style our web components, but are very interested in hearing how other people are tackling this problem. If you have ideas, please share.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Is it worth creating web components that work on IE 11? Or Edge?</title>
      <pubDate>Mon, 06 Nov 2017 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/is-it-worth-creating-web-components-that-work-on-ie-11-or-edge</link>
      <guid>http://component.kitchen/blog/posts/is-it-worth-creating-web-components-that-work-on-ie-11-or-edge</guid>
      <description><![CDATA[
      <p>I spent the last week on my least favorite engineering task: trying to get a body of code that works on Chrome/Safari/Firefox to work on Microsoft Edge and Microsoft Internet Explorer. In this case, I&#39;ve been trying to get the Elix project&#39;s unit tests and basic component set working as expected in Edge and IE 11. Such work is never fun. Lately I&#39;ve been wondering whether it&#39;s worth the Elix project&#39;s time to support Microsoft&#39;s browsers.</p>
<h2>Internet Explorer 11</h2>
<p>IE 11 is still supported by Microsoft, but as the mainstream browsers have accelerated away from it, working in IE feels increasingly anachronistic. Although many modern web technologies come with a polyfill or other means to accommodate IE 11, the set of workarounds required today has really piled up.</p>
<p>In the case of the Elix project, here&#39;s the current set of things we need to do for IE 11:</p>
<ul>
<li>Transpile everything to ES5.</li>
<li>Bundle everything into old school script files, since IE can&#39;t handle modules. (While bundling is currently appropriate for production deployments in all browsers, we prefer to have our unit tests and demos run as native modules. Performance is not the primary consideration in those contexts, and we prefer to work directly against the real code. We test in Firefox with module support turned on, although production Firefox doesn&#39;t yet support modules by default.)</li>
<li>Maintain a build process in general. In modern browsers, all of Elix can run directly as is.</li>
<li>Load a Shadow DOM polyfill.</li>
<li>Load a Custom Elements polyfill.</li>
<li>Load a <code>Promise</code> polyfill.</li>
<li>Load a runtime that lets us use transpiled <code>async</code> functions.</li>
<li>Load a <code>Symbol</code> polyfill.</li>
<li>Load a polyfill for <code>Object.assign</code>.</li>
<li>Incorporate many, many workarounds for deficiencies or quirks in IE. Did you know that IE&#39;s <code>classList</code> object has a <code>toggle</code> method that <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/classList#Browser_compatibility">does <em>not</em> support the standard second argument</a>? We know that now, and have had to work around that.</li>
</ul>
<p>Everything we&#39;re forced to add to the above list moves us further and further away from the metal. When we hit a bug, it&#39;s really hard to be confident about where the bug lies. Is it our code? Or somewhere in the list above?</p>
<p>I joked on Twitter that getting a modern web app to run on IE is possible, in the same way it&#39;s possible to <a href="https://www.youtube.com/watch?v=2T5LyEjLfP8">play Doom on a thermostat</a>. In truth, the situation is worse. For all I know, a modern thermostat has better hardware than the 1993 PCs which Doom originally ran on. A better comparison might be that getting a modern web app to run on IE is like getting a modern game title like <em>Horizon Zero Dawn</em> to run on a thermostat.</p>
<h2>Edge</h2>
<p>Microsoft Edge 16 is much better than IE, but it&#39;s still no picnic.</p>
<p>While Edge supports many modern web technologies, Microsoft still hasn&#39;t begun implementing Shadow DOM and Custom Elements. And Edge still suffers from some of the same painful, glaring problems as its predecessor:</p>
<ul>
<li>Edge&#39;s debugging tools are godawful. The debugger is slow. It hangs. It crashes. Its feature set is weak, weak, weak. It&#39;s so flaky, there was a point I couldn&#39;t get Elix&#39;s unit tests to pass in Edge <em>unless the debug tools were closed</em>. Opening the Edge debug tools would introduce unit test failures. How&#39;s that for a friendly developer experience?</li>
<li>Edge&#39;s release cadence is too slow. Today I isolated and filed an <a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14496746/">Edge flex box bug</a>. Even if Microsoft fixes the bug immediately, we could be waiting for the better part of a year to see the fix widely available.</li>
<li>Microsoft has offered no compelling vision of its own for the web. Interest in the Windows API as an application platform appears to be negligible and getting smaller. If that&#39;s correct, you would think Microsoft would invest heavily in a web-focused future. But at this past summer&#39;s Edge Developer Conference, Microsoft presentations were almost entirely focused on ideas introduced by Google long ago.</li>
</ul>
<p>It&#39;s not that Microsoft has forgotten about developers and how to cater to them. I&#39;m continually impressed by the speed and quality of the work currently going into Visual Studio Code and TypeScript, for example. But when it comes to the developer experience in modern browsers, Edge is dead last.</p>
<h2>Market share and inertia</h2>
<p>In discussions about browser support, IE and Edge support are often presumed to be important. But given the current state of the market and some <a href="https://en.wikipedia.org/wiki/Usage_share_of_web_browsers#Summary_tables">usage summaries</a>, I&#39;m not sure that makes sense.</p>
<p>Mobile browser usage exceeds desktop browser usage. On mobile, China&#39;s UC Browser appears to have significantly more market share than IE and Edge on the desktop. Samsung Internet for Android likewise may have already passed Edge in market share, and may soon pass IE.</p>
<p>The cost to keep things working on IE steadily grows. Even when new web advances come with polyfills that run on IE, the combined weight of all that&#39;s necessary to support IE is considerable. How much faster could your team go if it didn&#39;t have to support IE? In the case of the Elix project, I&#39;m guessing IE support soaks up 10% of our time, and 50% of our positive emotions.</p>
<p>And though Edge is Microsoft&#39;s replacement for IE, it&#39;s not clear Edge is on a path to any kind of interesting market position. In the 2 years Edge has been on the market, it&#39;s made miniscule gains. As far as I can tell, everyone who can abandon IE has already moved to Chrome. And those Chrome users must be sticking with Chrome even when they upgrade to a Windows machine capable of running Edge.</p>
<p>In the global political order, the country of France retains one of 5 permanent seats on the U.N. Security Council solely for historical reasons, out of all proportion to its current importance. It feels like similar historical reasons may soon be the primary justification for Microsoft&#39;s position on web app browser requirements lists. Microsoft acts as if it automatically deserves a seat at the table, but I question that. It&#39;s reasonable to ask Microsoft: <em>What are you doing, today, as a browser vendor, that makes you worth the time and energy you force developers to spend on you?</em></p>
<p>As someone who worked at Microsoft for many years, I hold no grudge against them. To the contrary, as an alum, I really <em>want</em> them to be successful. But if they&#39;re going to be relevant as a browser vendor, they&#39;re going to have to do a lot better. In the meantime, I&#39;m wondering whether their browsers are worth the trouble.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Your web components with Shadow DOM may need to update light DOM too</title>
      <pubDate>Mon, 30 Oct 2017 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/your-web-components-with-shadow-dom-may-need-to-update-light-dom-too</link>
      <guid>http://component.kitchen/blog/posts/your-web-components-with-shadow-dom-may-need-to-update-light-dom-too</guid>
      <description><![CDATA[
      <p>Web components and Shadow DOM are practically synonymous, but even web components with a shadow subtree often need to render information into the light DOM. A component might need to:</p>
<ul>
<li>Trigger conditional styling by applying CSS classes or attributes to itself.</li>
<li>Pass information to its light DOM children through CSS classes or attributes.</li>
<li>Set ARIA attributes on itself and its children.</li>
</ul>
<h2>Example: ARIA support</h2>
<p>Suppose you&#39;re creating a single-selection list component, and want to follow the
<a href="https://www.w3.org/TR/wai-aria-practices-1.1/#Listbox">ARIA best practices for list boxes</a>. Perhaps you use your favorite web component library to create a shadow root for your component and clone a template into it. Your component&#39;s shadow might include, among other things, styling for your list container and its light DOM items:</p>
<pre><code>  &lt;template&gt;
    &lt;style&gt;
      :host {
        /* Host element styling goes here */
      }

      ::slotted(*) {
        /* General list item styling goes here */
      }

      ::slotted([aria-selected=&quot;true&quot;]) {
        /* Styling for the selected list item goes here */
      }
    &lt;/style&gt;
    &lt;slot&gt;&lt;/slot&gt;
  &lt;/template&gt;
</code></pre><p>Maybe that&#39;s all that&#39;s happening on the Shadow DOM side of things. Your component will <em>also</em> need to do the following work in the light DOM:</p>
<ol>
<li>Set <code>role=&quot;listbox&quot;</code> on the host element.</li>
<li>If the list is horizontal, set <code>aria-orientation=&quot;horizontal&quot;</code>.</li>
<li>Set <code>role=&quot;option&quot;</code> on all items in the list. Be careful not to mark any
<a href="https://github.com/webcomponents/gold-standard/wiki/Auxiliary-Content">auxiliary content</a> like <code>style</code> as items in the list!</li>
<li>Set <code>aria-selected=&quot;true&quot;</code> on the selected item. (For what it&#39;s worth: I&#39;ve encountered at least one web component
<a href="https://github.com/PolymerElements/iron-menu-behavior/issues/75">bug</a>
where the <a href="https://www.nvaccess.org/">NDVA</a>
screen reader required <code>aria-selected=&quot;false&quot;</code> to be set on all other elements, even for a single selection list.)</li>
<li>Set the host&#39;s <code>aria-activedescendant</code> attribute to be the <code>id</code> of the currently-selected item. If the page author hasn&#39;t supplied <code>id</code> attributes for every item, you will need to generate and assign an <code>id</code> for those items.</li>
</ol>
<p>That&#39;s a lot of work going on in the light DOM! These updates to the light DOM may surprise a page author if they include your list component in markup:</p>
<pre><code>  &lt;accessible-list aria-label=&quot;Fruits&quot; tabindex=&quot;0&quot;&gt;
    &lt;div&gt;Apple&lt;/div&gt;
    &lt;div&gt;Banana&lt;/div&gt;
    &lt;div&gt;Cherry&lt;/div&gt;
  &lt;/accessible-list&gt;
</code></pre><p>At runtime, when this component updates the light DOM, the result might be:</p>
<pre><code>  &lt;accessible-list aria-label=&quot;Fruits&quot; tabindex=&quot;0&quot; role=&quot;listbox&quot;
      aria-activedescendant=&quot;_option0&quot;&gt;
    &lt;div role=&quot;option&quot; id=&quot;_option0&quot; aria-selected=&quot;true&quot;&gt;
      Apple
    &lt;/div&gt;
    &lt;div role=&quot;option&quot; id=&quot;_option1&quot; aria-selected=&quot;false&quot;&gt;
      Banana
    &lt;/div&gt;
    &lt;div role=&quot;option&quot; id=&quot;_option2&quot; aria-selected=&quot;false&quot;&gt;
      Cherry
    &lt;/div&gt;
  &lt;/accessible-list&gt;
</code></pre><p>All this ARIA work is happening in the light DOM, not the Shadow DOM. Work is underway on a better accessibility API, but ARIA attributes are the only solution for the foreseeable future. And as outlined above, your component might have other reasons to update the light DOM.</p>
<p>Generally speaking, you&#39;ll need to write the code to update the light DOM yourself. Most web component frameworks to date have focused on updating Shadow DOM, not light DOM.</p>
<h2>Conclusion</h2>
<p>What goes on in a component&#39;s shadow may only be half the picture — a substantial amount of work may be going on in the light DOM. That&#39;s an important point to consider when you&#39;re deciding how you want to write your component. Most component frameworks are focused on rendering Shadow DOM, so you&#39;ll need to understand what light DOM updates are appropriate and make them yourself.</p>
<p>Code to handle such cases can be complex. For that reason, the Elix project tries to identify common scenarios for updating light DOM and address those with mixins like <a href="/elix/AriaListMixin">AriaListMixin</a>.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>A compact JavaScript mixin for creating native web components in FRP/React style</title>
      <pubDate>Mon, 23 Oct 2017 12:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/a-compact-javascript-mixin-for-creating-native-web-components-in-frpreact-style</link>
      <guid>http://component.kitchen/blog/posts/a-compact-javascript-mixin-for-creating-native-web-components-in-frpreact-style</guid>
      <description><![CDATA[
      <p>
  Perhaps you like the benefits of functional reactive programming, but would
  like to create native web components with minimal overhead. This post explores
  a relatively simple JavaScript mixin that lets you author web components in a
  functional reactive programming (FRP) style modeled after React. This mixin
  focuses exclusively on managing state and determining when the state should be
  rendered. You can use this mixin with whatever DOM rendering technology you
  like: virtual-dom, hyperHTML, lit-html, plain old DOM API calls, etc.
</p>
<p>
  I spent several months this summer writing React and Preact components, and
  the values of an FRP model were immediately clear. As React advocates claim,
  using FRP does indeed make state easier to reason about and debug, code
  cleaner, and tests easier to write.
</p>
<p>
  I wanted to bring these reactive benefits to the
  <a href="/elix/">Elix web components</a>
  project which Component Kitchen leads. Elix already uses
  <a href="/elix/mixins">functional mixins</a>
  extensively for all aspects of component functionality for everything from
  accessibility to touch gestures. I wanted to see if it were possible to
  isolate the core of an FRP architecture into a functional mixin that could be
  applied directly to HTMLElement to create a reactive web component.
</p>
<p>
  You can use the resulting
  <a href="/elix/ReactiveMixin">ReactiveMixin</a>
  to create native web components in a functional reactive style. FRP frameworks
  often use a canonical increment/decrement component as an example. The
  ReactiveMixin version looks like this:
</p>

<pre>
  
    import ReactiveMixin from '.../ReactiveMixin.js';

    // Create a native web component with reactive behavior.
    class IncrementDecrement extends ReactiveMixin(HTMLElement) {

      // This property becomes the initial value of this.state at constructor time.
      get defaultState() {
        return { value: 0 };
      }

      // Provide a public property that gets/sets state.
      get value() {
        return this.state.value;
      }
      set value(value) {
        this.setState({ value });
      }

      // Expose "value" as an attribute.
      attributeChangedCallback(attributeName, oldValue, newValue) {
        if (attributeName === 'value') {
          this.value = parseInt(newValue);
        }
      }
      static get observedAttributes() {
        return ['value'];
      }

      // … Plus rendering code, with several options for rendering engine
    }

    customElements.define('increment-decrement', IncrementDecrement);

</pre>

<p>
  <a href="https://codepen.io/JanMiksovsky/pen/WLwjwL?editors=1010">Live demo</a>
</p>
<p>
  You end up with something that’s very similar to React’s Component class (or,
  more specifically, PureComponent), but is a native HTML web component. The
  compact mixin provides a small core of features that enable reactive web
  component development in a flexible way.
</p>

<h2>Defining state</h2>
<p>
  ReactiveMixin gives the component a member called <code>this.state</code>, a
  dictionary object with all state defined by the component and any of its other
  mixins. The <code>state</code> member, which is read-only and immutable, can
  be referenced during rendering, and to provide backing for public properties
  like the <code>value</code>
  getter above.
</p>
<p>
  ReactiveMixin provides a <code>setState</code> method the component invokes to
  update its own state. The mixin sets the initial state in the constructor by
  passing the value of the <code>defaultState</code> property to
  <code>setState</code>.
</p>

<h2>Detecting state changes</h2>
<p>
  When you call <code>setState</code>, ReactiveMixin updates the component’s
  state, and then invokes a <code>shouldComponentUpdate</code> method to
  determine whether the component should be rerendered.
</p>
<p>
  The default implementation of <code>shouldComponentUpdate</code> method
  performs a shallow check on the state properties: if any top-level state
  properties have changed identity or value, the component is considered dirty,
  prompting a rerender. This is comparable to the similar behavior in
  <code>React.PureComponent</code>. In our explorations, we have found that our
  web components tend to have shallow state, so pure components are a natural
  fit. You can override this to provide a looser dirty check (like
  <code>React.Component</code>) or a tighter one (to optimize performance, or
  handle components with deep state objects).
</p>
<p>
  If there are changes <em>and</em> the component is in the DOM, the new state
  will be rendered.
</p>

<h2>Rendering</h2>
<p>
  This mixin stays intentionally independent of the way you want to render state
  to the DOM. Instead, the mixin invokes an internal component method whenever
  your component should render, and that method can invoke whatever DOM updating
  technique you like. This could be a virtual DOM engine, or you could just do
  it with plain DOM API calls.
</p>
<p>
  Here’s a plain DOM API render implementation for the increment/decrement
  example above. We’ll start with a template:
</p>
<pre>

    &lt;template id="template">
      &lt;button id="decrement">-&lt;/button>
      &lt;span id="value">&lt;/span>
      &lt;button id="increment">+&lt;/button>
    &lt;/template>

</pre>

<p>
  To the component code above, we’ll add an internal render method for
  ReactiveMixin to invoke. The mixin uses a <code>Symbol</code> object to
  identify the internal render method. This avoids name collisions, and
  discourages someone from trying to invoke the render method from the outside.
  (The render method can become a private method when JavaScript supports
  those.)
</p>

<pre>

    import symbols from ‘.../symbols.js’;

    // This goes in the IncrementDecrement class ...
    [symbols.render]() {
      if (!this.shadowRoot) {
        // On our first render, clone the template into a shadow root.
        const root = this.attachShadow({ mode: 'open' });
        const clone = document.importNode(template.content, true);
        root.appendChild(clone);
        // Wire up event handlers too.
        root.querySelector('#decrement').addEventListener('click', () => {
          this.value--;
        });
        root.querySelector('#increment').addEventListener('click', () => {
          this.value++;
        });
      }
      // Render the state into the shadow.
      this.shadowRoot.querySelector('#value').textContent = this.state.value;
    }

</pre>

<p>
  That’s all that’s necessary. The last line is the core bit that will update
  the DOM every time the state changes. The two buttons update state by setting
  the <code>value</code> property, which in turn calls
  <code>setState</code>.
</p>
<p>
  This ReactiveMixin would also be a natural fit with template literal libraries
  like
  <a href="https://github.com/PolymerLabs/lit-html/">lit-html</a> or
  <a href="https://github.com/WebReflection/hyperHTML/">hyperHTML</a>.
  That could look like:
</p>

<pre>

    import { html, render } from ‘.../lit-html.js’;
    import symbols from ‘.../symbols.js’;

    // Render using an HTML template literal.
    [symbols.render]() {
      if (!this.shadowRoot) {
        this.attachShadow({ mode: 'open' });
      }
      const template = html`
        &lt;button on-click=${() => this.value-- }>-&lt;/button>
        &lt;span>${this.state.value}&lt;/span>
        &lt;button on-click=${() => this.value++ }>+&lt;/button>
      `;
      render(template, this.shadowRoot);
    }
  
</pre>

<p>
  The creation of the shadow root and the invocation of the rendering engine are
  boilerplate you could factor into a separate mixin to complement
  ReactiveMixin.
</p>

<h2>Web component and FRP lifecycle methods</h2>
<p>
  Since components created with this mixin are still regular web components,
  they receive all the standard lifecycle methods. ReactiveMixin augments
  <code>connectedCallback</code> so that a component will be rendered when it’s
  first added to the DOM.
</p>
<p>
  The mixin provides React-style lifecycle methods for
  <code>componentDidMount</code>
  (invoked when the component has finished rendering for the first time) and
  <code>componentDidUpdate</code> (whenever the component has completed a
  subsequent rerender). The mixin doesn’t provide
  <code>componentWillUnmount</code>; use the standard
  <code>disconnectedCallback</code> instead. Similarly, use the standard
  <code>attributeChangedCallback</code> instead of
  <code>componentWillReceiveProps</code>.
</p>

<h2>Conclusion</h2>
<p>
  This ReactiveMixin gives us much of what we like about React, but lets us
  write web components which are closer to the metal. All it does is help us
  manage a component’s state, then tell our component when it needs to render
  that state to the DOM. Separating state management from rendering is useful —
  we’ve already changed our minds about which rendering engine to use several
  times, but those changes entailed only minimal updates to our components.
</p>
<p>
  The coding experience feels similar to React’s, although I don’t see a need to
  make the experience identical. For example, I thought setState would work well
  as an `async` Promise-returning function so that you can wait for a new state
  to be applied. And it’s nice to avoid all the platform-obscuring abstractions
  (e.g., synthetic events) React pushes on you.
</p>
<p>
  We’re using this ReactiveMixin to rewrite the Elix components in a functional
  reactive style. That work is proceeding fairly smoothly, and we’re moving
  towards an initial 1.0 release of Elix that uses this approach in the near
  future. In the meantime, if you’d like to play with using this mixin to create
  web components, give it a try and let us know how it goes.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>A look at Stencil.js</title>
      <pubDate>Mon, 02 Oct 2017 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/a-look-at-stenciljs</link>
      <guid>http://component.kitchen/blog/posts/a-look-at-stenciljs</guid>
      <description><![CDATA[
      <p>
  <a href="https://stenciljs.com/">Stencil.js</a> was introduced recently at
  the latest <a href="https://youtu.be/UfD-k7aHkQE">Polymer Summit</a>. Some
  of our partners had questions as to what exactly Stencil is, what it creates,
  and what are the implications of its use. We thought we'd have a look. Here's
  what we discovered.
</p>

<h3>
  What Stencil <i>is</i>
</h3>
<p>
  Stencil is three things:
  <ol>
    <li>
      A component framework, similar in intent to Polymer and Skate.js, for 
      building web components using Functional Reactive Programming (FRP)
      techniques including state-triggered render methods
    </li>
    <li>
      A build system that leverages ES7 decorators through the use of 
      TypeScript, Rollup, Webpack, and Babel
    </li>
    <li>
      An optional application framework
    </li>
  </ol>
</p>

<h3>
  What Stencil <i>is not</i>
</h3>
<p>
  <ol>
    <li>
      A framework for building any other type of component than web components
    </li>
    <li>
      A component framework that produces web components supporting Shadow DOM
    </li>
  </ol>
</p>

<h2>
  Details
</h2>
<p>
  Stencil provides a fairly immersive development environment which is 
  installed via a clone of either their 
  <a href="https://github.com/ionic-team/stencil-starter">application starter project</a>, 
  or a simplified 
  <a href="https://github.com/ionic-team/stencil-component-starter">component builder project</a>. 
  The former allows you to build web components within the context of an 
  application, presumably where there is a tight coupling between component 
  design and application needs. The latter appears to be a more standalone 
  approach to building web components.
</p>
<p>
  There is a heavy influence of React here, with the application starter project 
  feeling similar in nature to Facebook’s 
  <a href="https://github.com/facebookincubator/create-react-app">create-react-app</a> 
  project template. Beyond the development environment particulars, Stencil 
  leans on React-like idioms for binding component state change to a render 
  function that outputs JSX.
</p>
<p>
  This is a similar approach to web component architectural design as 
  <a href="https://github.com/skatejs/skatejs">Skate.js</a> with the recent 
  difference of Skate’s offering of pluggable renderers (JSX, lit-html, template 
  strings, etc) versus Stencil’s fixed reliance on JSX. Skate appears to offer 
  a much reduced development environment beyond the JavaScript libraries it 
  provides for its implementation.
</p>
<p>
  Stencil specifies a canonical class model for defining a web component, 
  relying on ES7 decorators for signaling to the build system how the resulting 
  definition is to be assembled with Stencil library routines. The result is 
  then transpiled into ES5 JavaScript consumable web component code, coupled 
  with demand-loaded polyfills where required. Stencil refers to this build
  pipeline as a compiler.
</p>
<p>
  Where the “compiled” aspect comes in is the binding of the Stencil component 
  definition code with library code that somewhat opaquely provides 
  partial-specification web component support. More on that later. 
</p>

<h2>
  Frameworky stuff
</h2>
<p>
  The Stencil component class template is an abstraction that binds with Stencil 
  library code. In this sense, Stencil is a framework and the usage of the 
  Vanilla JavaScript™ terminology feels a bit like a cheat, if you’re of the 
  opinion that Vanilla JavaScript implies the code is all in front of you as a 
  developer with nothing tricky up the sleeves. In the sense that it has 
  nothing at all to do with Polymer and Polymer’s tricks, then, yes, it’s 
  vanilla. The discussion of what should define a Vanilla Javascript component 
  is probably worth a blog post of its own.
</p>
<p>
  But as an example of this sleight of hand, Stencil builds components that do 
  not make use of or rely on the Shadow DOM portion of the specification, 
  resulting in custom elements alone, yet it magically supports the use of the 
  <code>&lt;slot&gt;</code> tag. It does so by providing framework/library code 
  that parses for named slots and manages the child element merger on its own.
  Whether the full, expected functionality of slots under Shadow DOM is 
  supported, experimentation and probably more than a little cold sweat might
  be called for.
</p>
<p>
  There are other examples of this sort of polyfill/framework/non-vanilla 
  construct within Stencil’s definition/bind-to-library/transpile lifecycle, 
  including enforcing property immutability within a component’s internal code, 
  but the key point in analyzing Stencil is to recognize it’s not just an 
  ES5-generator for web components (as well as, don’t forget, not a React 
  component generator, or a Vue component generator, etc, etc). It’s an 
  opinionated framework.
</p>
<p>
  The documentation describes the use of several decorators for fleshing out a 
  component’s definition:
  <ul>
    <li>
      The <code>@Prop</code> decorator specifies properties, reflected to 
      attributes, that are immutable component code internally.
    </li>
    <li>
      The <code>@State</code> decorator enables a component to have internal 
      state that cannot be changed directly by a user. A change in state results 
      in the render function being called.
    </li>
    <li>
      The <code>@Method</code> decorator identifies public API methods
    </li>
    <li>
      The <code>@Element</code> decorator is how to get access to the host 
      element within the class instance. This returns an instance of an 
      <code>HTMLElement</code>, so standard DOM methods/events can be used here.
    </li>
    <li>
      <code>@Event</code> and <code>@Listen</code> set up native DOM events and 
      event handlers
    </li>
  </ul>
</p>
<p>
  Stencil also provides hooks for specifying web component lifecycle callback 
  code.
</p>
<p>
  Further in the way of framework flavor, Stencil provides mechanisms for 
  rendering Stencil web components via server side rendering, and for generating 
  pre-rendered static html+css pages. Stencil also provides objects for 
  integrating with Node.js/Express.js web servers.
</p>
<p>
  The inclusion of an add-on <code>stencil-router</code> is an additional 
  reminder that Stencil is as much about building Stencil-based applications as 
  it is about generating web components.
</p>

<h2>
  Distribution of Stencil components
</h2>
<p>
  Stencil provides a non-transparent means for setting up Stencil components for 
  distribution. It’s non-transparent in the sense that it relies on its build 
  tools coupled with a <code>stencil.config.js</code> configuration file and 
  expected additions to the project’s <code>package.json</code> file. Once 
  published to npm, the component package can be referenced through HTML via:
</p>
<p>
  <code>
    &lt;script src='https://unpkg.com/my-name@0.0.1/dist/myname.js'&gt;&lt;/script&gt;
  </code>
</p>
<p>
  In a Stencil application, a published and npm-installed component package can 
  be accessed through the application’s <code>stencil.config.js</code> file 
  where the components to be “imported” are added to the collections key. It’s 
  not apparent to me whether JavaScript <code>import</code> is supported.
</p>

<h2>
  Summary
</h2>
<p>
  As a development platform, Stencil.js looks as enticing as React in that 
  expressiveness through abstraction and FRP idioms make reasoning about the 
  architecture easy. The toolset is impressive as a means of building
  web component based web applications, and feels like the result of a team
  actually dogfooding their own products against it - just as the Stencil
  team suggests in their talks.
</p>
<p>
  The potential drawbacks in adopting it for your own project are
  clear, though: the fixed JSX renderer, abstractions hidden behind the 
  library/transpile system, and the adaptation of <code>&lt;slot&gt;</code> 
  into a Custom Element implementation despite its Shadow Dom origins. These 
  framework decisions might make moving away from Stencil difficult while 
  preserving the component design in another web component development 
  environment.
</p>
      ]]>
      </description>
    </item>
  

    <item>
      <title>Get involved with Elix</title>
      <pubDate>Mon, 08 May 2017 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/get-involved-with-elix</link>
      <guid>http://component.kitchen/blog/posts/get-involved-with-elix</guid>
      <description><![CDATA[
      <p>
  Jan and I have been very busy the past several months starting up the
  <a href="/elix">Elix project</a>, a library of high-quality web
  components designed to support the 
  <a href="https://github.com/webcomponents/gold-standard/wiki">Gold Standard Checklist</a>.
  Together with developers from Comcast, <a href="https://vaadin.com/home">Vaadin</a>, 
  <a href="https://www.commontime.com/">CommonTime</a>, and Google,
  we participate in the Elix Core Team with Component Kitchen serving as a host
  organization for the project.
</p>

<p>
  Much of what Jan and I have written about on this blog up to this point has
  led to the creation of Elix. Rather than restating what we've said in the
  past, we'd like to provide some getting-started tips and invite members 
  of the web application development community to contribute to Elix. Elix
  is just getting off the ground, but there is enough in place to serve as 
  examples and self-documenting guides for helping us continue to make progress.
</p>

<p>
  The <a href="/elix">Elix</a> site is a great place to
  start as well as to return to for architectural design overviews and 
  elements/mixins documentation. Also, Jan and I have spoken extensively
  about Elix, starting with an 
  <a href="http://thewebplatformpodcast.com/126-gold-standard-checklist-for-web-components">episode discussing 
  the Gold Standard</a>
  and following up with a 
  <a href="http://thewebplatformpodcast.com/129-elix-project">discussion about the Elix project</a>
  on <a href="http://thewebplatformpodcast.com/">The Web Platform Podcast</a>
  earlier this year.
</p>

<p>
  Jan also gave a <a href="https://youtu.be/3Xq0IrFbZGg">great presentation</a>
  at the 
  <a href="https://wcremoteconf.com/">Web Components Remote Conf</a>
  which we highly encourage you to watch.
</p>

<p>
  While we are looking forward to working with experienced industry partners,
  Elix is also a great open source project for those, such as university
  students, looking to gain their initial experience in web development work,
  and we extend a particular welcome to these contributors.
</p>
<p>
  Why contribute to the Elix project?
  <ol>
    <li>
      Web application and front-end development is a vibrant area of
      software engineering
    </li>
    <li>
      Web Components, as they become pervasively supported on the major 
      browsers, are a smart architectural approach for building web 
      applications, especially alongside popular frameworks such as React
    </li>
    <li>
      Therefore, this is a great time to invest in building knowledge and 
      expertise in this area
    </li>
    <li>
       Elix is just getting off the ground, so it's also a great way to begin 
       building and extending expertise in Web Components, especially given 
       Elix's focus on native JavaScript with a minimal toolchain
    </li>
    <li>
      With limited early contributors, you can, over time, establish some name 
      recognition in what we hope will become an important industry open source 
      project
    </li>
  </ol>
</p>

<p>
  There are many ways to get started in building up your understanding and 
  expertise. A few include:
  <ol>
    <li>
      Simply reading the documentation and studying, in general, the ideas 
      behind Web Components, progressive web applications, and web application 
      frameworks
    </li>
    <li>
      Reviewing and extending the
      <a href="/elix">Elix documentation</a>
    </li>
    <li>
      Building unit tests
    </li>
    <li>
      Building sample/demo progressive web applications that make use of Elix elements
    </li>
    <li>
      Working on existing/new 
      <a href="/elix/elements">elements</a>
      and <a href="/elix/mixins">mixins</a>
    </li>
  </ol>
</p>

<p>
  Any level of invovlement is welcome, and you may find that spending even
  only an hour a day will soon lead to deep understanding and the ability to
  make significant contributions to the project.
</p>

<p>
  Take a look at the links, read about Web Components, frameworks such as 
  <a href="https://facebook.github.io/react/">React</a>, and general 
  <a href="https://developers.google.com/web/ilt/pwa/">progressive web application</a> 
  information. You can clone the 
  <a href="https://github.com/elix/elix">Elix GitHub project</a>, read the 
  <a href="https://drive.google.com/drive/folders/0B_3KUXczQ13ATGhZWTRkb0hPWEk?usp=sharing">Elix core team meeting notes</a>, 
  and gear yourself up for involvement. Follow the Elix project on Twitter at 
  <a href="https://twitter.com/ElixElements">@ElixElements</a>.  
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Our experience upgrading web components from Shadow DOM/Custom Elements v0 to v1</title>
      <pubDate>Mon, 17 Oct 2016 07:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/our-experience-upgrading-web-components-from-shadow-domcustom-elements-v0-to-v1</link>
      <guid>http://component.kitchen/blog/posts/our-experience-upgrading-web-components-from-shadow-domcustom-elements-v0-to-v1</guid>
      <description><![CDATA[
      <p>
  With Google now shipping both Shadow DOM v1 and Custom Elements v1 in Chrome,
  and Apple shipping Shadow DOM v1 in Safari, we’ve been upgrading the
  <a href="https://github.com/basic-web-components/basic-web-components">Basic Web Components</a>
  library from the original v0 specs to v1. Here’s what we learned, in case
  you’re facing a similar upgrade of your own components, or just want to
  understand some ramifications of the v1 changes.
</p>

<h2>Upgrading components to Shadow DOM v1: Easy!</h2>
<p>
  Google developer Hayato Ito has a great summary of
  <a href="http://hayato.io/2016/shadowdomv1/">What’s New in Shadow DOM v1</a>.
  Adapting our components to accommodate most of the changes on that list was
  trivial, often just a matter of Find and Replace. The v0 features that were
  dropped were ones we had never used (multiple shadow roots, shadow-piercing
  CSS combinators) or had avoided (<code>&lt;content select=”...”></code>), so
  their absence in v1 did not present a problem.
</p>
<p>
  One v1 feature that we had heavily lobbied for was the addition of the
  slotchange event. The ability of an element to detect changes in its own
  distributed content is a critical addition to the spec. We are happy to
  replace our old, hacky method of detecting content changes with the new,
  official slotchange event. This allows us to easily write components that meet
  the
  <a href="https://github.com/webcomponents/gold-standard/wiki/Content-Changes">Content Changes</a>
  requirement on the Gold Standard checklist for web components.
</p>

<h2>Upgrading components to Custom Elements v1: Some challenges</h2>
<p>
  The changes from Custom Elements v0 to v1 were more challenging, although some
  were easy:
</p>
<ul>
  <li>
    Replacing <code>document.registerElement()</code> with
    <code>customElements.define()</code>. No issues.
  </li>
  <li>
    Drop support for <code>is=""</code> syntax. Ever since Apple announced that
    they would not support the syntax, we’ve avoided it. As a workaround, a
    while back we created a general wrapper component called
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-wrapped-standard-element">WrappedStandardElement</a>.
  </li>
  <li>
    Tweaks in lifecycle callback timing. There were spirited spec debates over
    the exact points in time when a component’s lifecycle callbacks should be
    invoked, but we didn’t notice any practical differences between v0 and v1.
  </li>
  <li>
    <code>attributeChangedCallback</code> automatically invoked at constructor
    time. This was a welcome change that allowed us to simplify our
    <a href="https://github.com/basic-web-components/basic-web-components/blob/master/packages/basic-component-mixins/docs/AttributeMarshalling.md">AttributeMarshalling</a>
    mixin, which automatically translates attribute changes into property
    updates.
  </li>
</ul>

<p>
  One small obstacle we hit is that a v1 component now needs to declare which
  attributes it wants to monitor for changes. This performance optimization in
  Custom Elements v1 requires that your component declare an
  <code>observedAttributes</code> array to avoid getting
  <code>attributeChangedCallback</code> invocations for attributes you don’t
  care about. That sounds simple, but in our mixin-based approach to writing
  components, it was actually a bit of a pain. Each mixin had to not only
  declare the attributes it cared about, but it had to cooperatively construct
  the final <code>observedAttributes</code> array. We eventually hit on the idea
  of having the aforementioned AttributeMarshalling mixin programmatically
  inspect the component class for all custom properties, and automatically
  generate an appropriate array of attributes for
  <code>observedAttributes</code>. That seems to be working fine.
</p>
<p>
  A more problematic change in v1 is that component initialization is now done
  in a class constructor instead of a <code>createdCallback</code>. The change
  itself is a desirable one, but we expected it would be tricky, and it was. The
  biggest problem we’ve encountered is that the list of
  <a href="http://w3c.github.io/webcomponents/spec/custom/#custom-element-conformance">Requirements for custom element constructors</a>
  prohibits a new component from setting attributes in its constructor. The
  intention, as we understand it, is to mirror standard element behavior.
  Calling <code>createElement('div')</code> returns a clean div with no
  attributes, so calling <code>createElement('my-custom-element')</code> should
  return a clean element too, right?
</p>
<p>
  That sounds good but turns out to be limiting. Custom elements can’t do
  everything that native elements can, and sometimes the only way to achieve a
  desired result is for a custom element to add an attibute to itself:
</p>
<ol>
  <li>
    A component wants to define default ARIA attributes for accessibility
    purposes. For example, our
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-list-box">ListBox</a>
    component needs to add <code>role=”listbox”</code> to itself. That helps a
    screen reader interpret the component correctly, without the person using
    the component having to know about or understand ARIA. That
    <code>role</code> attribute is a critical part of a ListBox element, and
    needs to be there by default.
  </li>
  <li>
    A component wants to reflect its state as CSS classes so that component
    users can provide state-dependent styling. For example, our
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-collapsible-panel">CollapsiblePanel</a>
    component wants to let designers style its open and closed appearances by
    adding CSS classes that reflect the open/closed state. This component
    reflects the current state of its <code>closed</code> property via CSS
    classes. It’s reasonable that a component would want to set the initial
    state of that <code>closed</code> property in a constructor. But setting
    that default value of that property in the constructor will trigger the
    update to the CSS class, which is not permitted in Custom Elements v1.
  </li>
</ol>

<p>
  In these cases, it doesn’t seem like it would be hard to just set the
  attributes in the connectedCallback instead. In practice, it introduces
  complications because a web app author that instantiates a component would
  like to be able to immediately make changes to it before adding it to the
  document. In the first scenario above, the author might want to adjust the
  <code>role</code> attribute:
</p>


<pre>
class ListBox extends HTMLElement {
  connectedCallback() {
    this.setAttribute('role', 'listbox');
  }
}

let listBox = document.createElement('basic-list-box');
listBox.setAttribute('role', 'tabs'); // Set custom role
document.body.appendChild(listBox); // connectedCallback will overwrite role!
</pre>


<p>
  Because ListBox can’t apply a default <code>role</code> attribute at
  constructor time, its connectedCallback will have to take care to see if a
  <code>role</code> has already been set on the component before applying a
  default value of <code>role=”listbox”</code>. It’s easy for a developer to
  forget such a check. The result will likely be components that belatedly apply
  default attributes, stomping on top of attributes that were applied after the
  constructor and before the component is added to the document.
</p>
<p>
  Another problem comes up in the second scenario above. The creator of the
  component would like to be able to write a property getter/setter that
  reflects its state as CSS classes:
</p>


<pre>
let closedSymbol = Symbol('closed');

class CollapsiblePanel extends HTMLElement {

  constructor() {
    // Set defaults
    this.closed = true; // Sets the “class” attribute, so will throw!
  }

  get closed() {
    return this[closedSymbol];
  }
  set closed(value) {
    this[closedSymbol] = value;
    this.toggleClass('closed', value);
    this.toggleClass('opened', !value);
  }

}
</pre>


<p>
  Since the above code won’t work, the developer has to take care to defer all
  attribute writes (including manipulations of the classList, which updates the
  <code>class</code> attribute) to the <code>connectedCallback</code>. To make
  that tolerable, we ended up creating
  <a href="https://github.com/basic-web-components/basic-web-components/blob/master/packages/basic-component-mixins/src/safeAttributes.js">safeAttributes</a>,
  a set of helper functions that can defer premature calls to
  <code>setAttribute()</code> and <code>toggleClass()</code> to the
  <code>connectedCallback</code>.
</p>
<p>
  That’s working for now, but it feels like the v1 restrictions on the
  constructor are overly limiting. The intention is to ensure that the component
  user gets a clean element from <code>createElement()</code> — but if the
  resulting element is just going to add attributes to itself in the
  <code>connectedCallback</code>, is that element really clean? As soon as the
  attribute-less element is added to the document, it will suddenly grow new
  attributes. In our opinion, that feels even more surprising than having
  <code>createElement()</code> return an element with default attributes.
</p>

<h2>The current state of Shadow DOM and Custom Elements v1</h2>
<p>
  Overall, we’re excited that we’ve got our components and mixins working in
  production Chrome 54, which just shipped last week with support for both
  Shadow DOM v1 and Custom Elements v1. The Chrome implementation of the specs
  feels solid, and we haven’t hit any bugs.
</p>
<p>
  Shadow DOM v1 is also coming together in Safari, including in Mobile Safari.
  At the moment, it feels more like a beta than a production feature — we’ve hit
  a number of critical bugs in WebKit that prevent most of our components from
  working. Apple’s working through those bugs, and we hope to see WebKit’s
  support for Shadow DOM improve soon.
</p>
<p>
  In the meantime, Google has been doing the thankless, herculean task of
  upgrading the Shadow DOM and Custom Elements polyfills to the v1 specs. That’s
  great to see, because without an answer for older browsers, web components
  won’t see wide adoption. At the moment, the v1 polyfills also feel like a
  beta, but they’re coming along quickly. As soon as the polyfills are stable
  enough, we’re looking forward to making a full release of Basic Web Components
  based on the v1 specs.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Can Service Workers service background applications?</title>
      <pubDate>Mon, 13 Jun 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/can-service-workers-service-background-applications</link>
      <guid>http://component.kitchen/blog/posts/can-service-workers-service-background-applications</guid>
      <description><![CDATA[
      <p>
  I had a thought experiment on how I might port an application I once
  developed for native Android to a web app, even if it were to run solely
  on Android devices. The application behaves like a mantle clock: every
  fifteen or thirty minutes, it wakes up and plays a custom chime. My son
  used to call it "Big Ben in Your Pocket."
</p>
<img style="max-width:100%; height:auto;" src="http://hyperfine.com/staticfiles/ct/images/banner.jpg">
<p>
  The app seems perfect for a web app approach since it's primarily visual UI and
  it plays an audio resource on a timer. The problem is that you want the
  app to wake up and chime on a regular schedule, even if the user doesn't
  have the application running in the foreground. In native Android, you
  employ an Android Service which runs in the background on a thread separate
  from the application's UI thread, and can run and wake up when the application
  isn't running in the foreground. In many ways, Android Services feel like
  Service Workers but with a critical exception: Service Workers have
  indeterminate lifetimes and I think the only way to wake them up is for
  them to receive a push notification. Android Services can be woken up
  through events like a local alarm notification.
</p>
<p>
  My question for the Service Worker folks is: how would I implement this
  as a web application? Conceptually, I'd have a timer running in a Service
  Worker, but since the Service Worker can be killed by the "OS" at any time,
  the timer dies with it. Waking up the Service Worker with a push notification
  is not a good local solution, as some server-based service would have to
  send 15-minute wakeup calls to all subscribed users. I think Greenwich
  already cornered the worldwide timer market.
</p>
<p>
  There are other application examples where you want local wake up of
  a background application. The question I have is whether Service Workers will
  make these web applications possible.
</p><p>
  While I was pondering this question, I noticed that
  <a href="https://twitter.com/slightlylate">Alex Russell</a> over at Google has a 
  really good recent
  <a href="https://infrequently.org/2016/06/pwa-discovery-you-aint-seen-nothin-yet/">
  post on installation strategies for PWAs</a>, and he
  references <a href="https://twitter.com/Lady_Ada_King">Ada Rose Edwards</a>'
  <a href="https://ada.is/blog/2016/06/01/yet-another-progressive-webapp-post/">
  followup discussion</a> on the state of web applications. Ada's post
  led me to read more on Financial Times's strategy for building web applications
  with support for offline (disconnected) and unreliable network conditions.
  Financial Times uses the older Application Cache (AppCache) mechanism since
  the more modern Service Worker currently has limited browser support outside 
  of Chrome. AppCache is implemented on a wider range of browsers, and in
  particular, Safari.
</p>
<p>
  The difficulty from a developer or product planner perspective in attempting
  to move away from native app development and toward PWA is bridging the
  differences between browser capabilities. For certain application types, 
  being able to run offline is everything, and without universal 
  (or at least modern) browser support for this,
  you're going to have a difficult time convincing people that limiting your
  customer base only to specific optimal browsers is a good thing. On the other hand,
  developing your web app to support both Service Worker with an AppCache
  fallback seems akin to balancing the development costs between native
  Android and iOS. So what's the best strategy to move forward today?
</p>
<p>
  I asked, and 
  <a href="https://twitter.com/robbearman/status/739879533625516032">Ada gave a response</a>:
  target Service Worker browsers. The lack of universal support remains
  an open issue.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>We made our static site work offline in a day using the Service Worker API</title>
      <pubDate>Mon, 02 May 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/we-made-our-static-site-work-offline-in-a-day-using-the-service-worker-api</link>
      <guid>http://component.kitchen/blog/posts/we-made-our-static-site-work-offline-in-a-day-using-the-service-worker-api</guid>
      <description><![CDATA[
      <p>
  We believe in progressive web applications as a strong alternative to native mobile applications.
  Along with small experimental projects we conduct on the side, we intend to improve our web site over
  time with new techniques and patterns, both to educate ourselves as well as to demonstrate the worth
  of these browser improvements. Our latest improvement makes use of
  <a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers">Service Workers</a>.
  You can now view most of the
  <a href="http://component.kitchen">Component Kitchen website</a> offline, courtesy of the power of Service Workers.
</p>
<p>
  For those of you looking into employing Service Workers, it’s not difficult to retrofit an existing web
  site. Our goal was to make our blog posts available offline along with the rest of the site, and to
  allow an Android device user to add our web site to the home screen as a full screen web
  application. We didn’t change any existing code in our web site to support this. All it took was:
</p>

<ol>
  <li>
    Adding a small bit of script to each of our pages, made easier by the use of a main template for all
    pages on our site. This script simply registers the Service Worker, pointing to our Service Worker
    script file. Note that there will soon be a declarative &lt;link rel=“serviceworker”&gt; tag that will
    do this for you.
  </li>
  <li>
    Adding the script file referenced by the Service Worker registration, and handling the corresponding
    Service Worker events. In particular, when the Service Worker is installed we specify a set of
    URLs from our site to cache so that on subsequent page requests such as blog posts, everything is
    already in the cache.
  </li>
  <li>
    Adding a manifest file allowing Chrome and other supporting browsers to post a banner to the user
    offering adding the site to their home screen.
  </li>
</ol>

<p>
  The progressive web application aspect of this is satisfying to see. While we understand our web site
  and blog posts aren’t the most spectacular example of a web application, it’s fun to see our site
  installed as a web application on a phone’s home screen, the app launching full screen, and
  displaying all pages even in Airplane Mode. More complex behaviors than we're demonstrating can
  be implemented with the use of Service Workers, so we are just scratching the surface.
</p>
<p>
  Try it yourself: Visit our site on an Android device. After the page loads (wait a moment if you are on
  a slow connection to allow the cache to fill), go offline by, for example, turning on Airplane Mode.
  Now you can continue navigating the site including all the blog posts, even when you’re disconnected
  from the network!
</p>
<p>
  Bonus: After your first visit and with the network turned on, come back to the site after a wait of at
  least five minutes. Chrome’s current behavior is to watch for a second visit after five minutes and
  then present a banner asking you if you’d like to install the site to your home screen as a web
  application. If you choose to do so, you’ll find our site installed as an app with an icon on your home screen.
  Launching the app opens it full screen, similar to a native app. As described above, you can
  even do this offline and navigate the full site.
</p>
      ]]>
      </description>
    </item>
  

    <item>
      <title>Replacing your server-side template language with plain JavaScript functions</title>
      <pubDate>Tue, 05 Apr 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/replacing-your-server-side-template-language-with-plain-javascript-functions</link>
      <guid>http://component.kitchen/blog/posts/replacing-your-server-side-template-language-with-plain-javascript-functions</guid>
      <description><![CDATA[
      <p>
  We’ve rewritten the
  <a href="http://component.kitchen">component.kitchen</a>
  backend server to rip out a popular templating language and replace it with
  plain JavaScript functions. Recent language improvements in ES2015 have, in
  our opinion, made it a sufficiently capable general-purpose language that
  we’ve dropped use of a special-purpose template language. As we began a
  rewrite of our site, we were inspired by our recent work
  <a href="http://component.kitchen/blog/posts/a-new-release-of-basic-web-components-based-on-plain-javascript-component-mixins">using plain JavaScript functions to create web components</a>
  and decided to apply the same philosophy to our backend as well.
</p>
<p>
  We serve up our site using Node and
  <a href="http://expressjs.com/">Express</a>.
  A popular feature of Express is that it supports pluggable template languages,
  called “view engines”. Until now, we’ve used
  <a href="http://www.dustjs.com/">Dust.js</a>
  as our template language. This has worked okay, and we’ve done it that way for
  so long that we’ve rarely questioned the need for a special language to solve
  this one problem. But using a template language has some downsides:
</p>

<ul>
  <li>
    The template language (e.g., Dust) is different than the JavaScript the rest
    of the Node/Express backend is written in. We write in JavaScript everyday,
    but only rarely in the template language. This means we’re constantly
    forced to look even simple things up in the template langauge documentation.
  </li>
  <li>
    The syntax for most template languages is ugly and inconsistent. A template
    language’s parser needs a reliable way to identify template directives
    you’ve placed inside your content, so there’s a bias towards syntax that’s
    very unlikely to appear in normal text. Most template languages end up with
    lots of dollar signs, percent signs, curly braces, etc. Every one of these
    languages makes different choices, and you can be left trying to remember
    when you need one curly brace and when you need two.
  </li>
  <li>
    Performing work both outside the template (to prepare the data before
    pouring it into the template) and within the template (using conditional
    template directives, for example) can create an uneasy relationship between
    both pieces of code. Template languages have control-flow constructs like
    traditional languages, but they can be cumbersome to work with. For example,
    a looping construct typically expects to iterate over a simple array. If you
    want to, say, filter the array, you need to preprocess your data into a form
    directly useful in the template language. This often results in splitting
    logic across multiple files.
  </li>
</ul>

<p>
  Why use a special-purpose template language at all? Why not JavaScript? Now
  that ES2015 has template literals, we thought we’d try using those as the
  basis for a plain JavaScript solution.
</p>

<h2>Step 1: Replace each template file with a plain JavaScript function</h2>

<p>
  We create a file for each kind of page we serve up. Each file exports a
  single function that accepts an Express request object (which contains the
  HTTP headers, URL parameters, etc.) and returns a text string containing the
  response to send to the client.
</p>

<pre>
// SamplePage.js
module.exports = request =>
  `&lt;!DOCTYPE html>
  &lt;html>
    &lt;head>
    &lt;title>Hello, world!&lt;/title>
    &lt;/head>
    &lt;body>
      You’re looking at a page hosted on ${request.params.hostname}.
    &lt;/body>
  &lt;/html>`;
</pre>

<p>
  This is a pure function — it has no side effects. It returns a string using a
  template literal, splicing in data using the <code>${...}</code> syntax. As
  with all template language syntax, it is ugly. But at least this particular
  ugly syntax is now standard JavaScript. You can use the <em>same</em> ugly
  syntax throughout your code, instead of different ugly syntaxes for different
  parts of your code. JavaScript FTW!
</p>
<p class="pullQuote">
  Why use a special-purpose template language at all? Why not JavaScript?
</p>
<p>
  The render function can do whatever you want. If you need to do some
  computation — filter an array, etc. — you can do that in plain JavaScript, then
  splice the results into the string you return. While you could embed
  conditionals in the template literal directly, we prefer to avoid that, as it
  quickly gets ugly.
</p>
<p>
  If you want to have a page use a more general template, you can easily do that
  too:
</p>

<pre>
// Define a template. It’s just a function that returns a string.
let template = (request, data) =>
  `&lt;!DOCTYPE html>
  &lt;html>
    &lt;head>
    &lt;title>${data.title}&lt;/title>
    &lt;/head>
    &lt;body>
      ${data.content}
    &lt;/body>
  &lt;/html>`;

// Create a page that uses the template.
module.exports = request => template(request, {
  title: `Hello, world!`,
  content: `You’re looking at a page hosted on ${request.params.hostname}.`
});
</pre>

<p>
  Since a render function often needs to do asynchronous work, we allow a render
  function to return either a string or a Promise for a string.
</p>

<h2>Step 2: Map Express routes to render functions</h2>
<p>
  We create a simple mapping of routes to the functions that handle those
  routes. Since a render function’s file exports only that function, we can
  reference it with a <code>require()</code> statement:
</p>

<pre>
let routes = {
  '/': require('./home.js'),
  '/about': require('./about.js'),
  '/blog': require('./blogIndex.js'),
  '/blog/posts/:post': require('./blogPost.js'),
  '/robots.txt': require('./robots.js'),
  '/sitemap.xml': require('./sitemap.js')
};
</pre>

<h2>Step 3: When a request comes in, invoke the render function</h2>
<p>
  We wire up our Express routes such that, when a request comes in matching a
  given route, the corresponding render function is invoked. The result of that
  function is resolved and returned as the request’s response.
</p>

<pre>
// Map routes to render functions.
for (let path in routes) {
  let renderFunction = routes[path];
  app.get(path, (request, response) => {
    // Render the request as a string or promise for a string.
    let result = renderFunction(request);
    // If the result's not already a promise, cast it to a promise.
    Promise.resolve(result)
    .then(content => {
      // Return the rendered content as the response.
      response.set('Content-Type', inferContentType(content));
      response.send(content);
    });
  });
}
</pre>

<h2>Step 4: Set the outgoing Content-Type</h2>
<p>
  Nearly all our routes respond with HTML, but we have a small number of routes
  that return XML, JSON, or plain text. We could have a render function return
  multiple values, including an indication of the desired Content-Type. But our
  simple site serves up such a small number of content types that we can
  reliably infer the content type from the start of the response string.
</p>

<pre>
// Given textual content to return, infer its Content-Type.
function inferContentType(content) {
  if (content.startsWith('&lt;!DOCTYPE html>')) {
    return 'text/html';
  } else if (content.startsWith('&lt;?xml')) {
    return 'text/xml';
  } else if (content.startsWith('{')) {
    return 'application/json';
  } else {
    return 'text/plain';
  }
}
</pre>

<p>
  That’s it. We end up with a small set of JavaScript files, one for each kind
  of page we serve up. Each file defines a single render function, and each
  function is typically quite simple. In our opinion, our code has gotten easier
  to read and reason about. It’s also closer to the metal — we have ripped out
  a substantial, mysterious template language layer — so there are fewer
  surprises, and we don’t have to keep looking up template language tricks in
  the documentation or on StackOverflow.
</p>
<p>
  Although domain-specific template languages like Dust look very efficient,
  over time we accumulated a non-trivial amount of JavaScript to get everything
  into a form Dust could process. Now that we’re just using JavaScript
  everywhere, we have much <em>less</em> page-generation code than we did
  before, and the new code is completely consistent with the rest of our code
  base.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Using React app techniques at the web component level with Redux, virtual-dom, and JSX</title>
      <pubDate>Mon, 14 Mar 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/using-react-app-techniques-at-the-web-component-level-with-redux-virtual-dom-and-jsx</link>
      <guid>http://component.kitchen/blog/posts/using-react-app-techniques-at-the-web-component-level-with-redux-virtual-dom-and-jsx</guid>
      <description><![CDATA[
      <p>
  The rising interest in React inspired us to try implementing web components that use a reactive approach
  to rendering. As an experiment, we’ve redone a React tutorial in web components, using Redux for
  predictive state management, JSX for rendering state, and virtual-dom for comparative DOM updating.
  Essentially, we treat each web component as if it were a reactive application in its own right. Our goal
  isn't to push an agenda, but to learn what the reactive web component patterns might look like.
</p>

<h2>Background</h2>
<p>
  <a href="https://facebook.github.io/react/">Facebook's React</a> JavaScript library is very popular and has
  growing numbers of supporters and projects. It often comes up in our discussions with clients and others,
  some suggesting that they're "strictly a React shop," with the implied notion that web components
  and/or other approaches are incompatible with React components and the library in general. We think
  web components are compatible with React (and other frameworks),
  <a href="http://facebook.github.io/react/docs/webcomponents.html">with some integration planning</a>. Others
  <a href="http://webcomponents.org/presentations/complementarity-of-react-and-web-components-at-reactjs-conf/">
  have contributed to the thinking</a> as well.
</p>
<p>
  The React phenomenon has moved us to think more about the principles of
  <a href="https://riad.blog/2015/11/13/understand-unidirectional-data-flow-by-practice-rewrite-an-angularjs-application/">
  reactive programming</a>
  and how those principles may be applied to web application development in general, and in particular
  whether they could be employed in the encapsulated development of web components.
</p>
<p>
  Stripping things down to bare essentials, we decided to try our hand at implementing web component
  internals with a React-like approach, using only <a href="https://github.com/reactjs/redux">Redux</a>
  for predictive state management and <a href="https://github.com/Matt-Esch/virtual-dom">virtual-dom</a>
  for comparative template rendering of a virtual node tree to the DOM.
</p>
<p>
  This post assumes you have familiarity with the web component specification and the basics of React &mdash; though
  we're not using React here. <a href="https://egghead.io/series/getting-started-with-redux">This series of
  lessons on Redux</a> is a great way to get familiar with its state management flow. It is also useful
  to have a look at
  <a href="http://component.kitchen/blog/posts/composing-mixins-to-make-a-solid-foundation-for-web-components">
  a couple</a> of
  <a href="http://component.kitchen/blog/posts/building-web-components-from-a-loose-framework-of-mixins">
  our earlier posts</a> on building web components and mixins with ES2015 JavaScript.
</p>

<h2>Following a React tutorial as a guide</h2>
<p>
  <a href="https://facebook.github.io/react/docs/tutorial.html">This introductory React tutorial</a> demonstrates
  how to build nested UI components in React in a simple, understandable way. It builds a comment box
  of the sort you might see following a blog post or news article. The comment box consists of a small number
  of React components which the tutorial guides you in building. The component structure of the
  comment box looks like this:
</p>
<pre>
  CommentBox
    --CommentList
      --Comment
      --Comment
      -- …
    --CommentForm
</pre>
<p>
  We'll follow the outline and structure of the tutorial in implementing a similar set of web components,
  and we'll generally follow the progression of the tutorial so you can compare the steps taken here
  with the React component approach. They're very similar approaches, but we are emphasizing the
  reactive programming model via Redux and virtual-dom rather than demonstrating the wrapping of React techniques.
  We want to emphasize the immutable state and virtual dom rendering techniques, usually seen applied
  at the application level, encapsulated within the implementation boundaries of web components.
</p>
<p>
  You should also note that as we are following the outline of the React tutorial, our components
  will render to their shadow DOM tree, as opposed to constructing local DOM. If you're confused about
  <i>local vs light vs shadow</i> DOM, see
  <a href="https://www.polymer-project.org/1.0/docs/devguide/local-dom.html">this description</a>.
  Keep in mind that shadow DOM is supported natively in a limited number of browsers, such as Chrome.
  We use the polyfill library, <a href="https://github.com/webcomponents/webcomponentsjs">webcomponents.js</a>,
  to provide shadow DOM behavior in browsers that don't otherwise support it.
</p>
<p>
  If you want to jump ahead and see a running demonstration of the project,
  <a href="http://componentkitchen.github.io/reactive-web-components/">you can find it here</a>.
</p>

<h2>Getting started</h2>
<p>
  <a href="https://github.com/componentkitchen/reactive-web-components">The completed project</a>
  can be cloned to your local environment. You can then pull down the npm dependencies and build the project
  following the directions in the link. The source code we'll be looking at is found in the
  src/scripts folder &mdash; CommentBox.js, CommentList.js, Comment.js, and CommentForm.js.
</p>
<p>
  You can load the root index.html file under a local web server.
  The HTML is very simple:
</p>
<script src="https://gist.github.com/robbear/19602ed89a6d948d5be2.js"></script>
<p>
  Note that we load the transpiled script file, es5scripts.js, in line 8.
  The previous line loads the web components polyfill library. And line
  19 is the entry point to our component code, with the use
  of the &lt;rwc-comment-box&gt; custom element.
</p>

<h2>Patterns common to all our reactive programming components</h2>
<p>
  First, we’ll note that we’re building our components as ES2015 classes, deriving each
  of our components from HTMLElement, and adding the
  <a href="https://github.com/basic-web-components/basic-web-components/blob/master/packages/basic-component-mixins/docs/AttributeMarshalling.md">
  AttributeMarshalling</a> mixin as discussed in
  <a href="http://component.kitchen/blog/posts/building-web-components-from-a-loose-framework-of-mixins">Jan’s post on mixins</a>.
</p>
<p>
  All of the components in this project implement a certain pattern which we'll illustrate with
  our outermost component, CommentBox. Each component begins with an implementation of
  createdCallback with a call to super. We will describe the use of the USING_SHADOW_DOM_V0
  constant soon.
</p>
<script src="https://gist.github.com/robbear/99b0f06eede57f4b86e7.js"></script>
<p>
  After defining the component class, we register the element with the DOM, and export it so it
  can be imported elsewhere in our project code. We have something like
  this for each of the four web components we’re building &mdash; CommentBox, CommentList,
  Comment, and CommentForm.
</p>
<p>
  Now that we have a basic shell for each of our components, we’ll look at the common aspects
  in the use of Redux and virtual-dom. Each component has its own instance of a Redux store,
  including its own implementation of the store subscriber callback, reducer method, state object,
  and dispatch actions. Let’s sketch those in next.
</p>
<script src="https://gist.github.com/robbear/277474d28e3fc2577b79.js"></script>
<p>
  We’ve added an import for createStore from the Redux module, defined a getter for the component’s
  immutable default state, set up the initial code for the component’s reducer method, and specified
  the Redux store listener. We’ve defined the reducer as a static class method for two purposes:
</p>
<ol>
  <li>To allow us to refer to it locally scoped within the component’s namespace</li>
  <li>To ensure that the reducer remains a stateless, pure function</li>
</ol>
<p>
  All state for the component should be maintained within the Redux store, and we organize
  our Redux code to help us remember reactive programming principles. We similarly define the default state getter
  as a static method. We’ll flesh out the default state object shortly.
</p>
<p>
  We added Redux initialization code at the beginning of the component’s createdCallback method,
  prior to making the call to the component’s base class. We are treating Redux initialization
  as constructor code (as we will with virtual-dom initialization), and because as of today the
  browser will not call into our constructor, we treat the opening chorus of the createdCallback
  method as if it were the class constructor.
</p>
<p>
  To this point, we’ve established the Redux flow in the component: Create the Redux store at
  initialization time (createdCallback) associating the static reducer method with the store,
  and subscribe to changes in state with the storeListener method which is bound to the class’s this object.
</p>
<p>
  Next, we’ll add scaffolding for our use of virtual-dom.
</p>
<script src="https://gist.github.com/robbear/ac904c2b71c29a4dfd49.js"></script>
<p>
  First, we added imports from virtual-dom for its <i>diff</i>, <i>patch</i>, <i>create</i>, and <i>h</i> APIs.
  We then initialized the virtual node tree in createdCallback with a call to the component’s
  render method. The render method uses JSX which is transpiled into virtual-dom <i>h()</i> calls and
  returns a virtual node tree. Note that for now, the component’s JSX is a placeholder div.
  Continuing, we then set the DOM root node for the component’s intended shadow DOM with a call to virtual-dom’s
  <i>create</i>.
</p>
<p>
  Thus far, this is very similar to setting up a &lt;template&gt; element for rendering to a
  component's shadow DOM. Instead of using &lt;template&gt;, we make use of JSX with the
  intention of rendering its virtual node tree to shadow DOM.
</p>
<p>
  Now the use of the USING_SHADOW_DOM_V0 constant comes into play. We create a shadow root
  by using the version of the API supported by the browser, falling back implicitly to the
  polyfill library where no native support for shadow DOM exists. We then append the
  resulting virtual-dom/JSX DOM tree to the component's shadow root. We do all of this
  initialization of the Redux store and virtual-dom tree prior to calling our superclass, ensuring
  that our state management and rendering system is in place before any mixins begin their initialization.
</p>
<p>
  Subsequent interactions and rendering will take advantage of virtual-dom’s ability to compare
  a new virtual node tree with the current one, and apply changes to the component's shadow DOM. While the virtual-dom
  <a href="https://github.com/Matt-Esch/virtual-dom#documentation">documentation</a>
  describes this process, what’s important to note here is that what is typically done
  on a full application UI basis is being done here only within the shadow DOM context of the component.
</p>
<p>
  <b>This is the key point</b>. We can take a pattern for utilizing Redux and virtual-dom at the application
  level and encapsulate them, instead, within the context of a web component. What we have in place
  now is code common to any web component we write in this manner. In fact, an additional exercise
  which we won’t do here is to capture this common code in a new
  <a href="http://component.kitchen/blog/posts/implementing-web-component-mixins-as-functions">mixin</a>
  which would be added by any reactive programming web component.
</p>
<p>
  Let’s summarize the flow for all our components at initialization, noting that createdCallback is
  the entry point to the component’s code.
</p>
<ol>
  <li>
    At initialization, prepare the component’s Redux store by creating it, associating it with
    the component’s static reducer method, and subscribing to store changes with the component’s
    storeListener method.
  </li>
  <li>
    At initialization, create a shadow root, capture the component’s initial virtual node tree,
    translate it to DOM, and append that to the component’s shadow DOM.
  </li>
  <li>
    Actions (soon to be written) dispatched to the component’s pure function, reducer,
    cause a new state object (or the current unchanged state) to be returned, triggering a
    call to the storeListener method.
  </li>
  <li>
    The storeListener method leverages virtual-dom, rendering a new virtual node tree based
    on the new state, comparing the new virtual node tree with the prior tree, and patching
    the differences into the component's shadow DOM.
  </li>
</ol>
<p>
  Interactions with the component cause steps 3 and 4 to repeat.
</p>
<p>
  Here we’ve reached the equivalent point in the React tutorial where you
  <a href="https://facebook.github.io/react/docs/tutorial.html#composing-components">begin composing components</a>.
  The rest of the work depends on leveraging this architecture, implementing the semantic
  details of each component.
</p>
<p>
  The React tutorial makes network requests for comment data, but we will simplify things
  here for illustration purposes, using mock data and local-only interactions. The CommentBox
  component will render an instance each of CommentList and CommentForm components as shadow DOM,
  passing comment data to CommentList, and watching for “comment-added” events from the CommentForm
  component. We’ll provide CommentBox with initial comment data, as if that data had been
  downloaded from a server. We do that in a method called initializeWithMockData. The changes
  to CommentBox’s initialization code look like this.
</p>
<script src="https://gist.github.com/robbear/a6731298381a51cf707e.js"></script>
<p>
  In createdCallback, we’ve added the call to initializeWithMockData, and we’ve added
  an event listener for “comment-added” which we’ve bound to a method called handleCommentAdded.
  The comment-added event will be dispatched from the CommentForm component. Note that
  initializeWithMockData dispatches an action to the component’s Redux store. We need to
  define what the component’s state looks like, and update the reducer method.
</p>
<script src="https://gist.github.com/robbear/bfbe8df599053be99bb1.js"></script>
<p>
  The CommentBox’s default state is an object holding an array, commentList, of comment objects.
  We’ve added a deepCopy method to the defaultState object that allows the object to be copied in
  an immutable fashion, remembering that the reducer method never modifies existing state.
</p>
<p>
  In the updated reducer method, we’ve added support for the ADD_COMMENTS action. We take the
  current state as passed into the reducer method by Redux, copy that state to a new object,
  then push the array of comments specified in the action parameter onto the new state’s
  commentList array. We then return that new state.
</p>
<p>
  What happens with that new state? Remember that we subscribed to changes in the Redux store with
  our storeListener method, so that gets called when we return the new state from the reducer method.
  It’s that state that then gets fed to our render method in order for virtual-dom to generate an
  updated DOM. We need to update our render method, which now looks like this.
</p>
<script src="https://gist.github.com/robbear/1142320be3e75ddfbb76.js"></script>
<p>
  We’ve added &lt;rwc-comment-list&gt; and &lt;rwc-comment-form&gt; to our JSX, corresponding
  to instances of our CommentList and CommentForm components. What’s important to note
  here is how the render method binds the new state to the updated UI of the component.
  The render method acts like a template rendering system. What we’ve done here is to pass
  the current state’s commentList as attributes to the CommentList component so that CommentList
  can construct its children Comment components. The CommentBox also hosts a CommentForm, for
  which we’ve added inline style just so we have some visual separation on the page.
</p>
<p>
  Remember that we set up an event listener for add-comment events being dispatched from
  the CommentForm component. The event listener callback looks like this.
</p>
<script src="https://gist.github.com/robbear/63fd5e28b307b5fb1fa4.js"></script>
<p>
  Here, we make use of the ADD_COMMENTS action once again, dispatching the action to the
  CommentBox’s store just as we did in initializing with the mock data.
</p>
<p>
  At this point, we’ve completed the implementation for the outermost component, CommentBox.
  The remaining components have the equivalent flow, sharing similar code that might later
  be refactored into a mixin class. Let’s look at some of the details of their implementation,
  starting with CommentList.
</p>

<h2>Implementing the CommentList component</h2>
<p>
  CommentList uses its coment-data attribute as its communication mechanism with its
  hosting CommentBox (or, for that matter, any host). Its state object is identical to
  CommentBox’s, though its reducer is somewhat special in that it treats the attribute
  data as the exclusive specification for the new state, ignoring any previous state. Feed
  the CommentList an updated comment-data attribute, and it will render the comment data to
  a set of child Comment components.
</p>
<p>
  What may not be obvious through viewing the code is that CommentList takes advantage
  of the
  <a href="https://github.com/basic-web-components/basic-web-components/blob/master/packages/basic-component-mixins/docs/AttributeMarshalling.md">
  AttributeMarshalling mixin</a> we mentioned earlier. A change in the comment-data attribute results,
  via AttributeMarshalling, in a call to CommentList’s commentData property setter.
</p>
<script src="https://gist.github.com/robbear/81761d7b5e7c247957c7.js"></script>
<p>
  This property implementation should look interesting to anyone familiar with web
  component development, and is a key aspect to the reactive programming approach. Note that the property
  does not correspond to class state. There’s no data object corresponding to this.commentData.
  Instead, the property setter is a dispatcher to the CommentList’s Redux store
  instance &mdash; a store instance separate from each of the other component instances in our
  project. Similarly, the property getter retrieves data from the Redux store’s current state.
</p>
<p>
  It’s worth looking at CommentList’s reducer to see how new state is generated.
</p>
<script src="https://gist.github.com/robbear/03d3750f2668e2bd416a.js"></script>
<p>
  And this is how CommentList renders changes to its state.
</p>
<script src="https://gist.github.com/robbear/72df780d2a079b8954fb.js"></script>
<p>
  The render method creates an array of rwc-comment virtual nodes, each rwc-comment corresponding
  to an instance of the Comment class.
</p>
<p>
  What we’re seeing here is a pattern of building web components using reactive programming techniques,
  each component holding its own instance of a Redux store and leveraging virtual-dom to
  specify its entire virtual node tree as rendering input for a difference-patched output.
  The pattern works at the individual component level, and works even with components
  nested within components. It’s no great surprise when you think about it, but it’s
  exciting at the same time to observe it in practice.
</p>

<h2>Implementing the Comment component</h2>
<p>
  Let’s look into the implementation details for the Comment component. If you take a
  look once more above at the render method for CommentList, you’ll see that each comment
  has the form:
</p>
<pre>
  &lt;rwc-comment attributes={{author: comment.author}}&gt;
    &lt;div id="commentText"&gt;
      {comment.commentText}
    &lt;/div&gt;
  &lt;/rwc-comment&gt;
</pre>
<p>
  We are anticipating that the Comment component is able to manage and render a host-supplied
  child node tree, most likely through the use of the &lt;content&gt; element. In fact, that
  is exactly the case, as we'll soon show. The Comment component processes the author
  attribute, but the decision for how the comment text is to be rendered is up to the
  host of the Comment component. Here, the decision is to render it as text within
  a &lt;div&gt;.
</p>
<p>
  From this interface, you might anticipate what the Comment component’s state object
  and reducer look like.
</p>
<script src="https://gist.github.com/robbear/e1fea9fc4e1cf5b13fe0.js"></script>
<p>
  The Comment component’s state object is simple, containing a string value for author.
  The reducer method follows logically, with a single action, SET_AUTHOR.
  Note the use of Object.assign for merging the previous state with new data, and
  creating a new state object to be returned in an immutable manner. At this point,
  you might anticipate that the component has an author property, with a setter
  and getter that work against the Redux store rather than keeping state as member
  variables in the class object.
</p>
<script src="https://gist.github.com/robbear/29241f345000b6924554.js"></script>
<p>
  This follows the same pattern we used with properties for CommentList. Next, let’s
  take a look at Comment’s render method.
</p>
<script src="https://gist.github.com/robbear/07b234dc5ac5922cf7cc.js"></script>
<p>
  The shadow DOM sets up a &lt;div id=”comment”&gt; element containing an &lt;h2&gt; element whose
  text content is the comment author. Sibling to the &lt;h2&gt; element is a &lt;content&gt; element
  which will display the child node tree specified by the component's host. Remember from above
  that this is the content specified in CommentList's render method, between the
  &lt;rwc-comment&gt;&lt;/rwc-comment&gt; tags:
</p>
<pre>
  &lt;div id="commentText"&gt;
    {comment.commentText}
  &lt;/div&gt;
</pre>
<p>
  As the Web Component specification evolves, the &lt;content&gt; tag will be
  replaced with the new &lt;slot&gt; tag and the way that content gets injected
  into the shadow DOM will change. That's just something to keep in mind for now.
</p>

<h2>Implementing the CommentForm component</h2>
<p>
  All that is left now is the implementation of the CommentForm component, which manages
  a form element with input fields for author and comment text, and a submit button.
  The state object and reducer are straightforward.
</p>
<script src="https://gist.github.com/robbear/3d8fcfcad314416e6838.js"></script>
<p>
  The state object has values for author and comment text, with the default state
  setting both of these to empty strings. The reducer method supports three actions:
  setting author or comment text, and clearing the form. The latter sets the current
  state to the default state object.
</p>
<p>
  Let’s look at the render method for CommentForm.
</p>
<script src="https://gist.github.com/robbear/8b822db2e3ba418e65f1.js"></script>
<p>
  The author and comment text input fields get populated by their corresponding
  values in the current state, with the both of these elements triggering onchange
  events. The form element itself handles onsubmit. The event handlers depend on
  property settings that dispatch actions to the Redux store.
</p>
<script src="https://gist.github.com/robbear/90962aad7d71c4c621a0.js"></script>
<p>
  We can see in handleSubmit that we create and dispatch the comment-added
  event which the CommentBox component listens to. It also causes a CLEAR_FORM
  action to be dispatched to the Redux store, resulting in the input fields
  being cleared out.
</p>
<p>
  The event handlers dealing with changes in the input fields use property setters
  to dispatch actions to the Redux store as well.
</p>
<p>
  Finally, note the special selector mechanism we use to set the focus on the
  input element having id="authorInput".
</p>
<pre>
  this.$.authorInput.focus();
</pre>
<p>
  We get support for this syntax by adding the
  <a href="https://github.com/basic-web-components/basic-web-components/blob/master/packages/basic-component-mixins/docs/ShadowElementReferences.md">
  ShadowElementReferences mixin</a> from basic-component-mixins. We're now adding two mixins to ComponentForm as
  it derives from HTMLElement. We need to import the appropriate modules, and we use the Composable helper
  to declare the class as shown here.
</p>
<script src="https://gist.github.com/robbear/9a26a7cf7cb072a6a1ed.js"></script>

<h2>Summary</h2>
<p>
  We've demonstrated how we can use a reactive programming approach to implementing web components.
  We treat a web component's implementation boundaries as if it were an application,
  with Redux and virtual-dom serving in the same manner in the component implementation
  as they would within a full application. Unlike in the React tutorial, the components
  we've created here, because they are web components, are usable outside the context of this tutorial.
</p>
<p>
  We're interested in seeing what kinds of discussions this approach raises. There's
  a lot to explore here including from a perspective of usefulness of approach, performance
  issues, and unit testing.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Writing a web component that wraps a standard HTML element might alleviate the need for is="" syntax</title>
      <pubDate>Mon, 29 Feb 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/writing-a-web-component-that-wraps-a-standard-html-element-might-alleviate-the-need-for-is-syntax</link>
      <guid>http://component.kitchen/blog/posts/writing-a-web-component-that-wraps-a-standard-html-element-might-alleviate-the-need-for-is-syntax</guid>
      <description><![CDATA[
      <p>
  What if you want to create a web component that extends the behavior of a
  standard HTML element like a link? An early draft of the Custom Elements
  specification allowed you to do this with a special syntax, but the fate of
  that syntax is in doubt. We've been trying to create custom variations of
  standard elements <em>without</em> that support, and wanted to share our
  progress. Our results are mixed: more positive than we expected, but with some
  downsides.
</p>

<h2>Why would you want to extend a standard HTML element?</h2>
<p>
  Perhaps there's a standard element does <em>almost</em> everything you want,
  but you want it to give it custom properties, methods, or behavior.
  Interactive elements like links, buttons, and various forms of input are
  common examples.
</p>
<p>
  Suppose you want a custom anchor element that knows when it's pointing to the
  page the user is currently looking at. Such a situation often comes up in
  navigation elements like site headers and app toolbars. On our own site, for
  example, we have a header with some links at the top to our
  <a href="http://component.kitchen/tutorial">Tutorial</a> and
  <a href="http://component.kitchen/about">About Us</a> pages. If the user's
  currently on the About Us page, we want to highlight the About Us link so the
  user can confirm their location:
</p>
<figure>
  <a href="http://component.kitchen/about">
    <img src="resources/blog/Component Kitchen Toolbar.png" style="max-width: 100%;">
  </a>
</figure>
<p>
  While such highlighting is easy enough to arrange through link styling and
  dynamically choosing CSS classes in page templates, it seems weird that a link
  can't just handle this highlighting itself. The link should be able to just
  combine the information it already has access to — its own destination, and
  the address of the current page — and determine for itself whether to apply
  highlighting.
</p>
<p>
  We recently released a simple component called
  <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-current-anchor">basic-current-anchor</a>
  that does this. We did this partly because it's a modestly useful component,
  and also because it's a reasonable testing ground for ways to extend the
  behavior of a standard element like an anchor.
</p>
<p>
  What's the best way to implement a component that extends a standard element?
</p>

<h2>Option 1: Recreating a standard element from scratch (Bad idea)</h2>
<p>
  Creating an anchor element completely from scratch turns out to be ferociously
  complicated. You'd think you could just apply some styling to make an element
  blue and underlined, define an <code>href</code> attribute/property, and then
  open the indicated location when the user clicks. But there's far more to an
  anchor element than that. A sample of the problems you'll face:
</p>
<ol>
  <li>
    The result of clicking the link depends on which modifier keys the user is
    pressing when they click. They may want to open the link in a new tab or
    window, and the key they usually press to accomplish that varies by browser
    and operating system.
  </li>
  <li>
    You'll need to do work to handle the keyboard.
  </li>
  <li>
    Standard links can change their color if the user has visited the
    destination page. That knowledge of browser history is not available to you
    through a DOM API, so your custom anchor element won't know which color to
    display.
  </li>
  <li>
    When you hover over a standard <code>&lt;a&gt;</code> element, the browser
    generally shows the link destination in a status bar. But there is <em>no
    way to set the status bar text in JavaScript</em>. That's probably a good
    thing! It would be annoying for sites to change the status bar for nefarious
    purposes. But even with a solid justification for doing so, your custom
    anchor element has no way to show text in the status bar.
  </li>
  <li>
    Right-clicking or long-tapping a standard link produces a context menu that
    includes link-specific commands like "Copy Address". Again, this is a
    browser feature to which you have no access in JavaScript, so your custom
    anchor element can't offer these commands.
  </li>
  <li>
    A standard anchor element has a number of accessibility features that are
    used by users with screen readers and other assistive techologies. While
    you can work around the problem to some extent with ARIA, there are
    numerous
    <a href="https://github.com/domenic/html-as-custom-elements/blob/master/docs/accessibility.md">gaps in implementing accessibilty</a>
    completely from scratch.
  </li>
</ol>
<p>
  Given this (likely incomplete) litany of problems, we view this option as a
  non-starter, and would strongly advise others to not go down this road.
  It's a terrible, terrible idea.
</p>

<h2>Option 2: Hope/wait for is="" syntax to be supported</h2>
<p>
  The original Custom Elements spec called for an <code>extends</code> option
  for <code>document.registerElement()</code> to indicate the tag of a standard
  element you wanted to extend:
</p>
<pre>
  class MyCustomAnchor { ... }
  document.registerElement('my-custom-anchor', {
    prototype: MyCustomAnchor.prototype,
    extends: 'a'
  });
</pre>
<p>
  Having done that, you could then create your custom variant of the standard
  element by using the standard tag, and then adding an <code>is</code>
  attribute indicating the name of your element.
</p>
<pre>
  &lt;body&gt;
    &lt;a is="my-custom-anchor" href="https://example.com"&gt;A custom link&lt;/a&gt;
  &lt;/body&gt;
</pre>
<p>
  However, at a W3C committee meeting in January, Apple indicated that they
  felt like this feature would likely generate many subtle problems. They do not
  want such problems to jeopardize the success of Custom Elements v1.0, and have
  argued that it should be excluded from the Custom Elements specification for
  now. Google and others would like to see this feature remain. But without
  unanimous support, the feature's future is unclear, and we're reluctant to
  depend on it.
</p>

<h2>Option 3: Use the Shadow DOM polyfill just for elements with <code>is</code> attributes</h2>
<p>
  The
  <a href="https://github.com/webcomponents/webcomponentsjs">web component polyfills</a>
  already support the <code>is=""</code> syntax, so in theory you could keep
  using the polyfill even in browsers where native Shadow DOM is available.
  But that feels weird for a couple of reasons. First, the polyfill won't load
  if native Shadow DOM is available, so you'd have to subvert that behavior.
  You'd have to keep just enough of the polyfill alive to handle just custom
  element instances using the <code>is=""</code> syntax. That doesn't sound like
  fun. And, second, if <code>is=""</code> isn't offically endorsed by all the
  browsers, it's future is somewhat uncertain, so it's seems somewhat risky to
  invest in it.
</p>
<p>
  You could also try to manually reproduce what the Shadow DOM polyfill is
  doing, but that seems like an even worse answer. Your approach won't be
  standard even in name, and so you'll create a burden for people that want to
  use your component.
</p>

<h2>Option 4: Wrap a standard element</h2>
<p>
  Since we think it's inadvisable to recreate standard elements from scratch
  (option 1 above), and are nervous about depending on a standard syntax in the
  near future (options 2 and 3), we want to explore other options under our
  control. The most straightforward alternative seems to be wrapping a standard
  element. The general idea is to create a custom element that exposes the same
  API as a standard element, but delegates all the work to a real instance of a
  standard element sitting inside the custom element's Shadow DOM subtree. This
  sort of works, but with some important caveats.
</p>
<p>
  The process of wrapping a standard element is consistent enough across all
  standard element types that we can try to find a general solution. We've made
  our initial implementation available in the latest v0.7.3 release of
  <a href="https://github.com/basic-web-components/basic-web-components">Basic Web Components</a>,
  in the form of a new base class called
  <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-wrapped-standard-element">WrappedStandardElement</a>.
  This component serves both as a base class for wrapped standard elements,
  and a class factory that generates such wrappers.
</p>
<p>
  We've used this facility to refactor an existing component called
  <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-autosize-textarea">basic-autosize-textarea</a>
  (which wraps a standard textarea), and
  deliver a new component,
  <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-current-anchor">basic-current-anchor</a>.
  The latter wraps a standard anchor element to deliver the feature discussed
  above: the anchor marks itself as current if it points to the current page.
  You can view a simple
  <a href="http://basicwebcomponents.org/basic-web-components/packages/basic-current-anchor/">demo</a>.
</p>
<p>
  The definition of basic-current-anchor wraps a standard anchor like this:
</p>
<pre>
  // Wrap a standard anchor element.
  class CurrentAnchor extends WrappedStandardElement.wrap('a') {
    // Override the href property so we can do work when it changes.
    get href() {
      // We don't do any custom work here, but need to provide a getter so that
      // the setter below doesn't obscure the base getter.
      return super.href;
    }
    set href(value) {
      super.href = value;
      /* Do custom work here */
    }
  }
  document.registerElement('basic-current-anchor', CurrentAnchor);
</pre>
<p>
  The <code>WrappedStandardElement.wrap('a')</code> returns a new class that
  does several things:
</p>
<ol>
  <li>
    The class' <code>createdCallback</code> creates a Shadow DOM subtree that
    contains an instance of the standard element being wrapped. A runtime
    instance of <code>&lt;basic-current-anchor&gt;</code> will look like this:
    <pre>
  &lt;basic-current-anchor&gt;
    #shadow-root
      &lt;a id="inner"&gt;
        &lt;slot&gt;&lt;/slot&gt;
      &lt;/a&gt;
  &lt;/basic-current-anchor&gt;</pre>
    Note that the inner <code>&lt;a&gt;</code> includes a <code>&lt;slot&gt;</code>
    element. This will render any content inside the <code>&lt;basic-current-anchor&gt;</code>
    inside the standard <code>&lt;a&gt;</code> element, which is what we want.
  </li>
  <li>
    All getter/setter properties in the API of the wrapped standard class are
    defined on the outer wrapper class and forwarded to the inner inner
    <code>&lt;a&gt;</code> element. Here, CurrentAnchor will end up exposing
    HTMLAnchorElement properties like <code>href</code> and forwarding those
    to the inner anchor. Such forwarded properties can be overridden, as shown
    above, to augment the standard behavior with custom behavior. Our
    CurrentAnchor class overrides <code>href</code> above so that, if the
    <code>href</code> is changed at runtime, the link updates its own visual
    appearance.
  </li>
  <li>
    Certain events defined by standard elements will be re-raised across the
    Shadow DOM boundary. The Shadow DOM spec defines a list of
    <a href="https://www.w3.org/TR/shadow-dom/#h-events-that-are-not-leaked-into-ancestor-trees">events that will not bubble up across a Shadow DOM boundary</a>.
    For example, if you wrap a standard <code>&lt;textarea&gt;</code>, the
    <code>change</code> event on the textarea will <em>not</em> bubble up
    outside the custom element wrapper. That's an issue for components like
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-autosize-textarea">basic-autosize-textarea</a>.
    Since Shadow DOM normally swallows <code>change</code> inside a shadow
    subtree, someone using basic-autosize-textarea wouldn't be able to listen to
    <code>change</code> events coming from the inner textarea. To fix that,
    WrappedStandardElement automatically wires up event listeners for such
    events on the inner standard element. When those events happen, the custom
    element will re-raise those events in the light DOM world. This lets users
    of basic-autosize-textarea listen to <code>change</code> events as expected.
  </li>
</ol>
<p>
  Because this approach uses a real instance of the standard element in
  question, many aspects of the standard element's behavior work as normal for
  free. For example, an instance of <code>&lt;basic-current-anchor&gt;</code>
  will exhibit all the appearance and behavior of a standard
  <code>&lt;a&gt;</code> described above. That includes mouse behavior, status
  bar behavior, keyboard behavior, accessibility behavior, etc. That's a huge
  relief!
</p>
<p>
  But this approach has one significant limitation: styling. Because our custom
  element isn't called "a", CSS rules that apply to <code>a</code> elements will
  no longer work. Link pseudo classes like <code>:visited</code> won't work
  either. Worse, because there's essentially no meaningful standard styling
  solution for web components that works across the polyfilled browsers, it's
  not clear how to provide a good styling solution.
</p>
<p>
  Things will become a little easier when CSS Variables are implemented
  everywhere, but even that is a sub-optimal solution to styling a wrapped
  standard element. For one thing, you would need to separately define new CSS
  variables for <em>every</em> attribute someone might want to style. That
  includes inventing variables to replace standard CSS pseudo-classes. Next,
  someone using your wrapped element would need to duplicate all the styling
  rules to use both the standard attributes and your custom CSS variables. That
  mess gets worse with each wrapped standard element added to a project, since
  each will likely to define different (or, worse, conflicting) variable names.
</p>
<p>
  For the time being, we're trying a different solution, which is to define the
  interesting CSS attributes on a wrapped element using the CSS
  <code>inherit</code> value. E.g., a <code>&lt;basic-current-anchor&gt;</code>
  element currently has internal styling for the inner standard anchor that
  effectively does this:
</p>
<pre>
  &lt;style&gt;
  a {
    color: inherit;
    text-decoration: inherit;
  }
  &lt;/style&gt;
</pre>
<p>
  What that means is that the inner anchor will have <em>no</em> color or
  text decoration (underline) by default. Instead, it will pick up whatever
  <code>color</code> or <code>text-decoration</code> is applied to the outer
  custom element. That's fairly close to what we want, but still not ideal.
  If someone neglects to specify a <code>color</code>, for example, they'll end
  up with links that are (most likely) black instead of the expected blue.
</p>
<p>
  In practice, we may be able to live with that. The typical use case for our
  basic-current-anchor component, for example, is in navigation elements like
  toolbars, where web applications nearly always provide custom link styling
  that overrides the standard colors anyway. That said, styling represents a
  significant complication in this wrapping approach, and should be carefully
  considered if trying this.
</p>

<h2>Wrapping up</h2>
<p>
  It would obviously be preferable for the Custom Elements specification to
  address the extension of standard elements when that becomes possible. But
  we're pragmatic, and would rather see Custom Elements v1.0 ship without
  <code>is=""</code> support if that means it comes sooner — as long as the
  problem is eventually solved correctly. Until then, wrapping a standard
  element may provide a stopgap solution to create a custom element extending
  standard behavior. It's not ideal, but may be sufficient for common cases.
</p>
<p>
  This is a complex area, and we could easily be overlooking things in our
  analysis. If you have thoughts on this topic, or know of an issue not
  discussed here, please give us a heads up!
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Web components let you preserve the backward compatibility of your own old code</title>
      <pubDate>Mon, 15 Feb 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/web-components-let-you-preserve-the-backward-compatibility-of-your-own-old-code</link>
      <guid>http://component.kitchen/blog/posts/web-components-let-you-preserve-the-backward-compatibility-of-your-own-old-code</guid>
      <description><![CDATA[
      <p>
  An interesting point of backward compatibility came up as we were recently
  porting our own <a href="http://component.kitchen">Component Kitchen</a>
  site to
  <a href="http://component.kitchen/blog/posts/a-new-release-of-basic-web-components-based-on-plain-javascript-component-mixins">plain JavaScript web components</a>.
  The main goal of the port was to be able to write our own site in plain ES6,
  with less abstraction between us and the platform. We've also reaped some
  other benefits: our site is now simpler to build, and much faster to load on
  older polyfilled browsers like Apple Safari and Internet Explorer.
</p>
<p>
  But the interesting bit was that we could use web components as a transitional
  strategy for our old code. The new components and the old components were
  written in a completely different way, but could nevertheless coexist on the
  page during the transition. All web components connect to the outside page
  through the same means: DOM attributes, DOM children, DOM events, as well as
  JavaScript properties and methods. So we could leave an old component in place
  while we changed the outer page, or vice versa, without having to rewrite
  everything at once.
</p>
<p>
  When we recently spoke on an
  <a href="https://www.youtube.com/watch?v=nli24SoWejY">Web Platform Podcast episode</a>,
  we spoke with panelist <a href="https://twitter.com/revillweb">Leon Revill</a>,
  who has raised this point of web components as a backward compatibility
  strategy. We think this is as a seriously underappreciated benefit of writing
  and using web components.
</p>
<p class="pullQuote">
  Which framework from three years ago would you prefer to use today
  if you were starting a new project?
</p>
<p>
  The web development industry is a highly chaotic, substantially fractured, and
  quickly evolving marketplace of competing approaches to writing apps. Even if
  you have the luxury of developing in an approach you think is absolutely
  perfect for 2016, the chances are probably very low that you will still want
  to write your app that way in 2019. If you don't believe that, ask yourself:
  which framework from three years ago would you <em>prefer</em> to use today
  if you were starting a new project?
</p>
<p>
  If you're working on something of lasting value, in three years time, you'll
  still be forced to reckon with some of your old code from 2016. Unless you're
  lavishly funded or insulated from the market, you probably won't be able to
  afford to always move all your old code to whatever you decide is the latest
  and greatest way to write software. You'll be forced to maintain code written
  in different eras, and that can be very tricky.
</p>
<p>
  A web component provides a useful encapsulation boundary that can help keep
  old front-end user interface code usefully running directly alongside new
  code. While a variety of contemporary web frameworks offer proprietary
  component models, they can only offer backward compatibility to the extent
  that you're willing to keep writing your whole app in that framework
  indefinitely. By virtue of being a web standard, the value of web components
  you write today should be able to be preserved for a very long time.
</p>
<p>
  <strong>Bonus:</strong> During our port, we were able to bring our popular
  <a href="http://component.kitchen/tutorial">Web Components Tutorial</a>
  up to date. If you know people who would be interested in learning about web
  components, just point them at the newly-updated tutorial.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Basic Web Components is a monorepo</title>
      <pubDate>Mon, 08 Feb 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/basic-web-components-is-a-monorepo</link>
      <guid>http://component.kitchen/blog/posts/basic-web-components-is-a-monorepo</guid>
      <description><![CDATA[
      <p>
  <a href="https://github.com/basic-web-components/basic-web-components">Basic Web Components</a> (BWC) is a project
  containing multiple, often-related Web Components along with support code implemented as mixins. As we have migrated
  the implementation of BWC from <a href="https://www.polymer-project.org/1.0/">Polymer</a> components to a
  <a href="/blog/posts/a-new-release-of-basic-web-components-based-on-plain-javascript-component-mixins">plain JavaScript</a> approach, we’ve also revisited
  the way we organize the project to support the following goals:
</p>
<ul>
  <li>
    Unified development across all BWC components: All components and mixins need to be part of the same
    Git repository.
  </li>
  <li>
    Distribution: Each component and each mixin package needs to be published separately for distribution under npm.
  </li>
  <li>
    Testing: Unit tests are easier to maintain when they can be applied across the full suite of components and mixins.
  </li>
  <li>
    Versioning and dependencies: BWC components and mixins may depend on each other as well as on common
    third-party npm modules, so a reproducible and understandable common development environment is required.
  </li>
</ul>
<p>
  These requirements depend somewhat on our decision to use
  <a href="http://blog.npmjs.org/post/122450408965/npm-weekly-20-npm-3-is-here-ish">npm version 3</a> and its support
  for flat directory installation of dependencies, rather than Bower. We believe that centralizing distribution and
  discoverability of Web Components in npm has been a long desired goal, hindered only by npm’s lack of support
  for Bower’s flat/peer folder installation. With npm version 3, we now have that along with npm’s greater developer
  mindshare and support. npm version 3 is a big win for the Web Components community.
</p>
<p>
  The BWC project's needs boil down to two main issues. The project needs to be maintained as a single Git
  repository, and multiple packages destined for publication to npm are defined within the repository. We chose to
  organize BWC as a <strong>monorepo</strong> in order to support these goals. A monorepo can be thought of as multiple
  independent software projects contained within a single Git repository. You can see other projects that rely on the
  monorepo approach by reading the
  <a href="https://github.com/babel/babel/blob/master/doc/design/monorepo.md">Babel team's reasoning</a> for
  organizing its project as a monorepo.
</p>
<p>
  We actually took steps towards a monorepo in our previous major version of BWC. We had identified the benefit in
  having all components and support code available in one directory tree for development and testing purposes. But
  instead of associating each Bower/npm-published component with the common repository, we created separate Git
  repositories for each component and built scripts that pushed changes from the consolidated repository to the
  individual component repositories. A consumer of a component could install from Bower or npm by passing along the
  Git repository’s master branch URL, or a version-tagged commit URL. The scripts to push to Git and set new
  version-tagged releases were onerous and confusing. A common question became whether contributors should work on
  the consolidated repository, or on the individual component repository.
</p>
<p>
  By moving to a monorepo, there’s no longer a question of where work should be done. All work is done on code within
  the BWC monorepo. We maintain a monorepo policy of updating, after the completion of significant work, all contained
  components to the same npm version, with each package in the monorepo having its own package.json. A Grunt
  task publishes each package in the monorepo to npm. While there are individual Basic Web Components npm packages
  registered with and searchable from npm, there is only one Git repository representing the code behind these packages.
  And because the individual component packages within the monorepo are contained within peer-adjacent filesystem
  folders, the monorepo development environment mirrors an npm installation of the components.
</p>
<p>
  One of the benefits of this approach is the shared, reproducible development environment we get by having all
  packages depend on the same root project package.json, coupled with an npm-shrinkwrap.json file that ensures each
  developer’s run of <strong>npm install</strong> against a clone of the BWC monorepo results in the same node_modules folder
  contents. This eliminates third-party version issues that may introduce errors or side effects that are not
  reproducible across development environments.
</p>
<p>
  As we develop new components and mixins for the Basic Web Components project, watch for them as new directories
  under the BWC monorepo’s
  <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages">packages</a>
  folder.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>A new release of Basic Web Components based on plain JavaScript component mixins</title>
      <pubDate>Mon, 01 Feb 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/a-new-release-of-basic-web-components-based-on-plain-javascript-component-mixins</link>
      <guid>http://component.kitchen/blog/posts/a-new-release-of-basic-web-components-based-on-plain-javascript-component-mixins</guid>
      <description><![CDATA[
      <p>
  As discussed in this blog over the past few months, we've been plotting a
  strategy for creating web components using a library of plain JavaScript
  mixins instead of a monolithic component framework. We've just published a
  new 0.7 release of the
  <a href="https://github.com/basic-web-components/basic-web-components">basic-web-components</a>
  project that represents a transition to this mixin strategy. So far, this
  approach appears to be working well, and meeting our expectations.
</p>
<p>
  What's changed?
</p>
<ol>
  <li>
    <strong>We've begun rewriting all our components in ES6.</strong>
    So far, we've rewritten the
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-autosize-textarea">basic-autosize-textarea</a>,
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-carousel">basic-carousel</a>, and
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-list-box">basic-list-box</a>
    components in ES6. We transpile the ES6 source to ES5 using Babel.
    Developers wanting to incorporate the components into ES6 applications can
    consume the original source, while devs working in ES5 can still easily
    incorporate these components into their applications.
  </li>
  <li>
    <strong>We have restructured the way we distribute these components to use
    npm 3 instead of Bower.</strong>
    The primary basic-web-components repository is now a monorepo: a single
    repository used to manage multiple packages separately registered with npm.
    This is much, much easier for us to maintain than our prior arrangement, in
    which Bower had forced us to maintain a constellation of separate
    repositories for our Bower packages. Using npm for web component
    distribution will likely bring its own challenges, but we're confident the
    much larger npm community will address those issues over time.
  </li>
  <li>
    <strong>Because we are just using JavaScript now, component files can be included
    with regular script tags instead of HTML Imports.</strong>
    That erases any concerns about cross-browser support for HTML Imports, and
    generally simplifies including these web components in an existing
    application build process. For example, instead of requiring use of a
    specialized tool like Vulcanize, developers can incorporate Basic Web
    Components into their applications using more popular tools like Browserify
    and WebPack.
  </li>
  <li>
    <strong>We are now offering a library of web component JavaScript mixins.</strong>
    See this
    <a href="http://component.kitchen/blog/posts/building-web-components-from-a-loose-framework-of-mixins">blog post</a>
    for some background on that strategy. Mixins
    <a href="http://component.kitchen/blog/posts/implementing-web-component-mixins-as-functions">take the form of functions</a>
    that can be applied to any component class without requiring a common
    runtime or framework. These mixins are collected in a new package,
    <a href="https://github.com/basic-web-components/basic-web-components/tree/master/packages/basic-component-mixins">basic-component-mixins</a>.
    See that package for details, including documentation our initial set of 25
    web component mixins. We believe this arrangement will make it much easier
    for people to adopt key features of the Basic Web Components in their own
    components.
  </li>
</ol>
<p>
  As we first noted when we first looked at
  <a href="http://component.kitchen/blog/posts/an-evaluation-of-polymer-micro-as-a-minimal-web-component-framework">using polymer-micro instead of full Polymer</a>,
  there are some distinct downsides to moving away from full Polymer:
</p>
<ul>
  <li>
    We can no longer use Polymer's Shady DOM to emulate Shadow DOM on older
    browsers, so anyone targeting browsers other than Google Chrome must include
    the full webcomponents.js polyfill. However, all four browser vendors are
    racing to implement native Shadow DOM v1, and it seems likely we will see
    all of them deliver native supoprt later this year. While using the full
    polyfill incurs a performance penalty today, we are very happy to be writing
    code that is squarely aimed at the future.
  </li>
  <li>
    We are left for the time being without a simple way to let developers style
    our components. Polymer provided a plausible styling solution, although it's
    based on CSS Variables (not in all browsers yet), and relies on proprietary
    extensions to CSS Variables (non-standard; unlikely to appear in any browser
    soon). So styling remains an issue for us — but then again, it's currently
    an unsolved problem for web components generally.
  </li>
</ul>
<p>
  Overall, for our project, we think the advantages of writing in plain
  JavaScript outweight any disadvantages. We're very happy to be able to write
  highly functional web components without having to use a monolithic framework
  and an accompanying required runtime. And so far, our mixin strategy is
  letting us maintain an elegant factoring of our component code, while avoiding
  the limitations of a single-inheritance class hierarchy.
</p>
<p>
  That said, we think frameworks are certainly an appropriate tool for many
  teams. For certain projects, we enjoy working in frameworks such as Polymer
  and React. One of the tremendous advantages of web components is that they're
  a <em>standard</em>. That lets us write our components in the way that makes
  most sense for us, while still allowing anyone to incorporate those components
  into applications written in other ways. In particular, Polymer remains the
  most active web component framework, so interop with Polymer is a critical
  feature for all our components. As a simple demonstration, we've posted a
  <a href="https://github.com/basic-web-components/carousel-with-tabs">carousel-with-tabs</a>
  example showing use of our basic-carousel component with Polymer's
  paper-tabs component.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Implementing web component mixins as functions</title>
      <pubDate>Tue, 05 Jan 2016 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/implementing-web-component-mixins-as-functions</link>
      <guid>http://component.kitchen/blog/posts/implementing-web-component-mixins-as-functions</guid>
      <description><![CDATA[
      <p>
  In response to our last post on
  <a href="/blog/posts/building-web-components-from-a-loose-framework-of-mixins">building components from a loose collection of mixins</a>,
  a helpful commenter
  <a href="https://plus.google.com/+JanMiksovsky/posts/bFBBGB8kEs8">referred us to another mixin library</a>
  he had released called <a href="https://github.com/justinfagnani/mixwith.js">mixwith.js</a>.
  That library treats mixins more as a pattern than a thing. In that pattern, a
  mixin is simply a function that takes a base class and returns a subclass of
  that base class with the desired new features.
</p>
<p>
  We were intrigued by this approach. As we've blogged about before, we're
  really only interested in coding approaches that can be shared with other
  people. This functional approach would allow us to lower the barrier to
  adopting a given mixin. As much as we like the Composable class discussed in
  that earlier post, using mixins that way requires adoption of that class. It's
  not quite a framework — it's more of a kernel for a framework — but it's still
  a bit of shared library code that must be included to use that style of mixin.
</p>
<p>
  Here's an example of a mixin class using that Composable approach. This
  creates a subclass of HTMLElement that incorporates a TemplateStamping mixin.
  That mixin will take care of stamping a `template` property into a Shadow
  DOM shadow tree in the element's `createdCallback`.
</p>
<pre>
<code>
import Composable from 'Composable'
import TemplateStamping from 'TemplateStamping';

class MyElement extends Composable.compose(HTMLElement, TemplateStamping) {
  get template() {
    return `Hello, world.`;
  }
}
</code>
</pre>
<p>
  That's pretty clean — but notice that we had to `import` two things:
  the Composable helper class, and the TemplateStamping mixin class.
</p>
<p>
  The functional approach implements the mixin as a function that applies
  the desired functionality. The mixin is self-applying, so we don't need a
  helper like Composable above. The example becomes:
</p>
<pre>
<code>
import TemplateStamping from 'TemplateStamping';

class MyElement extends TemplateStamping(HTMLElement) {
  get template() {
    return `Hello, world.`;
  }
}
</code>
</pre>
<p>
  That's even cleaner. At this point, we don't even really have a framework
  per se. Instead we have a convention for building components from mixin
  functions. The nice thing about that is that such a mixin could conceivably be
  used with custom elements created by other frameworks. Interoperability isn't
  guaranteed, but the possibility exists.
</p>
<p>
  We like this so much that we've changed out nascent
  <a href="https://github.com/ComponentKitchen/core-component-mixins">core-component-mixins</a>
  project to use mixin functions. Because there's so little involved in adopting
  this sort of mixin, there's a greater chance it will find use, even among
  projects that write (or claim to write)
  <a href="nobody-writes-production-web-components-in-vanilla-js-so-using-a-framework-makes-total-sense">web components in plain javascript</a>.
  Again, that should accelerate adoption.
</p>
<p>
  The most significant cost we
  <a href="https://github.com/ComponentKitchen/core-component-mixins/issues/1">discussed in making this change</a>
  is that a mixin author needs to write their mixin methods and properties to
  allow for composition with a base class. The Composable class had provided
  automatic composition of methods and properties along the prototype chain
  according to a set of rules. In a mixin function, that work needs to be done
  manually by the mixin author.
</p>
<p>
  We've identified a series of
  <a href="https://github.com/ComponentKitchen/core-component-mixins/blob/master/Composition%20Rules.md">composition rules</a>
  that capture our thinking on how best to write a mixin function that can
  safely applied to arbitrary base classes. The rules are straightforward, but
  do need to be learned and applied. That said, only the <em>authors</em> of a
  mixin need to understand those, and that's a relatively small set of people.
</p>
<p>
  Most people will just need to know how to <em>use</em> a mixin — something
  that's now as easy as calling a function.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Building web components from a loose framework of mixins</title>
      <pubDate>Mon, 07 Dec 2015 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/building-web-components-from-a-loose-framework-of-mixins</link>
      <guid>http://component.kitchen/blog/posts/building-web-components-from-a-loose-framework-of-mixins</guid>
      <description><![CDATA[
      <p>
  We think it&rsquo;s generally necessary to use
  <a href="http://component.kitchen/blog/posts/nobody-writes-production-web-components-in-vanilla-js-so-using-a-framework-makes-total-sense">some sort of framework to develop web components</a>,
  but that framework may not have to be monolithic in nature. Instead, the
  framework might be built entirely as mixins on top of a kernel that enables
  <a href="http://component.kitchen/blog/posts/composing-mixins-to-make-a-solid-foundation-for-web-components">mixin composition</a>.
  Rather than invoking a framework&rsquo;s class constructor, one would simply
  compose the desired mixins together to create an instantiable web component.
</p>
<p>
  We&rsquo;ve been prototyping a completely mixin-oriented approach to component
  development in a project called
  <a href="https://github.com/ComponentKitchen/core-component-mixins">core-component-mixins</a>.
</p>
<ul>
  <li>
    This relies on the
    <a href="https://github.com/ComponentKitchen/Composable">Composable</a>
    facility as the kernel to compose mixins in JavaScript. An alternative mixin
    strategy could be used as long it retained the same general degree of
    expressiveness. It would be ideal if multiple web component frameworks could
    agree on a mixin architecture so that we could share some of these mixins.
    We&rsquo;d be happy to use a different mixin strategy in order to
    collaborate with more people.
  </li>
  <li>
    The repo&rsquo;s /src folder shows a core set of component mixins for
    template stamping, basic attribute marshaling, and Polymer-style automatic
    node finding. For example, the TemplateStamping mixin will add a
    createdCallback that creates a shadow root and clones into it the value of
    the component's template property:
    <pre>
import TemplateStamping from 'core-component-mixins/src/TemplateStamping';

class MyElement extends Composable.compose(HTMLElement, TemplateStamping) {
  get template() {
    return `
      &lt;style&gt;
      :host {
        font-weight: bold;
      }
      &lt;/style&gt;
      Hello, world.
    `;
  }
}
    </pre>
    Use of the TemplateStamping mixin takes care of details like shimming any
    <code>&lt;style&gt;</code> elements found in the template when running under
    the Shadow DOM polyfill.
  </li>
  <li>
    That /src folder contains a sample ReactiveElement base class that pre-mixes the
    three core mixins mentioned above to create a reasonable starting point for
    custom elements. The above example becomes:
    <pre>
import ReactiveElement from 'core-component-mixins/src/ReactiveElement';

class MyElement extends ReactiveElement {
  get template() {
    return `
      &lt;style&gt;
      :host {
        font-weight: bold;
      }
      &lt;/style&gt;
      Hello, world.
    `;
  }
}
    </pre>

    Use of the ReactiveElement class is entirely optional
    &mdash; you could just as easily create your own base class using the same
    mixins.
  </li>
  <li>
    The /demo folder shows some examples of components created with this
    mixin-based framework. such as
    <a href="https://github.com/ComponentKitchen/core-component-mixins/tree/master/demos/Hello%20World">Hello World</a>
    example.
  </li>
  <li>
    A demo of a
    <a href="https://github.com/ComponentKitchen/core-component-mixins/tree/master/demos/X-Tag">hypothetical X-Tag implementation</a>
    shows how a framework can use mixins to create its own custom
    element base class. In that demo, the hypothetical framework adds support
    for a mixin that provides X-Tag&rsquo;s &ldquo;events&rdquo; sugar, but
    leaves out the mixin for automatic node finding. The point is that
    frameworks and apps can opt in to the component features they want.
  </li>
  <li>
    In this approach, web component class definition is generally kept separate
    from custom element registration. That is, there&rsquo;s no required entry
    point like Polymer() to both create the class and register it in a single
    step. We personally feel that keeping those two steps separate makes each
    step clearer, but that&rsquo;s a matter of taste. If you feel that combining
    those steps makes your code easier to write or read, it&rsquo;s easy enough
    to accomplish that. The X-Tag demo shows how a framework could define an
    entry point for class definition and registration.
  </li>
  <li>
    The mixin architecture explicitly supports custom rules for composing
    specific properties. That&rsquo;s intended for cases like the
    &ldquo;properties&rdquo; key in Polymer behaviors, where object values
    supplied by multiple mixins need to get merged together. The Composable
    kernel supports that, although none of the demos currently show off that
    feature.
  </li>
</ul>
<p>
  Taken collectively, these core component mixins form the beginnings of a
  deliberately loose but useful framework for web component development.
  They&rsquo;re still rudimentary, but they already provide much of
  <a href="http://component.kitchen/blog/posts/an-evaluation-of-polymer-micro-as-a-minimal-web-component-framework">what we need from a layer like polymer-micro</a>.
  We think this strategy confers a number of advantages:
</p>
<ol>
  <li>
    <strong>This is closer to the metal.</strong>
    The only new thing here is the concept of a mixin. Everything else is part
    of the web platform. There&rsquo;s no special class constructor required to
    perform black-box operations on a component. There&rsquo;s nothing new to
    master (like React&rsquo;s JSX or Polymer&rsquo;s &lt;dom-element&gt;)
    that&rsquo;s not already in the platform. There's no sugaring provided out
    of the box &mdash; and that&rsquo;s a good thing.
  </li>
  <li>
    <strong>Each mixin can focus on doing a single task really well.</strong>
    For example, the TemplateStamping mixin just creates a shadow root and
    stamps a template into it. The only real work it&rsquo;s doing is to
    normalize the use of native vs polyfilled Shadow DOM &mdash;&nbsp;that is,
    the work you&rsquo;d need to do anyway to work on all browsers today. Given
    the boilerplate nature of that task, it&rsquo;s reasonable to share that
    code with a mixin like this. Once all the browsers support Shadow DOM v1
    natively, this mixin could be simplified, or dropped entirely, without
    needing to rearchitect everything.
  </li>
  <li>
    <strong>You can stay as close to/far from the platform as you want.</strong>
    Most user interface frameworks take you far away from the platform in one
    giant step. Here you have fine-grained control over each step you take
    toward a higher level of abstraction. Each mixin takes you a tiny bit
    further away from the platform, and in exchange for the efficiency boost the
    mixin provides, you have to accept some trade-offs: performance, mystery,
    etc. That&rsquo;s an unavoidable price for sharing code, but at least this
    way you can decide how much you want to pay.
  </li>
  <li>
    <strong>There's a potential for cross-framework mixins.</strong>
    If multiple web component frameworks could agree on a mixin architecture,
    there&rsquo;d at least be a chance we could share good solutions to common
    higher-level problems at the sub-component level. When Component Kitchen
    creates a mixin to support, say, accessibility in a list-like web component,
    it would be great if we could make that available to people developing
    list-like web components in other frameworks. While any framework could in
    theory adopt some other framework&rsquo;s mixin format, mixins are usually
    intimately tied to a framework. Explicitly deciding to factor mixins into a
    separable concept may make cross-framework mixins more feasible.
  </li>
</ol>
<p>
  It&rsquo;s worth remembering that web components are, by their very nature,
  interoperable. If you decide to write a component using an approach like this,
  it&rsquo;s still available to someone who&rsquo;s using a different framework
  (Polymer, say). The reverse is also true. That means any team can pick the
  approach that works for them, while still sharing user interface elements at
  the component level.
</p>
<p>
  As we&rsquo;re experimenting with these mixin ideas in prototype form,
  we&rsquo;re opportunistically trying some other technology choices at the same
  time:
</p>
<ul>
  <li>
    These mixins are written in ES6. As the polymer-micro blog post mentioned,
    we&rsquo;re finding that ES6 makes certain things easy enough in JavaScript
    that we can use the DOM API directly, rather than relying on a framework for
    sugar. Transpiling with
    <a href="https://babeljs.io/">Babel</a>
    feels like a fine temporary solution while waiting for native ES6
    implementations in all browsers.
  </li>
  <li>
    While the core component mixins are written in ES6, they can still be used
    by plain ES5 apps. The
    <a href="https://github.com/ComponentKitchen/core-component-mixins/tree/master/demos/Hello%20World%20(ES5)">Hello World (ES5)</a>
    demo shows this in practice.
  </li>
  <li>
    The TemplateStamping mixin assumes use of the Shadow DOM polyfill if you
    want to support browsers that don&rsquo;t yet support Shadow DOM. If the
    majority of the world&rsquo;s web users have a Shadow DOM v1-capable browser
    by, say, the second half of 2016, we think businesses might accept using the
    polyfill to support the shrinking number of users with older browsers. To
    the extent using that polyfill has issues, those issues should diminish over
    time.
  </li>
  <li>
    We use JavaScript module imports as the dependency mechanism rather than
    HTML Imports. That lets us leverage tools like
    <a href="http://browserify.org/">browserify</a>
    for concatenation rather than Vulcanize. So far, that&rsquo;s working okay.
    ES6 template strings let us easily embed HTML directly inside of JavaScript
    files, instead of putting JavaScript code inside of HTML files as we did
    with HTML Imports. Both packaging formats can work, but given the need for
    JavaScript modules anyway, it seems worthwhile for us to see what we can
    build with modules alone. One thing we miss: an equivalent of HTML
    Import&#39;s &ldquo;document.currentScript&rdquo; so that a module can load
    a resource from a path relative to the JavaScript source file.
  </li>
  <li>
    We&rsquo;re trying out npm as the primary means of component distribution.
    We think that npm 3&rsquo;s support for dependency flattening addresses much
    of the need for Bower. We think the combination of ES6 modules and npm may
    prove to be a better way to distribute components, so we&rsquo;re trying
    that out with this prototype to see if we could make the switch to dropping
    Bower entirely. So far, this feels very good.
  </li>
</ul>
<p>
  This mixin-based component framework isn&rsquo;t done, but feels like
  it&rsquo;s reached the point where it&rsquo;s &ldquo;good enough to
  criticize&rdquo;. Please share your feedback at;
  <a href="https://twitter.com/ComponentK">@Component</a>
  or
  <a href="https://plus.google.com/%2BComponentKitchen">+ComponentKitchen</a>.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Composing mixins to make a solid foundation for web components</title>
      <pubDate>Mon, 30 Nov 2015 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/composing-mixins-to-make-a-solid-foundation-for-web-components</link>
      <guid>http://component.kitchen/blog/posts/composing-mixins-to-make-a-solid-foundation-for-web-components</guid>
      <description><![CDATA[
      <p>
  We've been searching for a way to quickly create web components by composing
  together pre-defined user interface behaviors, and we have some progress to
  share on that front.
</p>
<p>
  Web components are a great way to package user interface behavior, but they
  may not be the most interesting <em>fundamental</em> unit of behavior. There
  are certain aspects of behavior which you'd like to be able to share across
  components: accessibility, touch gestures, selection effects, and so on. Those
  things aren't top-level components in their own right; they're abstract
  aspects of behavior.
</p>
<p>
  This is something like saying that a chemical molecule is not the fundamental
  unit of physical behavior — the atoms that make up the molecule are. But you
  can't generally handle solitary atoms; atoms react and organize themselves
  into molecules. Likewise, a browser can only handle web components, not
  abstract behaviors. If we imagine a web component as a molecule, what's the
  equivalent of an atom? That is, can we decompose a web component into a
  more fundamental coding unit?
</p>
<p>
  One way to answer this question is to consider a web component as a custom
  element class. Is there a way we can decompose a class into its fundamental
  abstract behavioral aspects? The usual way to compose class behavior in
  JavaScript is with
  <a href="https://en.wikipedia.org/wiki/Mixin">mixins</a>, so perhaps mixins
  can form the fundamental unit of user interface behavior. That is, we'd like
  to be able to compose mixins together to create web component classes.
</p>
<p>
  For that purpose, mixins present some challenges:
</p>
<ul>
  <li>
    The simplest approach to JavaScript mixins will overwrite existing on a
    class, but that's not always desirable. Many web component behaviors want to
    augment an existing method like <code>createdCallback</code>. That is,
    the base class' method <em>and</em> the mixin's method should run.
  </li>
  <li>
    There's no standard JavaScript implementation of mixins. While many user
    interface frameworks (React, Polymer, etc.) include a mixin strategy, those
    are intimately tied to the framework itself. You can very quickly write a
    simple function to copy a mixin onto a class prototype, but that won't
    accommodate the range of complexity needed to define interesting web
    component behaviors.
  </li>
</ul>
<p>
  We thought it would be interesting to create a general-purpose mixin
  architecture that's flexible enough to serve as a foundation for creating web
  components in plain JavaScript. The initial result of that work is a
  facility we call
  <a href="https://github.com/ComponentKitchen/Composable">Composable</a>.
</p>
<p>
  Composable takes the form of a general-purpose factory for composing classes
  and objects from mixins. The most interesting part about it is its use of
  <em>composition rules</em> that let you decide how a mixin's properties and
  methods should be combined with those of the class you're adding the mixin to.
</p>
<p>
  Composable itself is entirely independent of web components, but we've
  designed it to serve as a micro-kernel for web component library or framework.
  An example in the Composable
  <a href="https://github.com/ComponentKitchen/Composable/blob/master/README.md">ReadMe</a>
  illustrates how it could be used to construct web components:
</p>

<pre>
// Create a general-purpose element base class that supports composition.
let ComposableElement = Composable.compose.call(HTMLElement, Composable);

// A mixin that sets an element's text content.
class HelloMixin {
  createdCallback() {
    this.textContent = "Hello, world!";
  }
}

// A sample element class that uses the above mixin.
let HelloElement = ComposableElement.compose(HelloMixin);

// Register the sample element class with the browser.
document.registerElement('hello-element', HelloElement);

// Create an instance of our new element class.
let element = document.createElement('hello-element');
document.body.appendChild(element); // "Hello, world!"
</pre>

<p>
  We'll share more on this direction as we go, but for now we wanted to share this
  as a fundamental building block. Even if you're not creating web components,
  you could use Composable to give your application or framework a flexible
  mixin architecture.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>An evaluation of polymer-micro as a minimal web component framework</title>
      <pubDate>Mon, 02 Nov 2015 17:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/an-evaluation-of-polymer-micro-as-a-minimal-web-component-framework</link>
      <guid>http://component.kitchen/blog/posts/an-evaluation-of-polymer-micro-as-a-minimal-web-component-framework</guid>
      <description><![CDATA[
      <p>Our <a href="https://github.com/basic-web-components/basic-web-components">Basic Web Components</a> project currently creates its components using Google&#39;s <a href="https://www.polymer-project.org">Polymer</a> framework, but we&#39;ve been evaluating the use of the smaller polymer-micro core as a replacement for full Polymer. The polymer-micro core appears to be a useful web component framework in its own right, and may provide nearly everything a component library like ours needs.</p>
<h2>Is Polymer the best choice for our open project?</h2>
<p>We believe that <a href="/blog/posts/nobody-writes-production-web-components-in-vanilla-js-so-using-a-framework-makes-total-sense">some amount of framework is necessary to create web components</a>. For a very long time,
Polymer has been the primary web component framework. We love Polymer! However,
we feel that Polymer has grown to the point where writing a Polymer app feels
distinctly different from writing a typical HTML app.</p>
<p>Polymer provides numerous helpers that reduce the amount of copy-and-paste boilerplate code required to invoke standard DOM features. In current parlance, it wants to make component code as <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> as possible. For example, Polymer provides a &quot;listeners&quot; key for wiring up event handlers with less code than a direct invocation of the underlying addEventListener(). Polymer&#39;s &quot;properties&quot; key similarly simplifies definition of component properties instead of directly defining property getter/setters on the component prototype and marshalling attributes to properties with attributeChanged().</p>
<p>We think Polymer&#39;s goal is commendable. If you can afford to train up a team of developers on Polymer&#39;s specific way of doing things, your team should be able to crank out web UI code very efficiently.</p>
<p>But as with any higher-level abstraction, these helpers trade off clarity and simplicity for a certain degree of magic and complexity. Each reduction in the amount of component code a developer must write forces an increase in the arcane Polymer-specific knowledge a developer must acquire to write <em>or even read</em> component code. It also hides details that may complicate debugging and maintenance.</p>
<p>For our open source project, those second-order effects reduce the potential pool of project contributors. Our priority is not time-to-market, but rather creating code which is self-evident to our open source users and potential contributors. Although 1 line of Polymer code might do the work of 3 lines of standard web code, if those 3 lines are more understandable to a wider base of developers, we might prefer the longer, clearer version.</p>
<h2>Carrying forward the burden of backward compatibility</h2>
<p>Another issue we&#39;re grappling with is Polymer is very much designed for this era immediately before web components emerge with native support across all mainstream browsers. Polymer wants, quite reasonably, to accommodate browsers that don&#39;t yet support web components. At the same time, Polymer also wants to deliver decent performance, notably on Mobile Safari, which <em>at this time</em> does not support native Shadow DOM. Rather than use the full Shadow DOM polyfill, Polymer introduced its own <a href="https://www.polymer-project.org/1.0/docs/devguide/local-dom.html">Shady DOM</a> approach for approximating Shadow DOM behavior on older browsers.</p>
<p>Shady DOM is an impressive technical accomplishment. But having written a great deal of Shady DOM code this year, it&#39;s our subjective opinion that Shady DOM code feels clunky. Even after months of writing Shady DOM code, wrapping DOM calls with Polymer.dom() still doesn&#39;t feel natural. And it&#39;s hard to explain to someone why they can&#39;t just call appendChild(), but have to call Polymer.dom().appendChild() instead. And while Polymer.dom() is somewhat future-proof, it doesn&#39;t feel future-facing. It erodes the original, extremely elegant vision for Polymer and the web components polyfills: to let people to write web components for future web browsers today.</p>
<p>The alternative to Shady DOM today is to use the <a href="https://github.com/WebComponents/webcomponentsjs">full Shadow DOM polyfill</a>. That entails slower performance and — given inevitable leaks in the abstraction — a greater potential for mysterious bugs. On the plus side, the full Shadow DOM polyfill lets one write clearer, future-facing code. With all the major browser vendors on board with Shadow DOM v1, the need to download and use the Shadow DOM polyfill on most devices should fade over the course of 2016.</p>
<p>We&#39;re also excited about the advent of ES6, with features like arrow functions that let code be more concise. Writing an addEventListener() call is no longer a substantial burden in ES6, or at least not enough to warrant a parallel system for event listener wiring. And using built-in ES6 classes feels better than calling a purpose-focused class factory like Polymer().</p>
<h2>Considering polymer-micro instead of full Polymer</h2>
<p>It turns out that, underneath all of Polymer&#39;s DRY magic, there&#39;s a very clean, simple core called polymer-micro. Polymer is helpfully constructed in three layers: full Polymer on top, a smaller polymer-mini below that, then a tiny polymer-micro at the bottom. The <a href="https://www.polymer-project.org/1.0/docs/devguide/experimental.html#polymer-micro">documentation</a> describes polymer-micro as &quot;bare-minimum Custom Element sugaring&quot;.</p>
<p>Rather than use the full Polymer framework, we&#39;ve been investigating whether polymer-micro on its own could meet our needs. Building on top of polymer-micro confers a number of advantages over writing our own web component framework:</p>
<ul>
<li>Google has already invested an enormous amount of money and resources developing Polymer, including polymer-micro, and will probably continue to do so for the foreseeable future.</li>
<li>The thousands of people using full Polymer today are <em>also</em> using polymer-micro. That means lots of testing of the polymer-micro core.</li>
<li>From its commit history, polymer-micro looks fairly stable. A substantial amount of future Polymer work will likely happen in the upper levels.</li>
<li>In terms of file size, polymer-micro is significantly smaller than full Polymer, although we don&#39;t see that as a huge advantage.</li>
<li>Relying on a small core like polymer-micro makes it easier to migrate to another framework when a better framework comes along.</li>
</ul>
<p>The polymer-micro layer happens to provide most of the features upon which Basic Web Components depend:</p>
<ul>
<li>Custom element registration.</li>
<li>Lifecycle support.</li>
<li>Declared properties.</li>
<li>Attribute deserialization to properties.</li>
<li>Behaviors.</li>
</ul>
<p>On the flip side, Basic Web Components use a number of Polymer features which polymer-micro does <em>not</em> provide:</p>
<ol>
<li><p>Shadow root Instantiation. If you use polymer-micro, you&#39;re expected to create a shadow root yourself.</p>
</li>
<li><p>Templates. If you want to use the <code>&lt;template&gt;</code> element to define initial content of a component&#39;s Shadow DOM, you need to manage that yourself.</p>
</li>
<li><p>Shimming for CSS styles. The full Shadow DOM polyfill requires that CSS be transformed to minimize styles leaking across a custom element boundaries. Full Polymer takes care of that for you, but using polymer-micro directly means that style shimming becomes your concern.</p>
</li>
<li><p>Automatic node finding. This lets your component code refer to a sub-element <code>&lt;button id=&quot;foo&quot;&gt;</code> with <code>this.$.foo</code>. Complex components need a consistent and easy way to refer to subelements within the local Shadow DOM. Polymer&#39;s <code>this.$</code> syntax satisfies those criteria, although we&#39;re really torn as to whether that sugar is worth it. It saves keystrokes, but isn&#39;t a web-wide convention. It may give an unfamiliar flavor to web component code.</p>
</li>
<li><p>ready() callback. Many of the Basic Web Components use Polymer&#39;s <a href="https://www.polymer-project.org/1.0/docs/devguide/registering-elements.html#ready-method">ready callback</a> to initialize themselves. Polymer takes pains to ensure that any Polymer elements inside a component&#39;s local Shadow DOM have their own ready callback fired <em>before</em> the outer component&#39;s ready callback is fired.</p>
</li>
<li><p>CSS mixins. This is Polymer&#39;s current answer for visual themes for components. It&#39;s based on a not-yet-standard proposal for extensions to CSS. Without full Polymer, you have to invent your own theming architecture.</p>
</li>
</ol>
<p>All the above features are provided at the levels above polymer-micro: either polymer-mini or full Polymer. However, those upper levels bring along a number of features we don&#39;t use, or would be happy to drop. Those features include:</p>
<ul>
<li>Data binding</li>
<li>Event listener setup (&quot;listeners&quot; key)</li>
<li>Annotated event listener setup (in markup)</li>
<li>Property change callbacks</li>
<li>Computed properties</li>
<li>reflectToAttribute</li>
</ul>
<p>These features all have some appeal, but in our estimation may add more complexity than they&#39;re worth to an open source project aiming for a general developer audience.</p>
<p>Lastly, there are a few higher-level Polymer features we have to use, but wish
we didn&#39;t have to:</p>
<ul>
<li><p><code>&lt;dom-module&gt;</code>. This is used as a wrapper around a <code>&lt;template&gt;</code> element, but it&#39;s hard to fathom why <code>&lt;dom-module&gt;</code> is necessary. It seems designed to support a use case we don&#39;t care about: defining a template in one file, then using it in a component defined in a separate file. Yet by far the most common way to define a Polymer component is to put its template and script definition in the same file. It&#39;s unfortunate full Polymer doesn&#39;t offer a better way to use a real <code>&lt;template&gt;</code>directly. (Although a trick does let you accomplish that in an unofficial way; see below.)</p>
</li>
<li><p>Polymer.dom(). As noted above, this feels awkward, like you&#39;re not using the web. It&#39;s also confusing to experienced web developers looking at Polymer code for the first time.</p>
</li>
</ul>
<h2>Prototyping a minimal component framework on top of polymer-micro</h2>
<p>With the above motivation, we considered the question: <em>What is the smallest amount of code that must be added to polymer-micro to create a web component framework that meets our project&#39;s needs?</em></p>
<p>This experiment entailed a fair amount of spelunking in the Polymer codebase. That exploration informed the creation of a little prototype web component framework called <a href="https://github.com/ComponentKitchen/polymer-micro-test">polymer-micro-test</a> that uses only polymer-micro as its base. In this prototype framework, we wrote a small amount of code (<a href="https://github.com/ComponentKitchen/polymer-micro-test/blob/master/minimalComponent.js">minimalComponent.js</a>) to implement the 5 numbered features above which we want but are missing in polymer-micro.</p>
<p>We then used the prototype framework to create a couple of sample components, such as a sample t<a href="https://github.com/ComponentKitchen/polymer-micro-test/blob/master/test-element.html">est-element</a> component. A <a href="https://componentkitchen.github.io/polymer-micro-test/index.html">live demo</a> of a simple <a href="https://github.com/ComponentKitchen/polymer-micro-test/blob/master/index.html">page</a> shows the test-element component in use. By virtue of using the full polyfills, components created in this prototype framework can run in all mainstream browsers.</p>
<p>Overall, the results of this experiment were fairly positive. Looking at each feature in turn:</p>
<ol>
<li><p>Creating a shadow root yourself is easy. This is only necessary for components with templates (next point).</p>
</li>
<li><p>Stamping out a template is easy. The smallest amount of code we could envision for this is for a component to declare a &quot;template&quot; property. This can be used in conjunction with HTML Imports for a fairly clean connection between the script and the template:</p>
<pre><code>&lt;template id=&quot;test-element&quot;&gt;
  ... template goes here ...
&lt;/template&gt;

&lt;script&gt;
Polymer({
  is: &#39;test-element&#39;,
  template: currentImport.querySelector(&#39;#test-element&#39;)
});
&lt;/script&gt;
</code></pre><p>Aside: we <em>really</em> like being able to use a plain <code>template</code> to define component content. It turns out that you can actually do this in full Polymer today, although it&#39;s something of a trick that depends upon your component defining an undocumented <code>_template</code> variable. See this <a href="https://gist.github.com/JanMiksovsky/ef59c30222b5d5fc06b5">gist</a>, which works in full Polymer.</p>
</li>
<li><p>Shimming CSS styles took a little investigation, but it turns out the full Shadow DOM polyfill exposes its CSS-shimming code as ShadowCSS. The first time this test framework is going to stamp a template, it just invokes ShadowCSS to shim any <code>&lt;style&gt;</code> elements found in the template. It then saves the shimmed result for subsequent stamping into the shadow root.</p>
</li>
<li><p>Automatic node finding. If we conclude we really need this feature, it&#39;s not that hard to implement ourselves. Right after the test framework stamps a template, it queries for all the elements in the shadow tree that have an <code>id</code> attribute, then adds those elements to <code>this.$</code>. This gives us a type of automatic node finding that meets our needs. Polymer&#39;s own implementation of the same feature is much more complex. It appears to do a lot of tree-parsing so in preparation for data binding, but since we don&#39;t need data binding, we don&#39;t need to do that work.</p>
</li>
<li><p>The ready() method is a bit of a puzzle to us. The Shadow DOM spec already defines two callbacks, createdCallback() and attachedCallback(), that can cover most of what we&#39;re currently doing in ready(). One issue is that createdCallback() and attachedCallback() are synchronous, while the Polymer ready() code takes enormous pains to handle asynchronous calls. That is likely necessary to support their asynchronous data binding model. That is, if your component has a sub-component with data bindings, you want all those asynchronous data bindings to settle down first before your top-level component does its own initialization. Since we&#39;re not interested in data binding, however, it&#39;s not clear whether we need ready(). Our sample element just uses the standard callbacks.</p>
</li>
<li><p>CSS mixins. This remains an open question for us. It&#39;s hard to imagine what we could do to allow component users to theme our components. At the same time, we&#39;re not convinced that the not-yet-standard CSS mixins are going to actually become a standard. The troubled history of vendor-prefixed CSS feature experiments suggests that one company&#39;s early interpretation of a hypothetical, future CSS mixin &quot;standard&quot; might significantly complicate things down the road when a real standard is finally established.</p>
</li>
</ol>
<p>This small prototype framework delivers most of the features required by Basic Web Components. The main exception is that it offers no facility for component theming (point #6 above).</p>
<p>Some other notes:</p>
<ul>
<li><p>Because polymer-micro supports Polymer <a href="https://www.polymer-project.org/1.0/docs/devguide/behaviors.html">behaviors</a> (mixins), we were able to implement all of the prototype&#39;s features in a behavior. That&#39;s quite elegant. It means our sample components can use those features simply by calling the standard Polymer() class factory and listing this prototype behavior in the &quot;behaviors&quot; key. It was a nice surprise that we didn&#39;t have to create our own component class factory for that.</p>
</li>
<li><p>To take advantage of Polymer&#39;s own attribute-to-property marshalling feature, we had to invoke an undocumented internal method in polymer-micro. If more people were building directly on top of polymer-micro, such facilities could probably be promoted to supported features.</p>
</li>
<li><p>Taking advantage of existing Polymers facilities (both official and undocumented) and polyfill features like ShadowCSS means that our little prototype framework can be tiny, less than 1K in size. That gets added to the size of polymer-micro, which is currently about 15K uncompressed. Combined, that 16K is a lot smaller than the full Polymer, about 105K uncompressed.</p>
</li>
<li><p>Any decrease in framework file size is more than offset by the need to use the full web component polyfills, which are much larger than the &quot;lite&quot; version used with Shady DOM. Still, since we think the need for the full polyfills will drop over the course of 2016, we&#39;re not particularly concerned about that.</p>
</li>
</ul>
<h2>Conclusions</h2>
<p>While this is just an experiment, it&#39;s intriguing to consider using polymer-micro as the basis for a minimalist web component framework.</p>
<ul>
<li><p>A minimalist framework leads to component code which we believe is easier for a general web developer to read.</p>
</li>
<li><p>Letting a component developer work at a lower level of abstraction — &quot;closer to the metal&quot; — means they have a greater capacity to diagnose problems when things inevitably go wrong. There&#39;s less mystery to clear away, so problems can be understood and fixed, rather than worked around.</p>
</li>
</ul>
<p>Despite these advantages, we&#39;re not yet ready to say that we&#39;re actually going to <em>use</em> this prototype to create components. As noted above, our goal is to foster a codebase that can be readily comprehensible to a wide audience of web developers. Using a proprietary framework, even a tiny one, impedes that goal. (Basic Web Components traces its ancestry to an earlier component library called QuickUI which <a href="http://blog.quickui.org/2013/12/01/some-lessons-from-an-open-source-project-that-never-gained-critical-mass/">never gained critical mass</a>, in part because it was built on a proprietary framework.)</p>
<p>Using polymer-micro as the basis for a proprietary framework would be better than writing a framework from scratch, but every bit of code added on top of polymer-micro runs the risk of producing a framework in its own right — one distinct and unfamiliar to our developer audience.</p>
<p>A minimalist strategy like this would only have meaning to us if it&#39;s shared by other people. To that end, we&#39;ve begun talking with other web component organizations to explore this idea a bit further. We&#39;re not sure where that discussion will go, but it&#39;s interesting, and might bear fruit in the form of a new, minimalist web component framework. If you&#39;d be interested in participating in that discussion, please ping us at <a href="https://twitter.com/ComponentK">@ComponentK</a>.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Nobody writes production web components in vanilla JS — so using a framework makes total sense</title>
      <pubDate>Mon, 26 Oct 2015 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/nobody-writes-production-web-components-in-vanilla-js-so-using-a-framework-makes-total-sense</link>
      <guid>http://component.kitchen/blog/posts/nobody-writes-production-web-components-in-vanilla-js-so-using-a-framework-makes-total-sense</guid>
      <description><![CDATA[
      <p>You may hear someone say they avoid using React, Polymer, Angular, or some other
framework du jour, and that they prefer to write their front end code in vanilla
JavaScript instead. But when it comes to writing web components, it seems
<em>everybody</em> ends up writing atop a framework — even if it&#39;s a tiny framework of
their own devising. Production web components written in vanilla JS appear to be
very rare.</p>
<p>It seems there&#39;s just a bit too much work involved to meet even baseline
expectations for a custom element. To handle instantiation, for example, you
might need to:</p>
<ol>
<li><p>Create a shadow root on the new instance.</p>
</li>
<li><p>Stamp a template into the shadow root.</p>
</li>
<li><p>Marshall any attributes from the element root to the corresponding component
properties. This process breaks down into more work, such as:</p>
<ul>
<li>Loop over the set of attributes on the element.</li>
<li>For each attribute, see if the component defines a corresponding property.
If you want to support conventionally hyphenated attribute names (&quot;foo-bar&quot;),
you&#39;ll want to first map those attribute names to conventionally camel-cased
property names (fooBar).</li>
<li>If the type of a target property is numeric or boolean, parse the
string-valued attribute to convert it to a value of the desired type.</li>
<li>Set the property to the value.</li>
</ul>
</li>
</ol>
<p>Given this amount of work to simply instantiate the component, it&#39;s easy to see
why most efforts to create interesting components typically end up relying on
shared code. You might write a single web component in vanilla JS, but as soon
as you start your second component, you&#39;ll be dying to factor the boilerplate
into shared code… And now you&#39;re constructing a framework.</p>
<p>That&#39;s not necessarily a bad thing. It only means that, when you hear someone
say that they want to write a component-based app, but don&#39;t want to use any
framework at all, you have to take that with a grain of salt. It&#39;s possible the
person has — perhaps unintentionally — ended up building the foundations of
their own web component framework.</p>
<p>Does it matter whether that code is called a framework? Wikipedia enumerates these <a href="https://en.wikipedia.org/wiki/Software_framework">software framework</a> hallmarks:</p>
<ul>
<li>inversion of control (control flow dictated by the framework, not the code on
top of it)</li>
<li>default behavior</li>
<li>extensibility</li>
<li>non-modifiable framework code</li>
</ul>
<p>Given this definition, it seems hard to conclude that frameworks are bad per se.
Surely there are good frameworks as well as bad frameworks.</p>
<p>Perhaps one reason people shy away from the concept of a framework is that, as a
framework achieves higher levels of abstraction, it becomes something tantamount
to a domain-specific language. If you and I both thoroughly understand
JavaScript, but we are using different JavaScript frameworks, then in practice
we may not find each other&#39;s code mutually intelligible.</p>
<p>Since the term &quot;framework&quot; can provoke strong negative reactions, authors of
such code may actually care whether their code is labeled a framework or not.
Google, for example, seems to take great pains to avoid describing its own
Polymer project as a framework. They call it a &quot;library&quot;, which sounds perhaps
smaller or less threatening. But Polymer easily meets all of the above framework
criteria. For example, Polymer&#39;s internal asynchronous task-scheduling
infrastructure establishes the flow of control in a Polymer application,
determining when to invoke component lifecycle callbacks and property observers.</p>
<p>Whether you like the idea of a framework or not, when it comes to web
components, the DOM API is so rudimentary that, in practice, that API alone does
not provide a sufficient framework for web component development. As long as
that remains the case, the use of a JavaScript web component frameworks seems
unavoidable. If you really, really want to avoid writing or using code that
meets the above definition of &quot;framework&quot;, perhaps you can do so and still be
productive, but that seems like a hard way to go.</p>
<p>For our own work, we <em>want</em> to be using a popular web component framework, be it
Polymer or something else. If our alternative were to write a proprietary, ad
hoc framework of our own, which was shared by no one else, we would likely waste
a lot of time solving problems others have already solved.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>We’re shutting down our web component catalog</title>
      <pubDate>Mon, 19 Oct 2015 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/were-shutting-down-our-web-component-catalog</link>
      <guid>http://component.kitchen/blog/posts/were-shutting-down-our-web-component-catalog</guid>
      <description><![CDATA[
      <p>We launched this Component Kitchen site in April 2014 with a web component catalog as its centerpiece. Today we&#39;re shutting down that catalog so we can focus on web component consulting and our open web components projects, including the <a href="https://github.com/webcomponents/gold-standard/wiki">Gold Standard Checklist for Web Components</a> and the general-purpose <a href="https://github.com/basic-web-components/basic-web-components">Basic Web Components</a> library.</p>
<p>Running the component catalog was a great way to learn about building production
applications using web components and Google&#39;s Polymer library. But we&#39;ve come
to feel that the catalog&#39;s utility is limited, and it no longer makes economic
sense to continue it.</p>
<ul>
<li><p>As in any online space, much of what is freely given publicly is, unfortunately,
junk. Many registered components are &quot;Hello, world!&quot;, or trivial wrappers of a
third-party library, or utilities so specialized as to be useful to no one but
their authors. That makes it hard to find something worth using.</p>
</li>
<li><p>Even potentially useful components are seldom written at a level of production
quality. We tried to start a &quot;component of the week&quot; blog post series in
late 2014. We would sift through a dozen components just to find one that even
<em>worked</em> outside the narrow confines of its demo. This isn&#39;t necessarily the
fault of the component authors — it&#39;s really hard to write a solid web component
today. (That&#39;s one reason we believe that establishing a Gold Standard for web
component quality is a vital project.) We also believe that the web user
interface framework vendors, such as Polymer and X-Tag, need to invest more
heavily in making it easy to create components that meet that standard.</p>
</li>
<li><p>Our catalog pages showed GitHub stars, but the direct GitHub metadata for
projects like web components isn&#39;t all that useful in assessing a project&#39;s
quality. A GitHub star doesn&#39;t tell you whether anyone has actually tried a
project, whether they thought it was good, whether they used it, or whether
they&#39;re still using it. We have some ideas for how to compile better indications
of a web component project&#39;s utility, but they would require a larger investment
of our resources than we can afford.</p>
</li>
<li><p>People want to see a component project&#39;s own documentation, not a third-party
repackaging of that documentation. We think that&#39;s true for any online catalog,
including successful ones like npm. When we find a package on npm, we never read
the package details there, because we&#39;ll have to go to the actual GitHub
repository to form an assessment of whether it&#39;s worth actually trying the
package.</p>
</li>
<li><p>GitHub itself could easily improve its own search and ranking features to the
point where external catalogs would struggle to add value. We&#39;d rather not
compete with them.</p>
</li>
<li><p>As a result of the above points, if you want to find a foobar web component,
it&#39;s easier to google for &quot;foobar web component&quot; than to consult a purpose-built
catalog. If you follow the search results to GitHub, you&#39;ll end up where you
wanted to go anyway.</p>
</li>
<li><p>It turns out that a coherent <em>collection</em> of components designed and implemented
together is more interesting than individual components from multiple authors.
While we had plans to feature component collections, we didn&#39;t think the payoff
would be high enough. Again, the collection creator is more interested in
driving traffic to their collection&#39;s own site, and that&#39;s probably what the
component customer is interested in seeing too.</p>
</li>
</ul>
<p>Retiring the catalog lets us invest more time in the projects that we think
matter more. People who want a component catalog can use
<a href="https://customelements.io/">customelements.io</a>, which has seen many
improvements lately. Also, as a service to people who have made deep links to
our catalog&#39;s component pages, for the indefinite future we will continue to
serve up tombstone pages at those URLs that offer a link to the corresponding
repository on GitHub.</p>
<p>When we started our catalog, there were only about 40 publicly registered web
components — now the number is in the thousands. We really appreciate all of the
people who visited our catalog in the last year and a half, who built a great
component we could feature, and who took the time to give us feedback or a
shout-out on social sites. We&#39;re still excited to be working in this
transformative web components space, and look forward to sharing our ongoing
work here soon.</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>The Gold Standard checklist for web components</title>
      <pubDate>Wed, 27 May 2015 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/the-gold-standard-checklist-for-web-components</link>
      <guid>http://component.kitchen/blog/posts/the-gold-standard-checklist-for-web-components</guid>
      <description><![CDATA[
      <p>
For the last few months, we've been excited to help a new open project get off
the ground: the
<a href="https://github.com/webcomponents/gold-standard/wiki">Gold Standard checklist for web components</a>.
The checklist’s goal is to define a consistent, high quality bar for web
components.
</p>
<p>
We believe web components should be every bit as predictable, flexible,
reliable, and useful as standard HTML elements. When someone is working in HTML,
they should be able to work as if all elements work the same. They shouldn’t
need to learn a special set of constraints or limitations that apply to specific
custom elements. They already know how standard HTML elements behave; new custom
elements should behave just like that.
</p>
<p>
The standard HTML elements establish an incredibly high bar for quality. For
example, you can use the standard elements in any combination, and they’ll not
only work, the result is usually predictable and reasonable. But, without a
great deal of care, custom elements don’t support that same degree of
flexibility by default. It’s all too easy to create a custom element that only
works when it’s used in a very particular way.
</p>
<p>
The project began by defining what it is that makes a standard HTML element
<em>feel</em> like a standard HTML element. It seems no one before ever wrote
down all the criteria that govern the expected behavior of a new standard HTML
element. We all generally know how HTML elements should behave, and through
careful design and testing, new standard elements eventually measure up to our
expectations.
</p>
<p>
You can think of this as a Turing Test for elements: if you were to encounter an
unfamiliar element in HTML, could you tell whether it was a new standard element
or a custom element? For most custom elements today, it wouldn’t take too long
to discover some unexpected quirk or limitation in the element that would reveal
its custom element nature. This is not for lack of dedication on the component
author’s part. It could simply be the case that they hadn’t considered some
aspect of standard element behavior.
</p>
<p>
To address that, the Gold Standard checklist captures the expected behavior of a
standard HTML element in a form that can guide the creation of new custom
elements. The checklist covers a wide range of topics, from accessibility to
performance to visual presentation. A component that meets that quality bar
should be able to generally satisfy all the expectations of people using that
component. This will greatly facilitating the component’s adoption and use.
</p>
<p>
A variety of people, particularly from Google, have already contributed to the
Gold Standard checklist in its draft stages, and continue to make contributions
to the checklist in its new wiki form. The initial focus of the project has been
to develop a solid set of top-level checklist items. It’s the hope of the
project contributors that every item on the list will be backed by a detailed
explanation of the checklist item: why it’s important, examples of what to do or
not to do, sample source code, and other resources.
</p>
<p>
If you’re interested in creating or using high-quality components, please take a
look at the checklist. The project welcomes comments and suggestions as issues,
or direct contributions through pull requests.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Try our interactive web components tutorial</title>
      <pubDate>Mon, 12 Jan 2015 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/try-our-interactive-web-components-tutorial</link>
      <guid>http://component.kitchen/blog/posts/try-our-interactive-web-components-tutorial</guid>
      <description><![CDATA[
      <p>
  We've just posted an
  <a href="/tutorial">interactive web components tutorial</a>
  that teaches the basic concepts with editable live demos. We hope you'll find
  that this tutorial:
</p>
<ul>
  <li>
    Explains the key principles at a quick pace under your control.
  </li>
  <li>
    Illustrates the principles through engaging, live HTML demos. We think the
    best way to learn a technology is to play with it yourself!
  </li>
  <li>
    Introduces concepts from the perspective of the component user. Most web
    component presentations start with the assumption that you're a developer
    creating a component from scratch. But one of the great things about web
    components is that components can be <em>used</em> by a wider audience than
    the people who can <em>create</em> components.
  </li>
  <li>
    Only requires knowledge of HTML. If you're one of the many people who has
    read or written HTML, but don't consider yourself to be a developer, this is
    the tutorial for you. And if you are a developer, we still think this
    presents the concepts in an approchable and useful manner.
  </li>
</ul>
<p>
  Please check it out, share it, and let us know what you think!
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Print a handy 2015 wall calendar built with web components</title>
      <pubDate>Sun, 21 Dec 2014 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/print-a-handy-2015-wall-calendar-built-with-web-components</link>
      <guid>http://component.kitchen/blog/posts/print-a-handy-2015-wall-calendar-built-with-web-components</guid>
      <description><![CDATA[
      <p>
  If you hold or participate in project management discussions, consider
  printing out this handy
  <a href="http://janmiksovsky.github.io/printable-wall-calendar/">Printable Wall Calendar</a>
  that was quickly built with web components.
</p>
<figure>
  <a href="http://janmiksovsky.github.io/printable-wall-calendar/">
    <img src="/static/20241020005925/images/blog/Printable Wall Calendar.jpg" style="max-width: 100%;">
  </a>
</figure>
<p>
  Jan constructed the original version of this calendar years ago to answer
  to two simple calendar questions that often come up in planning discussions:
</p>
<ol>
  <li>
    <strong>On which day of the week will a given date fall?</strong>
    If some asks, "Can you ship this on June 15?", you often want to know,
    "Well, what day of the week is that? Is that even a weekday?"
  </li>
  <li>
    <strong>What's the date of a given day of the week?</strong>
    Maybe your agile development group likes to make big releases on Mondays.
    If you think you might release something two Mondays from now, what date is
    that?
  </li>
</ol>
<p>
  You can answer these questions by pulling out your phone, but sometimes paper
  is faster than gadgets. A wall calendar can answer these questions nearly
  instantly — as long as the calendar is well designed for this purpose. The
  problem is that most wall calendars have way too much clutter. They're
  designed for a previous era in which people <em>wrote critical scheduling
  information on a paper wall calendar</em>. No one does that now. If instead
  you just want a calendar to answer the questions above, its design can be much
  simpler. A simpler design means the actual calendar dates can be bigger and
  easier to read across a room.
</p>
<p>
  This calendar was built using the
  <a href="http://component.kitchen/components/basic-web-components/basic-calendar-month">basic-calendar-month</a>
  component, which takes care of all the date math, as well as handling
  localized month and day names for a huge number of languages and regional
  preferences. To build a year calendar was a simple matter of slapping 12 of
  these month calendars together and applying some styling.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>basic-list-box — keyboard-navigable list box, now with ARIA support for better accessibility</title>
      <pubDate>Wed, 10 Dec 2014 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/basic-list-box-keyboard-navigable-list-box-now-with-aria-support-for-better-accessibility</link>
      <guid>http://component.kitchen/blog/posts/basic-list-box-keyboard-navigable-list-box-now-with-aria-support-for-better-accessibility</guid>
      <description><![CDATA[
      <p>
  This review focuses not on a component, but an <em>aspect</em> of a component
  called
  <a href="http://component.kitchen/components/basic-web-components/basic-list-box">basic-list-box</a>.
  Component Kitchen released that component under the aegis of the
  <a href="https://github.com/basic-web-components/components-dev/wiki">Basic Web Components</a>
  project. In our reviews, we want to avoid focusing too much on
  our own work, but in this case we can happily feature a small but important
  contribution to the project from developer
  <a href="https://twitter.com/marcysutton">Marcy Sutton</a>,
  a passionate advocate for building an accessible web that can be used by
  everyone.
</p>
<p>
  An important goal for Basic Web Components is to make all its components as
  accessible as possible, for several reasons. You can use these components,
  used as is, and reach the broadest possible range of users. You can extend
  these components or incorporate them into your own components, and
  automatically pick up a degree of support for accessibility. And you can refer
  to these components as good examples of how to implement accessibility if
  you’re creating a new component entirely from scratch. This work is just
  beginning, and by no means perfect, but those are the goals. The good news is
  that improvements are made to the components, anyone using those components
  can easily pick up those improvements for free.
</p>
<p>
  As a case in point, Marcy recently contributed an enhancement to
  basic-list-box (and a lower-level base class called
  <a href="http://component.kitchen/components/basic-web-components/basic-selector">basic-selector</a>)
  that improves a list's accessibility through the use of appropriate
  <a href="http://www.w3.org/WAI/intro/aria">ARIA</a> features on the list itself
  and the individual items in the list. The best part about an improvement like
  this in a fundamental building block like basic-selector or basic-list-box
  means that you can achieve better accessibility simply by using those
  components. Even if you know nothing about ARIA and accessibility
  technologies, using these components makes your app likely to be more
  accessible than one constructed from a undifferentiated pile of divs.
</p>
<p>
  <strong>Noteworthy:</strong>
  Support for keyboard navigation, including Up/Down, Page Up/Down, Home/End.
  Appropriate use of ARIA roles and other attributes means that users who are
  blind or visually impaired can more easily identify and navigate a list of
  items.
</p>
<p>
  <a href="https://github.com/basic-web-components/basic-list-box">View basic-list-box on GitHub</a>
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>ordered-columns — Pinterest-style packed column layout</title>
      <pubDate>Mon, 01 Dec 2014 16:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/ordered-columns-pinterest-style-packed-column-layout</link>
      <guid>http://component.kitchen/blog/posts/ordered-columns-pinterest-style-packed-column-layout</guid>
      <description><![CDATA[
      <p>
  ordered-columns implements a packed column layout in the style of Pinterest.
  Home pages with cards or modules that vary in height often use this layout to
  pack the cards into columns: cards are assigned in order to whichever column
  is currently the shortest. Such a layout is quick to compute, produces
  visually engaging results, maximizes content that appears above the fold. It's
  a useful responsive design pattern that scales well from small displays to
  very large ones. Many JavaScript libraries exist to implement this pattern,
  but this is a great example of a pattern that can be delivered as a web
  component.
</p>
<p>
  <strong>Likes:</strong> Author
  <a href="https://github.com/stevenrskelton">Steven Skelton</a>
  implements this column layout from the ground up as a Polymer web component.
  We see many, many web components that simply wrap an existing JavaScript
  library, and while that's a fine way to start, it can also lead to bloat. He
  also provides good documentation and numerous examples.
</p>
<p>
  <strong>Nits:</strong> The component only works with &lt;article&gt; elements
  (or elements with role="article"); it would be nicer if it could work with any
  type of child element. The component also moves all the children from the
  light DOM (the outer page) to the component's own shadow DOM. This effectively
  removes the children from the main page, complicating styling and the handling
  of events generated by the children.
</p>
<p>
  Apologies that we were unable to get our demo working in IE. We try hard to
  ensure all demos work in all mainstream browsers, but after spending too much
  time wrestling with IE, we decided we'd rather publish this review than keep
  debugging. Our issue likely had more to do with our own blog-with-demos
  environment than with the ordered-columns component itself.
</p>
<p>
  <a href="https://github.com/stevenrskelton/ordered-columns">View ordered-columns on GitHub</a>
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>akyral-modal – Modal overlay with beautiful demos and documentation</title>
      <pubDate>Thu, 06 Nov 2014 08:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/akyral-modal-modal-overlay-with-beautiful-demos-and-documentation</link>
      <guid>http://component.kitchen/blog/posts/akyral-modal-modal-overlay-with-beautiful-demos-and-documentation</guid>
      <description><![CDATA[
      <p>
  We love the elegant demos and documentation
  <a href="https://github.com/filaraujo">filaraujo</a>
  is creating for his collection of web components. His akyral-modal component,
  for example, addresses the common need to have a modal dialog or other UI
  appear in front of other elements on the page. Several other modal components
  exist, but none so nicely documented.
</p>
<p>
  <strong>Likes:</strong>
  The author's taken care to give akyral-modal a bare-bones appearance. We find
  often it easier to add our own visual style to a plain component than to try
  to override a complex visual styling baked into a component's default
  appearance. We're also a big fan of interactive demos that can be configured
  on the fly. A demo is worth 10,000 words.
</p>
<p>
  <a href="https://github.com/filaraujo/akyral-modal">View akyral-modal on GitHub</a>
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>x-rating — Simple star rating element that works</title>
      <pubDate>Mon, 03 Nov 2014 08:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/x-rating-simple-star-rating-element-that-works</link>
      <guid>http://component.kitchen/blog/posts/x-rating-simple-star-rating-element-that-works</guid>
      <description><![CDATA[
      <p>
  Sometimes the simplest approach works best. A number of registered web
  components aim to handle the simple task of showing or soliciting a star
  rating from a user using the now-convential set of 5 stars. On its own, a
  5-star rating system can present serious issues, as users tend to offer
  responses only at the extremes, but when managed well (adding users to add
  comments to explain their response, etc.), such rating systems can be useful.
</p>
<p>
  We tried three star rating components:
</p>
<ul>
  <li><a href="http://component.kitchen/components/dreyescat/rating-element">rating-element</a>.
    We set aside this one aside when we found that it relies on an image
    sprite; in this age of responsive design, using an image sprite feels a
    bit antiquated.
  </li>
  <li>
    <a href="http://component.kitchen/components/manoelneto/star-rating">polymer-star-rating</a>.
    This is the most full-featured of the three components we looked at: in
    particular, it's the only one that lets you can use different symbols for
    each rating, instead of always using a star. We had some difficulties
    getting the component to work in a demo of our own. (We filed a bug.)
    There were some other confusing points as well: the package name (polymer-
    star-rating) doesn't match the element name (star-rating), and the
    component made assumptions about the location of dependencies like
    polymer.html that didn't match up with how we'd set up things. Still, we
    have high hopes for this component.
  </li>
  <li>
    <a href="http://component.kitchen/components/hershmire/x-rating">x-rating</a>.
    This is the simplest component of the lot, but it worked immediately and
    did what we wanted. It uses Unicode code glyphs for the stars, which has
    the advantage of picking up the current text color. The glyph unfortunately
    isn't a parameter you can change, but that's nevertheless fine for the many
    cases in which you might want to just use a standard star.
  </li>
</ul>
<p>
  Obviously, with any head-to-head comparison like this, it's hard to say which
  component is really "best" for everyone. But for our quick experiment, we
  found x-rating did the job simply and well, so that's the component we're
  showing in the accompanying demo. Nice work,
  <a href="https://github.com/hershmire">hershmire</a>!
</p>
<p>
  <a href="https://github.com/hershmire/x-rating/">View x-rating on GitHub</a>
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>voice-elements — Easy access to the Web Speech API (on Chrome)</title>
      <pubDate>Thu, 30 Oct 2014 08:01:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/voice-elements-easy-access-to-the-web-speech-api-on-chrome</link>
      <guid>http://component.kitchen/blog/posts/voice-elements-easy-access-to-the-web-speech-api-on-chrome</guid>
      <description><![CDATA[
      <p>
  The voice-elements component gives you easy access to the Web Speech API
  natively supported (as of this writing) only in Chrome. This lets you both
  read text aloud to the user, and perform basic voice recognition. Users can
  quickly tire of repetitive spoken prompts, but voice playback might useful for
  short alerts that incorporate dynamic content such as data coming from your
  app.
</p>
<p>
  <strong>Likes:</strong>
  This supports multiple accents!
</p>
<p>
  <strong>Dislikes:</strong>
  None of the other browsers — Firefox, Safari, and IE — currently support the
  Web Speech API. We still think components like this are an important
  indication of the sort of power that components can put in anyone's hand.
</p>
<p>
  <a href="https://github.com/zenorocha/voice-elements/">View voice-elements on GitHub</a>
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>A new series of web component reviews with live demos</title>
      <pubDate>Thu, 30 Oct 2014 08:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/a-new-series-of-web-component-reviews-with-live-demos</link>
      <guid>http://component.kitchen/blog/posts/a-new-series-of-web-component-reviews-with-live-demos</guid>
      <description><![CDATA[
      <p>
  We've been eagerly tracking the state of the web components community since
  we started Component Kitchen earlier this year. Over that time, it's been
  exciting to watch the number of web components registered with
  <a href="http://bower.io">Bower</a> grow from about 40 to nearly 500 today.
</p>
<p>
  The growth in our component catalog, however, has meant that it's becoming
  harder and harder for someone like you to find interesting components just by
  browsing around. We want to help you find the interesting stuff. To do that,
  we're making three changes to our site:
</p>
<ol>
  <li>
    <p>
      We've begun dedicating a portion of our own time to sifting through the
      catalog of web components for components that are notable in some way. We
      want to highlight components that: solve a common user interface design
      problem in a way that can be readily adopted in your own apps, demonstrate
      how to write good web components, or show off what's possible with web
      components.
    </p>
    <p>
      When we find a notable component, we'll write a small capsule review for
      it. Along with the review, we’ll craft our own little demo of that
      component being used in some common way. This demo will let us confirm to
      ourselves that the component works as advertised, and will also give us a
      feel for the component’s strengths and weaknesses. We hope these little
      demos will make it easier for you to see on a small scale what a component
      might do for you.
    </p>
  </li>
  <li>
    <p>
      We've redesigned our home page to feature these component reviews and
      other news (like this post). The home page previously featured a complete
      list of all registered components; that list is now available in the
      <a href="http://component.kitchen/components">Component Catalog</a> section of our site.
    </p>
  </li>
  <li>
    <p>
      We've moved our temporary Component Kitchen blog feed in house. To get off
      the ground, we'd hosted our blog on a separate site, but you'll now find
      it here. If you'd like to keep track of what's happening in the world of
      web components, <a href="http://component.kitchen/feeds/blog.xml">subscribe to our blog feed</a>
      at this new location.
    </p>
  </li>
</ol>
<p>
  We'll be scouring the catalog of components for interesting work, but if
  you've seen something you think is worth highlighting, please give us a shout
  at
  <a href="http://twitter.com/ComponentK">@ComponentK</a>!
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>slide-page — Create basic browser-based presentations in HTML</title>
      <pubDate>Mon, 27 Oct 2014 08:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/slide-page-create-basic-browser-based-presentations-in-html</link>
      <guid>http://component.kitchen/blog/posts/slide-page-create-basic-browser-based-presentations-in-html</guid>
      <description><![CDATA[
      <p>
  There are already a number of web components that wrap existing slide-based
  presentation libraries; slide-page is notable for being written from the
  ground up with web components. The
  <a href="https://github.com/unbug/slide-page/blob/master/slide-page.html">source code</a>
  for the core component is little more than a wiring together of existing parts
  in a novel combination. That approach is, in fact, <em>exactly right</em>, and
  component writing at its best! This component mostly adds sequential arrow
  button navigation around Polymer's core-animated-pages component. For the
  buttons, it takes advantage of Google's Material Design theme, specifically
  the Paper floating action button.
</p>
<p>
  <strong>Likes:</strong>
  Great use of existing Polymer and Paper components; some keyboard navigation.
</p>
<p>
  <strong>Dislikes:</strong>
  The stock appearance shows a "Powered by Polymer" banner that few people are
  going to want. It's possible to turn it off through styling, but we like
  components whose default appearance is the most practical starting point.
</p>
<p>
  <a href="https://github.com/unbug/slide-page">View slide-page on GitHub</a>
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>google-map — A simple wrapper for maps and driving directions</title>
      <pubDate>Mon, 20 Oct 2014 08:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/google-map-a-simple-wrapper-for-maps-and-driving-directions</link>
      <guid>http://component.kitchen/blog/posts/google-map-a-simple-wrapper-for-maps-and-driving-directions</guid>
      <description><![CDATA[
      <p>
  Many companies embed a hard-coded Google Map on their site to show, for
  example, the location of their office. This component allows you to easily
  create more dynamic maps. You could, for example, combine this with
  <a href="http://component.kitchen/components/ebidel/geo-location">geo-location</a> to show
  your user's current location.
</p>
<p>
  <strong>Likes:</strong>
  You can combine the basic <code>google-map</code> component with the companion
  <code>google-map-directions</code> to provide driving directions from the user
  to your store, office, etc. This points toward a momentous promise: a domain-
  specific markup language for creating interactive maps.
</p>
<p>
  <strong>Dislikes:</strong>
  In its current state, this component mostly wraps the Google Maps API, which
  is powerful but rather complex if you're not already familiar with it. In
  many cases (e.g., a driving route with more than one stop), you'll be forced
  to use the more complex underlying API. Given Google's preemince in mapping,
  we'd love to see them push much further with this library of components.
</p>
<p>
  <a href="https://github.com/GoogleWebComponents/google-map/">View google-map on GitHub</a>
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>General-purpose web components</title>
      <pubDate>Mon, 16 Jun 2014 08:15:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/general-purpose-web-components</link>
      <guid>http://component.kitchen/blog/posts/general-purpose-web-components</guid>
      <description><![CDATA[
      <p>
Component Kitchen founder Jan Miksovsky shares some of his <a href="http://miksovsky.blogs.com/flowstate/2014/06/deconstructing-the-standard-photo-carousel-into-general-purpose-web-components.html%20">recent experience creating some general-purpose components</a> over on his user interface design/development blog at flow|state.
</p>
<p>
Creating really good general-purpose components entails more work than creating components for a single organization or product. You can find a good list of <a href="https://github.com/basic-web-components/components-dev/wiki/Ten-Principles-for-Great-General-Purpose-Web-Components">principles for great general-purpose components</a> on the site for the open source <a href="https://github.com/basic-web-components/components-dev/wiki">basic-web-components</a> project, which is sponsored by Component Kitchen.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Live demos let people see what a component is all about</title>
      <pubDate>Mon, 26 May 2014 08:00:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/live-demos-let-people-see-what-a-component-is-all-about</link>
      <guid>http://component.kitchen/blog/posts/live-demos-let-people-see-what-a-component-is-all-about</guid>
      <description><![CDATA[
      <p>
We recently added live demos to the Component Kitchen site for all components that define a demo. Components with demos are marked on the <a href="http://component.kitchen">home page</a> with a "DEMO" indicator, so you can check out all the demos.
</p>
<p>
We always want to make it as easy as possible to find interesting components, and demos are obviously the quickest way for someone to really understand what a component can do for them. From the beginning of our work on the service, we've wanted to host demos <em>in situ</em> on the pages we build for components. We want to let a user looking for a component to see the demos front and center (without having to link off to another site just to see a demo) so they can quickly find what they're looking for.
</p>
<p>
As described in our evolving <a href="http://component.kitchen/docs/developers">developer documentation</a>, for the time being, you'll need to host the demo at a site you maintain (e.g., a GitHub Pages site for your component repository). You can then include a @demo line in the comments at the top of your component's main source file to indicate where the component is. We've also seen some conventions emerge whereby a component can imply the location of a demo, and we try to detect when one of those conventions is in use as well, but use of the @demo indicator is the clearest way to point to a demo.
</p>
<p>
We host demos within an iframe, but traditional iframes make it hard to seamlessly incorporate content from another site, and in particular, the page hosting the iframe can't know how <em>tall</em> the framed page is. While it's fine for us to define a default height for a framed demo, we really want demo authors to be able to control how tall the demo is. Some components, for example, are really small, and so it'd be nicer to have the iframe showing the demo be exactly the height it needs to be.
</p>
<p>
The standard way to securely communicate across a frame boundary is a facility called window.postMessage(). That approach is somewhat cumbersome to use, however. What we really wanted was a way to package that communication up. A web component was, of course, a great way to do that! We've published our solution through our companion of open source project, <a href="https://github.com/basic-web-components">basic-web-components</a>. There you'll find two components that work together, <a href="http://component.kitchen/components/basic-web-components/basic-seamless-iframe">basic-seamless-iframe</a>, which goes on the <em>framing</em> page, and <a href="http://component.kitchen/components/basic-web-components/basic-framed-content">basic-framed-content</a>, which goes on the <em>framed</em> page. These components cooperatively communicate across the frame boundary so that, among other things, the outer page can correctly adjust the height of the frame.
</p>
<p>
So, if you'd like to have your demo auto-size when shown on our site, just add the basic-framed-content component to your project, and wrap the contents of your demo in an instance of &lt;basic-framed-content&gt;. The latter won't interfere with anything when someone views the demo on your site, but when someone views your component on Component Kitchen, the demo will communicate its height to the framing page so that the demo looks just right.
</p>

      ]]>
      </description>
    </item>
  

    <item>
      <title>Component Kitchen preview launched</title>
      <pubDate>Wed, 30 Apr 2014 22:08:00 GMT</pubDate>
      <link>http://component.kitchen/blog/posts/component-kitchen-preview-launched</link>
      <guid>http://component.kitchen/blog/posts/component-kitchen-preview-launched</guid>
      <description><![CDATA[
      <p>Today we’re excited to publicly announce the launch of a preview edition of our site at <a href="http://component.kitchen"><span class="s1">https://component.kitchen</span></a>.</p>
<p>At Component Kitchen, we think web components are fundamentally a great way to create apps and sites that run across an enormous range of desktop and mobile devices. We’re eager to help a mainstream audience learn about this technology, and discover for themselves how this technology is going to amplify their own creative capabilities as designers, developers, writers, students, business people, and more.</p>
<p>Earlier this year, we observed that most of the material and tools related to web components was intended for a fairly experienced technical audience. We feel that, since web components extend what’s possible with plain HTML and CSS, web components is actually fundamentally interesting to a much broader audience: anyone who is comfortable editing HTML. That’s a lot of people!</p>
<p>Additionally, we believe that people creating web components are going to need a range of services to help promote and distribute their components to a broad audience that includes both hardcore developers and people who work at the HTML level.</p>
<p>We’re starting with a few basics:</p>

<ul>
    <li>A <a href="http://component.kitchen/components">catalog of components</a> which have publicly registered for use. The preview release is quite basic, but includes some interesting features such as image previews for many components, and an ability to search the catalog.</li>
    <li>A <a href="http://component.kitchen/feeds/newComponents.xml">New Web Components RSS feed</a>. Subscribe to learn about new components as soon as they’re registered.</li>
    <li>A <a href="http://discuss.component.kitchen/">discussion board for talking about web components</a>. There are some other public forums for web components, but they focus on a highly technical audience. Lots of people will want to use components who have never heard of developer hangouts like GitHub or StackOverflow.</li>
</ul>
<p>We have a number of interesting features ahead:</p>

<ul>
    <li>Live, interactive, configurable component demos. You can see an example on the page for the <a href="http://component.kitchen/components/basic-web-components/basic-autosize-textarea">basic-autosize-textarea</a> component. This lets you play with the component and see how its customization options will affect its appearance and behavior.</li>
    <li>Web component hosting. Many people create HTML in environments like blogging platforms or mainstream web hosting platforms that don’t allow complete control over the site. If that’s you, we want to allow you to still take advantage of web components by hosting the components on Component Kitchen. Again, visit the <a href="http://component.kitchen/components/basic-web-components/basic-autosize-textarea">basic-autosize-textarea</a> component for an example of component hosting. Click the Copy to Clipboard button, then paste the result in any HTML editor or environment. This will paste in the &lt;script&gt; and &lt;link&gt; tags that let you use that component from its hosted location on Component Kitchen.</li>
</ul>
<p>Our core mission is to help people create great products using web components. While we have many ideas for how we can do that, we’re most interested in hearing from you. If you have questions or suggestions for our site, let us know at <a href="https://twitter.com/ComponentK">@ComponentK</a> on Twitter, or on our discussion board.</p>
<p>This is going to be <i>such</i> an exciting time to work on the web!</p>
      ]]>
      </description>
    </item>
  
      </channel>
    </rss>