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

hula

v1.0.3

Published

A simple, modern web app framework

Downloads

3

Readme

hula

A simple, modern web app framework

Basic Setup

The following commands will create a hula app and start the development server. Your app will be served at http://localhost:3000.

$ git clone https://github.com/nothingisdead/hula.git new_app
$ cd new_app
$ npm install
$ node

In development mode (default), the server will reload any open pages when it is restarted. nodemon can be used to automatically restart the server on changes:

$ npm install -g nodemon
$ nodemon

Components

  • Components should be created under src/components.
  • Routes matching the component path will automatically be created for any components.
  • Child routes will automatically be passed to any matching parent routes for inclusion.

Example:

hula comes with an example todo app, which is reproduced below.

src/components/todo.js

if(typeof document !== 'undefined') {
	document.title = 'Todo Example';
}

export default class {
	constructor(app) {
		this.app = app;
	}

	static get forward() {
		return '/list';
	}

	// Return an html string (or a Promise)
	render(child) {
		// Use the this.app template tag to include components
		return this.app`
			<style>
				.container {
					display         : flex;
					align-items     : center;
					justify-content : center;
					position        : absolute;
					top             : 0;
					right           : 0;
					bottom          : 0;
					left            : 0;
				}

				.app {
					box-shadow : 0 0 1px 0 black;
					padding    : 1rem;
					width      : 600px;
					height     : 400px;
					text-align : center;
					overflow   : auto;
				}
			</style>

			<div class="container">
				<div class="app">
					<h1>Todos:</h1>
					<!-- Include the child component -->
					${child || ''}
				</div>
			</div>
		`;
	}
};

src/components/todo/list.js

const items = [
	{
		title : 'Create sample hula app',
		done  : true,
	},
	{
		title : 'Add some todos',
		done  : false,
	}
];

export default class {
	constructor(app) {
		this.app = app;
	}

	// Register event listeners for this component
	register(component) {
		// Handle deleting an item
		component.addEventListener('change', (e) => {
			if(e.target.type === 'checkbox') {
				// Set the 'done' property
				items[e.target.dataset.item].done = e.target.checked;

				// Update the component
				component.update();
			}
		});

		// Handle creating an item
		component.addEventListener('submit', (e) => {
			// Prevent navigation
			e.preventDefault();

			// Add the item
			items.push({
				title : component.querySelector('input').value,
				done  : false,
			});

			// "Add some todos" is complete
			items[1].done = true;

			// Reset the form
			e.target.reset();

			// Upate the component
			component.update();
		});
	}

	render() {
		return this.app`
			<style>
				.list {
					display         : inline-block;
					padding         : 0;
					text-align      : left;
					list-style-type : none;
				}

				.list label {
					cursor : pointer;
				}

				.list .done span {
					text-decoration : line-through;
				}
			</style>

			<form>
				<input type="text" placeholder="Enter an item">
			</form>
			<ul class="list">
				${items.map(({ title, done }, i) => `
					<li${done ? ' class="done"' : ''}>
						<label>
							<input data-item="${i}" type="checkbox"${done ? ' checked' : ''}>
							<span>${title}</span>
						</label>
					</li>
				`)}
			</ul>
		`;
	}
};