CSS in JSでStyled ComponentsをAngularやReactといったフレームワークなしで作る最小デザインを例示する。
次のようなHTMLで表されるDOM ComponentにCSSを適用したいとする。
<article id="id"> <h1>Title</h1> <ul> <li>item</li> <li>item</li> </ul> </article>
単純にidで絞り込んだCSSを記述したstyle要素があればCSSを不足なく利用できる。
<article id="id"> <style>#id ul { width: 100px; }</style> <h1>Title</h1> <ul> <li>item</li> <li>item</li> </ul> </article>
このHTML(DOM Component)を生成する方法は次のように考えられる。
import TypedHTML from 'typed-dom'; const component = TypedHTML.article({ id: 'id' }, { style: TypedHTML.style(`#id ul { width: 100px; }`), title: TypedHTML.h1(`title`), content: TypedHTML.ul([ TypedHTML.li(`item`), TypedHTML.li(`item`), ]) });
idを自動で埋め込めるようにするとミスを防ぐことができ、モジュラリティも得られる。
import TypedHTML from 'typed-dom'; const component = TypedHTML.article({ id: 'id' }, { style: TypedHTML.style(`$scope ul { width: 100px; }`), title: TypedHTML.h1(`title`), content: TypedHTML.ul([ TypedHTML.li(`item`), TypedHTML.li(`item`), ]) });
固定idの直接指定は次のように
class Component { constructor(private readonly parent: HTMLElement) { this.parent.appendChild(this.element); } private readonly element = TypedHTML.div({ id: 'id' }, [ TypedHTML.style(`$scope { position: relative; }`) ]).element; private readonly children = Object.freeze({ list: new MicroComponent(this.element) }); destroy() { this.element.remove(); } }
一時idの生成は次のように行える。
class MicroComponent { constructor(private readonly parent: HTMLElement) { this.parent.appendChild(this.dom.element); } private readonly dom = TypedHTML.div({ id: `${this.parent.id}-list-${Date.now()}-${Math.random() * 1e9 | 0}` }, { style: TypedHTML.style(`$scope ul { width: 100px; }`), content: TypedHTML.ul([ TypedHTML.li(`item`) ]) }); }
以上のようにCSS in JSでStyled Componentsを作るには単にscopeを作る要素を指定するセレクタの埋め込みとCSSを定義するstyle要素の同梱の2機能さえあれば最小構成として十分であり、面倒なフレームワークに抱き合わせられずに簡単に導入できる。
なおこのライブラリは以下のようにDOM構造の静的型を生成し内部構造を可視化、開発支援するものであり、付属機能としてCSS in JSをサポートしている。
TypedHTMLElement<"article", HTMLElement, { style: TypedHTMLElement<"style", HTMLStyleElement, string>; title: TypedHTMLElement<"h1", HTMLHeadingElement, string>; content: TypedHTMLElement<"ul", HTMLUListElement, TypedHTMLElement<"li", HTMLLIElement, string>[]>; }>;