Skip to content

Instantly share code, notes, and snippets.

View calebdwilliams's full-sized avatar

Caleb Williams calebdwilliams

View GitHub Profile
/** See https://astexplorer.net/#/gist/029b3c40b76e04ceb3dada59d4a4cbab/9e5ee857c583ed6fb1ed05d2bbd934a41eb4156e */
import * as postcss from "postcss";
const rootToRefSelectorMap = new WeakMap();
const exportsString = '._export💲';
function toSassMixin(rule) {
const mixin = rule.clone();
mixin.selector = `@mixin ${rule.selector.replace('$', '')}`;
return mixin;
@calebdwilliams
calebdwilliams / SILENT-CLASSES-PROPOSAL.md
Last active May 29, 2021 16:35
Silent classes proposal WIP

Introduce silent classes

This is an RFC on a proposal to introduce silent classes to CSS. This concept borrows heavily from the abandoned @apply specification while hopefully learning from the places that particular API failed.

The problem

Styles cannot be reused across instances of DocumentOrShadowRoot. While the shadow DOM’s encapsulation is incredibly powerful and enables developers to have full control over portions of the DOM, there are often rules that design system authors might want to reuse across contexts.

While some recent proposals will allow for style sharing across shadow roots (like constructible stylesheets and CSS module scripts), often times the target node type is different (between something like a div and :host`).

@calebdwilliams
calebdwilliams / syncAttributesAndProperties.js
Created May 14, 2021 19:27
Synt attributes and properties for custom elements
export function syncAttributesAndProperties(self) {
self.constructor.observedAttributes.forEach(attribute => {
const descriptor = Object.getOwnPropertyDescriptor(self.constructor.prototype, attribute);
Object.defineProperty(self, attribute, {
get() {
if (descriptor?.get) {
return descriptor.get.apply(self, []);;
}
return self.getAttribute(attribute);
@calebdwilliams
calebdwilliams / mixin-annotated.js
Created July 15, 2020 14:17
Mixin annotation with JSDoc and TypeScript
import { LitElement } from 'https://cdn.pika.dev/lit-element@^2.3.1';
/** @typedef {new (...args: any[]) => any} Constructor */
/**
* @template {!Constructor} T
* @param {T} superclass - The class to extend
*/
const FormControlMixin = (superclass) =>
class FormControl extends superclass {
@calebdwilliams
calebdwilliams / rollup-plugin-lit-scss.js
Created June 25, 2020 15:44
Rollup Plugin LitElement SCSS
import sass from 'node-sass';
import { resolve, extname } from 'path';
import { processString } from 'uglifycss';
import stringToTemplateLiteral from 'string-to-template-literal';
import nodeSassImporter from 'node-sass-package-importer';
const importer = nodeSassImporter();
function transform(css) {
return `import { css } from 'lit-element';
/**
* This code was adapted from the excellent Braid Design System
* by SEEK OSS, you can find their original code code here
* https://github.com/seek-oss/braid-design-system/blob/master/lib/hooks/typography/basekick.ts
*
* They're doing some really amazing stuff and I got to copy them here,
* you should definitely check them out.
*/
export const updatePath = (obj, path, value) => {
const paths = path.split('.');
const location = paths.pop();
let pointer = obj;
for (let point in paths) {
const path = paths[point];
if (path in pointer) {
pointer = pointer[path];
} else {
function fetchResource(url, interval = 500, i = 1) {
let attempts = 0;
return new Promise((resolve, reject) => {
const repeat = setInterval(() => {
fetch(url)
.then(response => {
if (response.ok) {
resolve(response);
clearInterval(repeat);
const traceProperty = (object, property) => {
let value = object[property];
Object.defineProperty(object, property, {
get () {
console.trace(`${property} requested`);
return value;
},
set (newValue) {
console.trace(`setting ${property} to `, newValue);
value = newValue;