# p-cool **Repository Path**: mirrors_WebReflection/p-cool ## Basic Information - **Project Name**: p-cool - **Description**: Pretty Cool Elements - **Primary Language**: Unknown - **License**: ISC - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-08-09 - **Last Updated**: 2026-01-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Pretty Cool Elements **Social Media Photo by [Jamison McAndie](https://unsplash.com/@jamomca) on [Unsplash](https://unsplash.com/)** This module is a follow up of [this Medium post](https://webreflection.medium.com/about-web-components-cc3e8b4035b0), 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 **S**erver **S**ide **R**endering 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](https://github.com/WebReflection/vanilla-elements#readme) #### Example ```js 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) {}, }); ``` ```html
Hello Behaviors 👋
``` ## 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](https://github.com/WebReflection/vanilla-elements#readme) extends through a `p-cool-*` prefix, so that `
`, and `

`, or `

` 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. ```html
Hero
...
``` To implement an *element extend*, the `` *Custom Element* is registered too, so that a page could be defined by non-builtin extends, with mixins/behaviors attached when, and if, needed. ```html ... ``` ## 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. ```js import {define} from 'p-cool'; define('mixin', { attachedCallback(element) { console.log('mixin attached'); }, detachedCallback(element) { console.log('mixin detached'); } }); // example document.body.innerHTML = `
First
Second
`; // 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.