Pretty Cool Elements

Overview

Pretty Cool Elements

Social Media Photo by Jamison McAndie on Unsplash

This module is a follow up of this Medium post, and it provides element mixins/behaviors, through class names, without names clashing.

Features

  • it addresses every single point touched in the Medium's post:
    • no name clashing
    • multiple mixins/behaviors attached/detached at any time
    • native Custom Elements builtin callbacks, associated to mixins/behaviors
  • it's Server Side Rendering compatible out of the box
  • it uses all the DOM primitives without needing an extra attribute (bloat-free layouts)
  • it's semantically bound with element's view (their classes and their dedicated style)
  • it's graceful enchancement out of the box, based on builtin extends
  • it provides a robust polyfilled version through vanilla-elements

Example

import {define} from 'p-cool';

define('my-div', {

  // to know when a behavior is attached or detached via class
  attachedCallback(element) {},
  detachedCallback(element) {}, // see ## About Callbacks

  // to observe connected/disconnected lifecycle
  connectedCallback(element) {},
  disconnectedCallback(element) {},

  // to observe specific attributes (omit to observe them all)
  observedAttributes: ['some-attribute'],

  // to know when observed attributes changed
  attributeChangedCallback(element, name, oldValue, newValue) {},
});
<div is="p-cool-div" class="my-div" some-attribute="ok">
  Hello Behaviors 👋
</div>

About PCool

With native Custom Elements, we need to reserve a single name in a shared global registry to pass through the upgrade, and callbacks, mechanism.

With p-cool elements, the registry is pre-populated with vanilla-elements extends through a p-cool-* prefix, so that <div is="p-cool-div">, and <p is="p-cool-p">, or <main is="p-cool-main"> are all valid, already registered, builtin extends, that brings mixins/behaviors to any element, and through their class name, as long as one, or mixin, is defined/attached, through the define(name, mixin) module's export.

<!doctype html>
<script type="module">
import {define} from '//unpkg.com/p-cool';

import Hero from './mixins/hero.js';
define('hero', Hero);

import Bottom from './mixins/bottom.js';
import AutoHide from './mixins/auto-hide.js';
define('bottom', Bottom);
define('auto-hide', AutoHide);
</script>
<style>
main { /* ... */ }
.hero { /* ... */ }
.bottom { /* ... */ }
</style>
<body is="p-cool-body" class="hero">
  <main>Hero</main>
  <footer is="p-cool-footer" class="bottom auto-hide">
    ...
  </footer>
</body>

To implement an element extend, the <p-cool> Custom Element is registered too, so that a page could be defined by non-builtin extends, with mixins/behaviors attached when, and if, needed.

<!doctype html>
<script type="module">
import {define} from '//unpkg.com/p-cool';

import Hero from './mixins/hero.js';
define('hero', Hero);

import Bottom from './mixins/bottom.js';
import AutoHide from './mixins/auto-hide.js';
define('bottom', Bottom);
define('auto-hide', AutoHide);
</script>
<body>
  <p-cool class="hero"></p-cool>
  <p-cool class="bottom auto-hide">
    ...
  </p-cool>
</body>

About Callbacks

attachedCallback

This callback is granted to be invoked only once, and before any other callback, whenever a mixin/behavior is attached through the element's class, somehow simulating what a constructor would do with Custom Elements.

This callback is ideal to add related event listeners, setup an element for the specific mixin/behavior, and so on.

Please note that if a mixin/behavior is detached, and then re-attached, this callback will be invoked again.

attributeChangedCallback

If any observedAttributes is specified, or if there is an attributeChangedCallback, this is invoked every time observed attributes change.

Like it is for Custom Elements, this callback is invoked, after a mixin/behavior is attached, hence after attachedCallback, but before connectedCallback.

This callback is also invoked during the element lifecycle, whenever observed attributes change, providing the oldValue and the newValue.

Both values are null if there was not attribute, or if the attribute got removed, replicating the native Custom Element behavior.

connectedCallback

This callback is granted to be invoked after an element gets a new mixin/behavior, if the element is already live, and every other time the element gets moved or re-appended on the DOM, exactly like it is for native Custom Elements.

Please note that when a mixin/behavior is attached, and there are observed attributes, this callback will be invoked after attributeChangedCallback.

disconnectedCallback

This callback is granted to be invoked when an element gets removed from the DOM, and it would never trigger if the connectedCallback didn't happen already.

Both callbacks are the ideal place to attach, on connected, and remove, on disconnected, timers, animations, or idle related callbacks, as even when elements get trashed, both callbacks are granted to be executed, and in the right order of events.

detachedCallback

This callback is not granted to be invoked if an element get trashed, but it's granted to be invoked after disconnectedCallback, if a mixin/behavior is removed from an element.

Please note that this callback is not really useful for elements that might be, or may not be, trashed, because there is no way to use a FinalizationRegistry and pass along the element, but it's very hando for those elements that never leave the DOM, but might change, over time, their classes, hence their mixins/behaviors.

import {define} from 'p-cool';

define('mixin', {
  attachedCallback(element) {
    console.log('mixin attached');
  },
  detachedCallback(element) {
    console.log('mixin detached');
  }
});

// example
document.body.innerHTML = `
  <div id="first" class="mixin">First</div>
  <div id="second" class="mixin">Second</div>
`;
// logs "mixin attached" twice

// will **not** "mixin detached"
first.remove();

// it **will** log "mixin detached"
second.classList.remove('mixin');

About Exports

This module offers the following exports:

  • p-cool with a define(name, mixin) export that does not polyfill Safari
  • p-cool/min with a minified define(name, mixin) export that does not polyfill Safari
  • p-cool/poly with a minified define(name, mixin) export that also does polyfill Safari
  • p-cool/behaviors with the internally used define and behaviors exports, plus constants, useful to potentially create other libraries or utilities on top of the same logic

The https://unpkg.com/p-cool points at the minified /poly variant, useful to quickly test, or develop, with this module.

Compatibility

Every ES2015+ compatible browser out of the box, including Safari/WebKit based browsers in the poly version.

You might also like...

Team Alpha Super Awesome Cool Dynamite Wolf Squadron - 10 - Project 1

Team Alpha Super Awesome Cool Dynamite Wolf Squadron - 10 - Project 1

Super Hero Wiki This is a group project for our Interactive Front End Web Site. We created a Super Wiki that uses two (2) APIs to provide users a comi

Mar 24, 2022

A cool npm package.

aditya.utils Colorful Console const a = require('aditya.utils') a.logblue("TEXT") // Blue Text a.logred("TEXT") // Red Text a.loggreen("TEXT") // Gree

Apr 8, 2022

A cool npm package.

aditya.utils Colorful Console const a = require('aditya.utils') a.logblue("TEXT") // Blue Text a.logred("TEXT") // Red Text a.loggreen("TEXT") // Gree

Apr 8, 2022

A cool tool that saves you time if you want to remove node_modules before running 'npm i'

rmnpm A cool tool that saves you time if you want to remove your node_modules folder before running the npm install command. How does it do it? By fir

Jul 16, 2022

Tool Cool Color Picker is a color picker library written in typescript and using web component technologies.

Tool Cool Color Picker is a color picker library written in typescript and using web component technologies.

Tool Cool Color Picker Tool Cool Color Picker is a color picker library written in typescript and using web component technologies. Check out the demo

Oct 23, 2022

Tool Cool Range Slider

Tool Cool Range Slider

Responsive range slider library written in typescript and using web component technologies. Pure JavaScript without additional dependencies. It has a rich set of settings, including a vertical slider, touch, mousewheel and keyboard support, local and session storage, and RTL support.

Dec 31, 2022

The official pokemon website is not that cool? Here is the alternative 😉

The official pokemon website is not that cool? Here is the alternative 😉

Pokemon Awesome Pokemon Data All Pokemon data used in this project comes from PokeAPI GraphQL Beta. Playground: https://beta.pokeapi.co/graphql/consol

Dec 23, 2022

🚀 A small JS no-dependency library for a cool download experience

🚀 A small JS no-dependency library for a cool download experience

JS File Downloader 🌟 Please remember to star this github repo if you like it. Thank you! ❤️ Introduction JS File Downloader is a simple no dependency

Dec 23, 2022

Chocolat : the lightbox so cool horses use it :horse:

Chocolat : the lightbox so cool horses use it  :horse:

Chocolat Chocolat is a responsive lightbox Documentation is here Demo page is here Documentation You can access the full documentation at this page :

Jan 6, 2023
Owner
Andrea Giammarchi
Web, Mobile, IoT and all Web & JS things since 00's
Andrea Giammarchi
A pretty cool org-mode -> interactive blog post tool

Radish A kinda-cool org-mode -> interactive blog post tool written with and for Clojure(script). Here are two example posts created with this tool: Ra

adam-james 46 Dec 28, 2021
Create a deep copy of a set of matched elements with the dynamic state of all form elements copied to the cloned elements.

jq-deepest-copy FUNCTION: Create a deep copy of a set of matched elements while preserving the dynamic state of any matched form elements. Example Use

Michael Coughlin 5 Oct 28, 2022
This is a (pretty broken, but mostly functional) organic-shaped jigsaw generator with custom border support

OrganicPuzzleJs This is a (pretty broken, but mostly functional) organic-shaped jigsaw generator with custom border support. It relies on two linbrari

null 6 Dec 10, 2022
A javascript framework for developing pretty browser dialogs and notifications.

AlertifyJS AlertifyJS is a javascript framework for developing pretty browser dialogs and notifications. AlertifyJS is an extreme makeover of alertify

Mohammad Younes 2k Jan 2, 2023
Pretty, customisable, cross browser replacement scrollbars

jScrollPane - cross browser custom scroll bars jScrollPane is a jQuery plugin which allows you to replace a browser's default scroll bars (on an eleme

Kelvin Luck 2.2k Dec 15, 2022
A lightweight JavaScript library for creating interactive maps and pretty data visualization.

Jsvectormap A lightweight Javascript library for creating interactive maps and pretty data visualization. Explore docs . Report bug · View demo · Down

Mustafa Omar 204 Dec 24, 2022
✨ Properly credit deps and assets in your projects in a pretty way.

Acknowledgements ✨ Properly credit deps and assets in your projects in a pretty way. About Acknowledgments is a CLI tool that generates a JSON file wi

Clembs 5 Sep 1, 2022
An open-source, pretty, simple and fast meilisearch UI for managing your meilisearch instances

Meilisearch-UI An open-source, pretty, simple and fast meilisearch UI for managing your meilisearch instances [IMPORTANT] The main branch may be unsta

Kyrie Lrvinye 29 Dec 29, 2022
The repository contains the list of awesome✨ & cool web development beginner-friendly✌️ projects!

Web-dev-mini-projects The repository contains the list of awesome ✨ & cool web development beginner-friendly ✌️ projects! Web-dev-mini-projects ADD AN

Ayush Parikh 265 Jan 3, 2023
JavaScript/TypeScript library to run repetitive tasks with throttle control and other cool features

Repeatify JavaScript/TypeScript library to run repetitive tasks with throttle control and other cool features Install npm install repeatify Usage impo

Evert Arias 2 Jan 15, 2022