npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

shadow-dom-style-sharing

v2.1.0

Published

polyfill ::part and ::theme

Downloads

7

Readme

what is this

polyfills ::theme and ::part to support sharing css styling between custom elements

see https://meowni.ca/posts/part-theme-explainer/ for more information on these selectors

setup

install package

npm i -s shadow-dom-style-sharing

import

using as a node modules

const {process} = require('shadow-dom-style-sharing')

using as a es6 modules

import {process} from 'build-path-to-shared-styling/es6/index.js';

using <es6 with no build tool

<script>window.module = {};</script>
<script src="build-path-to-shared-styling/src/index.js"></script>

usage process(root, changed)

invoke process each time you'd like to update the styling. this will typically need to be done once the DOM loads:

document.addEventListener('DOMContentLoaded', () => {
   process(document); 
});

and again when new elements are added to the DOM:

let myElement = document.createElement('my-element');
document.appendChild(myElement);
process(document, myElement);

the first argument to process should be the root element style rules are relative to. This is typically always the document.

the second argument to process is optional and scopes the style rules to only be added to that element. This is useful to avoid css rule duplication when invoking process multiple times; e.g. when dynamically adding elements to the DOM after it has loaded.

limitations

syntax

at the moment, to avoid having to re-parse the css styling, we reuse the browser's parsed document.styleSheets. Unfortunately, browsers prune invalid css when generating document.styleSheets. This means we're unable to use custom pseudo-selectors such as ::theme and ::part, and instead use the .theme and .part syntax. Furthermore, as class selectors, e.g. .part, can't have parenthetical parameters, we must use .pend to indicate the end of .part, otherwise it will be assumed to end at the next .theme, .part, or ;.

example

.theme

<!-- styling -->

<style>
	.theme .line-orange {
		color: orange;
		border: 1px solid orange;
	}
</style>

<!-- html -->

<p class="line-orange">inline black</p>

<my-element></my-element>

<template id="my-template">
	<p class="line-orange">element orange</p>
	<my-element-nested part="nested-element"></my-element-nested>
	<div part="nested-div">
		<p class="line-orange">nested div orange</p>
	</div>
</template>

<template id="my-element-nested">
	<p class="line-orange">nested element orange</p>
</template>

<!-- set up custom elements -->

<script>
	customElements.define('my-element', class extends HTMLElement {
		constructor() {
			super();
			this.attachShadow({mode: 'open'});
			const template = document.getElementById('my-template').content.cloneNode(true);
			this.shadowRoot.appendChild(template);
		}
	});

	customElements.define('my-element-nested', class extends HTMLElement {
		constructor() {
			super();
			this.attachShadow({mode: 'open'});
			const template = document.getElementById('my-element-nested').content.cloneNode(true);
			this.shadowRoot.appendChild(template);
		}
	});
</script>

<!-- apply shared css styling -->

<script type="module">
	import {process} from '../es6/index.js';
	document.addEventListener('DOMContentLoaded', () => process(document));
</script>

.part

<!-- styling -->

<style>
	my-element .part line-orange,
	my-element .part nested-element .partend .part nested-line-orange,
	my-element .part nested-div .partend .line-orange {
		color: orange;
		border: 1px solid orange;
	}
</style>

<!-- html -->

<p class="line-orange">inline black</p>

<my-element></my-element>

<template id="my-template">
	<p part="line-orange">element black</p>
	<my-element-nested part="nested-element"></my-element-nested>
	<div part="nested-div">
		<p class="line-orange">nested div orange</p>
	</div>
</template>

<template id="my-element-nested">
	<p part="nested-line-orange">nested element part orange</p>
</template>

<!-- set up custom elements -->

<script>
	customElements.define('my-element', class extends HTMLElement {
		constructor() {
			super();
			this.attachShadow({mode: 'open'});
			const template = document.getElementById('my-template').content.cloneNode(true);
			this.shadowRoot.appendChild(template);
		}
	});

	customElements.define('my-element-nested', class extends HTMLElement {
		constructor() {
			super();
			this.attachShadow({mode: 'open'});
			const template = document.getElementById('my-element-nested').content.cloneNode(true);
			this.shadowRoot.appendChild(template);
		}
	});
</script>

<!-- apply shared css styling -->

<script type="module">
	import {process} from '../es6/index.js';
	document.addEventListener('DOMContentLoaded', () => process(document));
</script>

styling dynamically modified dom

<!-- styling -->

<style>
	.theme .line-orange {
		color: orange;
		border: 1px solid orange;
	}
</style>

<!-- html -->

<p class="line-orange">inline black</p>

<my-element></my-element>

<template id="my-template">
	<p class="line-orange">element orange</p>
	<div id="nested-element-placeholder"></div>
	<div part="nested-div">
		<p class="line-orange">nested div orange</p>
	</div>
</template>

<template id="my-element-nested">
	<p class="line-orange">nested element orange</p>
</template>

<!-- set up custom elements -->

<script>
	customElements.define('my-element', class extends HTMLElement {
		constructor() {
			super();
			this.attachShadow({mode: 'open'});
			const template = document.getElementById('my-template').content.cloneNode(true);
			this.shadowRoot.appendChild(template);
		}
	});

	customElements.define('my-element-nested', class extends HTMLElement {
		constructor() {
			super();
			this.attachShadow({mode: 'open'});
			const template = document.getElementById('my-element-nested').content.cloneNode(true);
			this.shadowRoot.appendChild(template);
		}
	});
</script>

<!-- apply shared css styling -->

<script type="module">
	import {process} from '../es6/index.js';

	document.addEventListener('DOMContentLoaded', () => process(document));

	setTimeout(() => {
		let nestedElement = document.createElement('my-element-nested');
		document.querySelector('my-element').shadowRoot.querySelector('#nested-element-placeholder').appendChild(nestedElement);
		process(document, nestedElement);
	}, 500);

	setTimeout(() => {
		let nestedElement = document.createElement('my-element-nested');
		document.querySelector('my-element').shadowRoot.querySelector('#nested-element-placeholder').appendChild(nestedElement);
		process(document, nestedElement);
	}, 1000);
</script>

this markdown was generated by de-document-examples