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

figura

v6.1.0

Published

View component for markup you already have.

Downloads

3,429

Readme

figura

Build Status BrowserStack Status

View component for markup you already have.

Features:

  • Basic state and props setting and implicit rendering
  • Subview managment: adding, getting and removing

Inspired by:

Try it now!

Install

npm install figura --save

Usage

<div id="shelby">
	<span id="sasha">
		<button type="button" class="lilly">Lilly button</button>
		<span class="honey">Honey content</span>
	</span>
	<i class="roxie">Roxie content</i>
</div>
import Figura from 'figura';

class Shelby extends Figura {
	static el = '#shelby';
	static childrenEl = {
		sasha: '#sasha'
	};
	static events = {
		'click .lilly': 'clickMethod'
	};
	clickMethod() {
		// .lilly clicked!
	}
}

class Sasha extends Shelby {
	static el = '#sasha';
	static childrenEl = {
		...Shelby.childrenEl,
		honey: '.honey'
	};
	clickMethod() {
		// .lilly clicked, with overriden method on `Sasha`.
	}
}

const shelby = new Shelby();

// `roxie` won’t have any child elements and won’t have any event listeners since it doesn’t have any children nodes
const roxie = new Sasha({
	el: '.roxie'
});

Using state and props. All render specifics can be contained inside render method.

import Figura from 'figura';

class Shelby extends Figura {
	static el = '#shelby';
	static defaultProps = {
		text: 'shelby'
	};
	constructor(props) {
		super(props);
		this.render(); // Initial render only with props
		this.setState({
			jackie: 42,
			romeo: '42'
		});
		const state = this.state;
		state.jackie; // => 42 as number
	}
	render(key, value) {
		if (typeof key === 'undefined') {
			this.$el.innerHTML = `Initial content is ${this.props.text}.`; // Initial content is shelby.
		}
		if (key === 'romeo') {
			this.$el.innerHTML = `Value is ${value}.`; // Value is 42.
		}
		return this;
	}
}

Render placeholder and view assign usage.

import Figura from 'figura';

class Shelby extends Figura {
	static el = '#shelby';
	template() {
		// Template function result
	}
	constructor(props) {
		super(props);
		this.addSubview(new Figura(), 'customKey');
	}
	render() {
		this.$el.innerHTML = this.template({
			customKeyComponent: this.getSubview(
				'customKey'
			).getRenderPlaceholder()
		});
		this.assignSubview('customKey');
		return this;
	}
}

API

Every property except el, childrenEl and events will be merged with defaultProps and added to this.props.

el

Type: (string|HTMLElement)
Default: ``

Element on which should view be created.

childrenEl

Type: Object
Default: {}

List of children elements, mapped to DOM nodes based on CSS selector.

To handle common use case of selecting only one element, if result contains only one element, only that element is returned, otherwise array of elements is returned.

If you want to return array of elements regardless of resulting count, append [] to list key.

{
	'shelby': '.shelby', // this.$shelby = this.$('.shelby'); - Returns either one or array of elements, based on resulting count
	'sasha': '.sasha' // this.$sasha = this.$('.sasha'); - Returns either one or array of elements, based on resulting count
	'rudy[]': '.rudy' // this.$rudy = this.$('.rudy'); - Always returns array of elements
}

events

Type: Object
Default: {}

List of events, delegated to children elements.

There are certain considerations to take when using Figura’s event delegation:

  • Since delegating focus and blur events is not natively possible, those events are mapped to focusin and focusout respectively
  • If you don’t provide selector to which you want to delegate event, that event will be attached to root element (i.e., el property value).
{
	'click .shelby': 'method1', // Delegated click event to `.shelby` calling instance method `method1`
	'submit .sasha': 'method2', // Delegated submit event to `.sasha` calling instance method `method2`
	'mouseleave .lilly': 'method3', // Delegated mouseleave event to `.lilly` calling instance method `method3`
	'mouseenter .rudy': ( e ) {  // Delegated mouseenter event to `.rudy` calling anonymous function
		// Do something
	},
	'click': 'method4' // Attached to root element since there is no selector to delegate to
}

defaultProps

Type: Function
Default: {}

Default values for props to ensure that this.props property has value if it hasn’t been passed when creating view instance.

$(selector, returnAllNodes)

Type: Function
Returns: (HTMLElement|HTMLElement[])

Finds all descendants of $el filtered by CSS selector.

| Property | Type | Default | Description | | ---------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | selector | string | N/A | Standard CSS selector. | | returnAllNodes | boolean | false | Always return array of elements. By default, if result contains only one element only that element is returned, if result doesn’t contain any element null is returned, otherwise array of elements is returned. |

render(key, value)

Type: Function
Returns: Figura

Render view. Takes into account state modifications if you use state—every time state is modified render is called with key which is changed and current state. In this instance, state is combination of previous and new state.

| Property | Type | Description | | -------- | -------- | -------------------------------------------------------------- | | key | string | Current state key that should be handled in render. | | value | * | Value of current state key that should be handled in render. |

remove

Type: Function

Remove view, but not root DOM element—use removeElement for that.

setElement(element)

Type: Function

Sets or re-sets current UI element.

element

Type: (string|HTMLElement)

removeElement

Type: Function

Remove view DOM element.

cacheChildrenEl(elements)

Type: Function

Caches children elements.

elements

Type: Object

See childrenEl.

delegateEvents(events)

Type: Function

Delegates events.

events

Type: Object

See events.

undelegateEvents

Type: Function

Undelegates events.

delegate(eventName, selector, listener)

Type: Function

Delegate single event.

If you provide empty string selector, event will be attached to root element.

eventName

Type: string

selector

Type: string

listener

Type: Function

undelegate(eventName, selector, listener)

Type: Function

Undelegate single event. For argument definition, see delegate.

setState(data)

Type: Function

Set state for instance. Runs synchronously, so if one piece of state depends on other (e.g. one key depends on another key), run multiple setState calls with different keys.

addSubview(view, key)

Adds subview to current view.

view

Type: Figura

Subview to add to current view.

key

Type: (string|number)

Subview key so it can be easily identified in subview collection. If undefined, view’s uid property will be used.

getSubview(key)

Gets subview referenced by key.

key

Type: (string|number)

Key which is used to reference subview.

removeSubviews

Removes all subviews from current view.

getRenderPlaceholder

Returns view’s placeholder element which will be used in resolving for assignSubview.

assignSubview(key)

Replaces view’s render placeholder with real content. Real content should be rendered inside subview render method.

key

Type: (string|number)

Key which is used to reference subview.

addSideEffect(...args)

Add side effect. See manageSideEffects.add documentation.

removeSideEffect(...args)

Remove side effect. See manageSideEffects.remove documentation. Every registered side effect is removed on remove method call.

FAQ

Running setState on multiple keys which depend on each other in that call doesn’t render changes properly.

setState runs synchronously, so if one piece of state depends on other (e.g. one key depends on another key in current setState call), run multiple setState calls.

For example, if romeo and layla values depend on each other in current setState call:

// Instead of this
this.setState({
	romeo: 'gigi',
	layla: 'buddy'
});

// Use this
this.setState({
	romeo: 'gigi'
});
this.setState({
	layla: 'buddy'
});

Communicating with parent component from child component

There are a lot of ways you can achieve this:

  • Passing parent component instance to child component instance as prop
  • Using event emmiter and publish/subscribe pattern
  • Passing callback from parent component to child component as prop (recommended, try the example)

Test

For local automated tests, run npm run test:automated:local.

Browser support

Tested in IE9+ and all modern browsers. For IE <= 10 support, you will have to polyfill __proto__ if you use class extending.

For static class properties, you need to use Babel plugin, otherwise set properties explictly on class.

import Figura from 'figura';

// With static class properties
class Shelby extends Figura {
	static el = '';
}

// Without static class properties
class Shelby extends Figura {}
Shelby.el = '';

License

MIT © Ivan Nikolić