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

dom-bindings

v2.0.0

Published

Takes binding declarations and returns key-tree-store of functions that can be used to apply those bindings.

Downloads

2

Readme

dom-bindings

Takes binding declarations as described below and returns key-tree-store of functions that can be used to apply those bindings to a DOM tree.

The returned functions should be called with these arguments: The root element, the current value of the property, and a name for the binding types where that is relevant.

install

npm install dom-bindings

Binding types

text

sets/maintains textContent of selected element. treats undefined, null, and NaN as ''

'model.key': {
    type: 'text',
    selector: '.someSelector' // or role
}

class

sets and maintains single class as string that matches value of property

  • handles removing previous class if there was one
  • treats undefined, null, and NaN as '' (empty string).
'model.key': {
    type: 'class',
    selector: // or role
}

attribute

sets the whole attribute to match value of property. treats undefined, null, and NaN as '' (empty string).

'model.key': {
    type: 'attribute',
    selector: '#something', // or role
    name: 'width'
}

booleanClass

add/removes class based on boolean interpretation of property name.

'model.active': {
    type: 'booleanClass',
    selector: '#something', // or role
    // to specify name of class to toggle (if different than key name)
    // you could either specify a name
    name: 'active'
    // or a yes/no case
    yes: 'active',
    no: 'not-active'
}

booleanAttribute

toggles whole attribute on the element (think checked) based on boolean interpretation of property name.

'model.isAwesome': {
    type: 'booleanAttribute',
    selector: '#something', // or role
    name: 'checked'
}

toggle

toggles existance of entire element (uses a comment node as placeholder if gone) based on boolean interpretation of property name.

// simple show/hide of single element
'model.key': {
    type: 'toggle',
    selector: '#something' // or role
}

// show/hide where true/false show different things
'model.key': {
    type: 'toggle',
    yes: '#true_case',
    no: '#false_case'
}

switch

Toggles existance of multiple items based on value of property.

'model.activetab': {
    type: 'switch',
    cases: {
        'edit': '#edit_tab',
        'new': '#new_tab',
        'details': '#details_tab'
    }
}

Handling multiple bindings for a given key

If given an array, then treat each contained item as separate binding

'model.key': [
    {
        type: 'booleanClass',
        selector: '#something', // or role
        name: 'active' // (optional) name of class to toggle if different than key name
    },
    {
        type: 'attribute',
        selector: '#something', // or role
        name: 'width'
    }
]

binding using role attribute

We've started using this convention a lot, rather than using classes and IDs in JS to select elements within a view, we use the role attribute. This lets designers edit templates without fear of breaking something by changing a class. It works wonderfully, but the only thing that sucks about that is the syntax of attribute selectors: [role=some-role] is a bit annoying to type a million types, and also in JS-land when coding and we see [ we always assume arrays.

I'm proposing that for each of these bindings you can either use selector or role, so these two would be equivalent:

'model.key': {
    selector: '[role=my-element]'
}

'model.key': {
    role: 'my-element'
}

handling simplest cases: text

'model.key': '#something' // creates `text` binding for that selector and property

// `type` defaults to `text` so we can also do
'model.key': {
    role: 'role-name'
}

real life example

var View = require('ampersand-view');
var templates = require('../templates');


module.exports = View.extend({
    template: templates.includes.app,
    bindings: {
        'model.client_name': {
            role: 'name'
        },
        'model.logo_uri': {
            type: 'attribute',
            name: 'src',
            role: 'icon'
        }
    }
});

other benefits

Previously after having given views the ability to have their own properties (since view inherits from state) it was awkward to bind those to the DOM. Also, for binding things that were not just this.model the syntax had to change.

Now this is fairly simple/obvious:

module.exports = View.extend({
    template: templates.includes.app,
    props: {
        activetab: 'string',
        person: 'state',
        meeting: 'state'
    },
    bindings: {
        // for the property that's directly on the view
        'activetab': {
            type: 'switch',
            case: {
                'edit': '#edit_tab',
                'new': '#new_tab',
                'details': '#details_tab'
            }
        },
        // this one is for one model
        'person.full_name': '[role=name]',
        // this one is for another model
        'meeting.subject': '[role=subject]'
    }
});

credits

If you like this follow @HenrikJoreteg on twitter.

license

MIT