Skip to content

Instantly share code, notes, and snippets.


Trey Shugart treshugart

View GitHub Profile

Defining a scoping inner-boundary in CSS

Concretely, I want to implement simulated CSS scoping for react-shade. This uses the imperative Shadow DOM APIs, by default, to enable scoping on the client. However, in order to get fully-scoped CSS when using SSR, we need either:

  • A declarative API for shadow DOM (closed due to lack of implementer interest), or
  • A way to tell CSS to stop selecting elements in slots. So, we'd need to be able to select between an ancestor and a descendant in a given DOM tree.
  • ...?

I am currently able to find solutions for :host and :host-context, and can scope stuff to descendants of a shadow root tree, the hard part is just simulating the exclusion of slotted content.

treshugart / gist:7220c2ee1a3952bbb995c52fab663cdd
Last active Dec 12, 2018
I want to get type checking working for custom elements in JSX. The following examples should work.
View gist:7220c2ee1a3952bbb995c52fab663cdd
type HTMLElementPrototype = HTMLElement extends { prototype: infer Prototype }
? Prototype
: never;
declare namespace h {
namespace JSX {
interface Element {}
type LibraryManagedAttributes<E, _> = E extends {
prototype: infer Prototype;
treshugart /
Last active Apr 20, 2020
HMR for generic web components

Generic web component HMR

I'm messing around with a generic way to do hot-module-replacement with generic web components whether they be vanilla, or done in a framework like Polymer or Skate.

The idea is that you call hmr(customElementConstructor) in your module files and it will set up the proper hooks.

The const filename should be inserted at build time so that it can remember the original localName of the component for the module.

WTF is "x-layout", "Layout" and "filename"

treshugart /
Last active Jul 25, 2018
Shadow DOM issues
View good-promise.js
function wrap(func) {
return function(value) {
try {
return func(value);
} catch (e) {
throw new Error(e);
View skate-mobx.js
import { autorun, toJS } from 'mobx';
import { props } from 'skatejs';
export const withObserver = (Base = HTMLElement) =>
class extends Base {
constructor() {
const { stores } = this;
// This dynamically adds props post construction, so this happens for every instance that is created. One way to
treshugart /
Last active Nov 1, 2017
Skate mixin to rehydrate props and state on the client.


This is a Skate mixin for serialising and rehydrating props and state for a component. Essentially it will apply JSON encoded attributes for props and state after rendering on the server. When rendered on the client, it then takes those attributes and decodes them as props, essentially rehydrating the component state.


  • The didMount callback is specific to Skate and is called after the component is connected.
  • The didRender callback is specific to Skate and is called after the component renders.
View streamed-web-components.js
const express = require('express');
const app = express();
const delay = (...args) =>
(prev, curr) =>
prev.then(() => new Promise(yey => setTimeout(() => yey(curr()), 2000))),

Declarative / composed Shadow DOM

This is a light proposal for Shadow DOM (no pun intended). The purpose of this proposal is to flesh out how we can take the current state of Shadow DOM and allow certain aspects of it to be used separately and composed together. The goals are:

  1. Being able to use CSS encapsulation separately from DOM encapsulation (SSR is one beneficiary of this)
  2. Being able to enable DOM encapsulation on a previously CSS-only encapsulated node (rehydration)
  3. Maintaining backward compatibility

CSS-only encapsulation

View example.html
<x-vue yell>World</x-vue>
You can’t perform that action at this time.