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

@onenexus/polymorph

v1.0.0-beta.5

Published

Style Synergy modules/BEM DOM elements using JavaScript

Downloads

6

Readme

GitHub license Inline docs Build Status npm version npm downloads codecov

Style Synergy modules/BEM DOM elements using JavaScript

Overview

Polymorph is used for styling DOM elements that follow the Synergy naming convention.

Learn how to integrate with React components

View a live demo using React + Polymorph

Example Module Markup
<div class="accordion">
    <div class="accordion_panel">
        <div class="accordion_title">foo</div>
        <div class="accordion_content">bar</div>
    </div>
    <div class="accordion_panel-active">
        <div class="accordion_title">fizz</div>
        <div class="accordion_content">buzz</div>
    </div>
</div>

Learn more about Synergy modules

Style all accordion modules
document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        'position': 'relative'
    });
});
Style panel components

Learn more about Synergy Components

document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        panel: {
            'display': 'block'
        }
    });
});
Style panel components with active modifier
document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        panel: {
            'color': 'white',

            'modifier(active)': {
                'color': 'blue'
            }
        }
    }
});
Alternatively
document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        panel: panel => ({
            'color': panel.matches('.accordion_panel-active') ? 'blue' : 'white'
        })
    }
});
Using In-Built modifier Method

This ensures no class names are hard coded

Learn more about the modifier method

document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        panel: panel => ({
            'color': polymorph.modifier(panel, 'active') ? 'blue' : 'white'
        })
    }
});
Using sQuery (Recommended)

Learn more about sQuery

sQuery('accordion', element => {
    polymorph(element, {
        panel: panel => ({
            'color': panel.modifier('active') ? 'blue' : 'white'
        })
    }
});
Style title components when parent panel component has active modifier
document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        panel: {
            'modifier(active)': {
                title: {
                    'color': 'red'
                }
            }
        },
        title: {
            'color': 'blue'
        }
    }
});
Alternatively
document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        title: title => ({
            'color': title.closest('.accordion_panel-active') ? 'red' : 'blue'
        })
    }
});
Using sQuery

Learn more about sQuery

sQuery('accordion', element => {
    polymorph(element, {
        title: title => ({
            'color': title.parent('panel').is('active') ? 'red' : 'blue'
        })
    }
});

Installation & Setup

npm install --save @onenexus/polymorph
import 'polymorph' from '@onenexus/polymorph';

polymorph(document.getElementById('someElement'), someConfigurationObject);

Using BEM? Checkout the Working With BEM page

API

Polymorph.modifier()

Determine if an HTML element has the specified modifier

polymorph.modifier(element, modifier)
Example
<div class="accordion">
    <div class="accordion_panel">
        <div class="accordion_title">foo</div>
        <div class="accordion_content">bar</div>
    </div>
    <div class="accordion_panel-active">
        <div class="accordion_title">fizz</div>
        <div class="accordion_content">buzz</div>
    </div>
</div>
document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        panel: panel => ({
            'color': polymorph.modifier(panel, 'active') ? 'blue' : 'white'
        })
    }
});
Result
<div class="accordion">
    <div class="accordion_panel" style="color: white;">
        ...
    </div>
    <div class="accordion_panel-active" style="color: blue;">
        ...
    </div>
</div>

Element.repaint()

Repaint the module by re-applying the style rules

element.repaint()

This method is attached directly to the DOM element after the initial polymorph call

This is useful for updating the styles after an event that modifies the DOM, such as a click event which adds an active modifier to an element. In order to repaint the element, you should call the repaint() method in the same place you handle the event.

Example
<div class="accordion" id="alpha">
    <div class="accordion_panel">
        <div class="accordion_title">foo</div>
        <div class="accordion_content">bar</div>
    </div>
    <div class="accordion_panel">
        <div class="accordion_title">fizz</div>
        <div class="accordion_content">buzz</div>
    </div>
</div>
polymorph(document.getElementById('alpha'), {
    panel: {
        'background': 'red';

        'modifier(active)': {
            'background': 'blue'
        }
    }
});

// `#alpha` element and all targeted child components
//  will now have a `repaint()` method
document.querySelectorAll('.accordion').forEach(accordion => {
    accordion.querySelectorAll('.accordion_panel').forEach(panel => {
      panel.querySelector('.accordion_title').addEventListener('click', () => {
        // do event handling...
        panel.classList.toggle('accordion_panel-active');
        
        // repaint the accordion panel
        panel.repaint();
      });
    }
});
Using sQuery
sQuery('accordion').getComponents('panel').forEach(PANEL => {
    sQuery(PANEL).getComponent('title').addEventListener('click', () => {
        // the `repaint` method is called automatically
        // when using the sQuery API
        sQuery(PANEL).toggleModifier('visible');
    });
});
Using Lucid
// By passing a styles function/object to the `styles` prop of `<Module>`,
// `repaint()` will be called on the approprate rendered DOM elements
//  in the `componentDidUpdate` lifecycle method
<Module name='myModule' styles={styles}>...</Module>

Use With sQuery

sQuery is a JavaScript library for interacting with Synergy modules

sQuery is perfect for interacting with Polymorph, and isn't included by default to keep bundle size down (as it isn't strictly required for functionality).

Once installed, you can use sQuery to style your modules and components much more easily using the provided API.

Without sQuery
document.querySelectorAll('.accordion').forEach(element => {
    polymorph(element, {
        title: title => ({
            'color': title.closest('.accordion_panel-active') ? 'red' : 'blue'
        })
    }
});
With sQuery
sQuery('accordion', element => polymorph(element, {
    title: title => ({
        'color': title.parent('panel').is('active') ? 'red' : 'blue'
    })
}));

Use With Lucid

Lucid is a set of higher-order React components for rendering Synergy modules

Lucid and Polymorph were built in tandem as part of the Synergy framework, so go hand-in-hand together. If you are using Lucid, the easiest way to use Polymorph as the styleParser function is to attach it to the window.Synergy.styleParser property:

import { Module, Component } from '@onenexus/lucid';
import Polymorph from '@onenexus/polymorph';

window.Synergy = {
    styleParser: Polymorph
}

// start using Lucid components (Module, Component)...

Learn more about using Polymorph with Lucid