Security News
NVD Backlog Tops 20,000 CVEs Awaiting Analysis as NIST Prepares System Updates
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Skate is a library built on top of the W3C web component specs that enables you to write functional and performant web components with a very small footprint.
Skate is a functional abstraction over the web component standards that:
props
, such as
attribute reflection and coercionAt its core, Skate is about creating Custom Elements. Skate provides a series of mixin functions that enable you to control what your component can do.
For instance, Skate's main mixin, withComponent
, is just a composition of all
of Skate's other mixin behaviours:
withUpdate
-- the generated element will react to changes on their props or
HTML attributes.withChildren
-- the generated element will react to changes to its child
elements.withRenderer
-- the element can generate its own DOM and output it to a
renderRoot
(a ShadowRoot
node by default).withLifecycle
-- the element can use added sugar on top of the built-in
lifecycle callbacks.withContext
-- the element will inherit context from components up the tree,
like in React.withUnique
-- allows for naming the custom element through is
.Calling withComponent()
gives you a Custom Element class constructor, which
you can then extend to define your own elements.
Every mixin accepts an optional Element
constructor as its only parameter,
which allows you to extend virtually any element type in HTML!
As an example, let's create a simple greeting component...
<x-hello>Bob</x-hello>
...such that when this element is rendered, the end-user will see Hello, Bob!
.
We can define a Skate component that renders the contents of our Custom Element:
import { withComponent } from 'skatejs';
const Component = withComponent();
class GreetingComponent extends Component {
renderer (renderRoot, render) {
renderRoot.innerHtml = '';
renderRoot.appendChild(render());
}
render () {
const el = document.createElement('span');
el.innerHTML = 'Hello, <slot></slot>!';
return el;
}
}
customElements.define('x-hello', GreetingComponent);
When this element is rendered, the DOM will look something like the following:
<x-hello>
#shadow-root
<span>Hello, <slot></slot>!</span>
Bob
</x-hello>
This is the utility that web components provide when using Custom Elements and the Shadow DOM.
Skate also allows turning off Shadow DOM if you don't wanna use it for
various particular reasons. You can turn it off via get renderRoot()
override:
NOTE: by turning off Shadow DOM you cannot use content projection anymore by default, further tweaks needs to be applied
import { withComponent, props } from 'skatejs';
// define base class withouth Shadow DOM
class NoShadowComponent = class extends withComponent() {
// you need to return where you want to render your content, in our case we wanna render directly to our custom element children
get renderRoot() {
return this
}
}
// use custom NoShadowComponent as a base class
class GreetingComponent extends NoShadowComponent {
static props = {
name: props.string
};
renderer (renderRoot, render) {
renderRoot.innerHtml = '';
renderRoot.appendChild(render());
}
render ({name}) {
const el = document.createElement('span');
el.innerHTML = `Hello, ${name}!`;
return el;
}
}
customElements.define('x-hello', GreetingComponent);
Now when you write:
<x-hello name="Bob"></x-hello>
When this element is rendered, the DOM will look something like the following:
<x-hello>
<span>Hello, Bob!</span>
</x-hello>
We can create a Skate component that watches for HTML attribute changes on itself:
import { props, withComponent } from 'skatejs';
const Component = withComponent();
class GreetingComponent extends Component {
static props = {
name: props.string
};
renderer (renderRoot, render) {
renderRoot.innerHtml = '';
renderRoot.appendChild(render());
}
render ({ name }) {
const el = document.createElement('span');
el.innerHTML = `Hello, ${name}!`;
return el;
}
}
customElements.define('x-hello', GreetingComponent);
The resulting HTML when the element is rendered would look like this:
<x-hello name="Bob">
#shadow-root
<span>Hello, Bob!</span>
</x-hello>
Now, whenever the name
property or attribute on the greeting component
changes, the component will re-render.
In the previous exampless, each component implements its own rendering behaviour. Rather than re-defining it all the time, we can write a mixin and take advantage of prototypal inheritance:
NOTE: the
with
prefix is not mandatory, just a common practice for naming HOCs and Mixins
import { props, withComponent } from 'skatejs';
const withDangerouslyNaiveRenderer = (Base = HTMLElement) => {
return class extends Base {
renderer (renderRoot, render) {
renderRoot.innerHtml = render();
}
}
};
const Component = withComponent(withDangerouslyNaiveRenderer());
class GreetingComponent extends Component {
static props = {
name: props.string
};
render ({ name }) {
return `<span>Hello, {name}!</span>`;
}
}
customElements.define('x-hello', GreetingComponent);
Because Skate provides a hook for the renderer, it can support just about every
modern component-based front-end library — React, Preact, Vue... just
provide a render
to stamp out your component's HTML, a renderer
to update
the DOM with your HTML, and then it's all the same to Skate!
The Skate team have provided a few renderers for popular front-end libraries; check the Installing section.
Instead of writing our own renderer
, we could use a library like
Preact to do the work for us. Skate provides a
ready-made renderer for Preact; here's how we would update our previous greeting
component to use it:
/** @jsx h */
import { props, withComponent } from 'skatejs';
import withRenderer from '@skatejs/renderer-preact';
import { h } from 'preact';
const Component = withComponent(withRenderer());
customElements.define(
'x-hello',
class extends Component {
static props = {
name: props.string
};
render({ name }) {
return <span>Hello, {name}!</span>;
}
}
);
Now that the greeting component is rendered via Preact, when it renders, it only changes the part of the DOM that requires updating.
To use Skate on its own, just add it to your package.json
:
npm install skatejs
To use Skate with another front-end library, you'll want to install that library itself, along with a Skate renderer for it.
npm install skatejs @skatejs/renderer-[renderer] [renderer]
Where [renderer]
is one of:
Skate builds upon the Custom Elements and the Shadow DOM standards. Skate is capable of operating without the Shadow DOM — it just means you don't get any encapsulation of your component's HTML or styles.
Though most modern browsers support these standards, some still need polyfills to implement missing or inconsistent behaviours for them.
For more information on the polyfills, see the web components polyfill documentation.
Skate supports all evergreens and IE11, and is subject to the browser support matrix of the polyfills.
Support us with a monthly donation and help us continue our activities. [Become a backer]
Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]
FAQs
Skate is a library built on top of the W3C web component specs that enables you to write functional and performant web components with a very small footprint.
The npm package skatejs receives a total of 2,274 weekly downloads. As such, skatejs popularity was classified as popular.
We found that skatejs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 8 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.