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

@carlosvpi/mosaic

v0.0.14

Published

MVC for the front end

Downloads

6

Readme

mosaic

MVC for the front-end

From a high level perspective, a Mosaic app is made up of tiles, where each tile is one DOM element. @carlosvazpi/mosaic provides a quick way to create and integrate DOM elements in an HTML document, as well as to provide them with a behaviour.

Install

yarn add @carlosvpi/mosaic

How to use

  1. Import Mosaic in your file
import { Mosaic } from '@carlosvpi/mosaic'
  1. Wrap document.body
const bodyConstructor = Mosaic(document.body)

Now through bodyConstructor you can add or remove elements to the body of your document

Creating new tiles in your mosaic

The NodeTile constructor

const nodeTileConstructor = Mosaic`tag[attr1 = value1; attr2 = ${ value 2 }]`

A NodeTile constructor created calling Mosaic with a string template. On creation, a new DOM element is created, and its attributes are set to those provided by the template.

// create a span constructor
const spanConstructor = Mosaic`span[id=span-1]`

Providing attributes to a NodeTile constructor

A NodeTile constructor can be provided attributes that may be static (if provided at the time of creating the NodeTile constructor) or dynamic (if, instead, a function is provided that will set the attribute at a different point in time, or points in time).

  1. Static attribute

This code gives the attribute placeholder statically to an input constructor

const inputConstructor = Mosaic`input[placeholder=type something here]`

A DOM element (input) is created and assigned the attribute placeholder to the value "type something here".

  1. Dynamic attribute

This code gives the attribute placeholder dynamically to an input constructor

const assignPlaceholder = assign => {
	assign('A')
	setTimeout(() => assign('B'), 1000)
	setTimeout(() => assign('Final'), 2000)
}

const inputConstructor = Mosaic`input[placeholder=${assignPlaceholder}]`

A Dom element (input) is created. Then assignPlaceholder is called. The parameter (assign) is a function that sets the attribute of the input to its argument (so assign('a') has the effect that the placeholder of the input will be set to 'a'). In this case, assignPlaceholder sets the placeholder of the input, first, to 'A'. After 1 second, to 'B'. And after yet another second, to 'Final'.

Return the tile from the tile constructor

As we said, a tile constructor creates a tile, but it doesn't return it. Instead, the constructor returns a function children that expects to take the children to be appended to the tile. The children function does return the tile form the tile constructor.

const inputConstructor = Mosaic`input[placeholder=type something here]`
const inputTile = inputConstructor()

In the example above, an input is created without children.

Providing children to a tile constructor

Children are passed as arguments to a tile constructor. This has the effect of adding the children to the tile held by the tile constructor, and also makes the whole expression return said tile.

Children passed to a tile constructor can either be other tiles or even just plain strings (which are transformed into Text DOM elements).

const spanConstructor = Mosaic`span`
const strongConstructor = Mosaic`strong`
const strongTile = strongConstructor('Bold')
const spanTile = spanConstructor('This text is in ', strongTile, '. And this one is not.')

In the example above, a couple of elements are created and one is nested inside the other.

Methods tile.onEnter(enter) and tile.onExit(exit) allow to provide enter and exit functions, to be run when the tile is appended into a parent, and when it is to be removed from the father. The enter function takes as a parameter this (the entering tile) and isn't expected to return anything. The exit function takes as a parameter this (the exiting tile) and is expected to return a promise such that the exiting tile will be removed upon its resolution.

When using a function to return the children, Mosaic expect this function to return an array of pairs [child: Node, keep: boolean], where keep says whether the child has to be kept or removed. Then, children that are not to be kept are called .onExit(). The reason for this structure is to allow some components to unmount on their own terms through tile.onExit(), instead of being unmounted immediatelly, which is what would happen if we don't pass them to the children() method.

The tile.onCancelExit() allows to provide a function to run when a tile's exit must be cancelled due to it having been re-added before it was completely removed.

Assigning classes to a tile

Like attributes, classes can be static or dynamic. Classes are assigned to tiles, not to tile constructors.

Classes are assigned through the .classed() method, which accepts two parameters: the class name and whether the class is to be added (true) or removed (false). Alternatively, instead of two parameters, classes can be given in the form of a hash { string => boolean }.

The .classed() method returns the tile, so it is chainable.

  1. Static classes

This code adds class 'my-class' statically to a span tile.

const spanTile = Mosaic`span`().classed('my-class', true)

Notice that we have to call the span constructor (Mosaic\span``) in order to assign its tile a class.

Another way to do the same:

const spanTile = Mosaic`span`().classed({ 'my-class': true })

The above method allows us to add several classes with one call.

  1. Dynamic classes

Like with the dynamic attributes, if instead true or false we provide a function when calling .classed(), the function will be called and assign the class in a timely manner.

const assignMyClass = assign => {
	let value = true
	assign(value)
	setInterval(() => assign(value = !value), 1000)
}
const spanTile = Mosaic`span`().classed('my-class', assignMyClass)

The above code assigns initially the class my-class to the span tile, and it toggles this class every second.

Another way to do the same:

const assignMyClass = assign => {
	let value = true
	assign(value)
	setInterval(() => assign(value = !value), 1000)
}
const spanTile = Mosaic`span`().classed({ 'my-class': assignMyClass })

Assigning event listeners

Event listeners can be assigned using the .on() on tiles. This method has the same signature as .addEventListener.

The .on() method returns the tile, so it is chainable.

const buttonTile = Mosaic`button`('Click me').on('click', () => { alert('Clicked') })

The above code makes an alert appear upon clicking the button.

Render everything inside the body

In order to build a page, we just pass to the bodyConstructor function the children we expect it to have

bodyConstructor(inputTile, spanTile)

How to compile

@carlosvpi/mosaic is provided as a ts module. In order to use it in the browser you will have some ts file src/index.ts importing it like so

import { Mosaic } from `@carlosvpi/mosaic`

Mosaic(document.body)(Mosaic`h1`('Hello, world'))

Follow these steps:

  1. Compile it

Run

tsc

You will need a tsconfig.json file roughly like this one

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2015",
    "lib": ["es6", "dom", "es2017"],
    "declaration": true,
    "outDir": "./js-src"
  },
  "include": [
    "src/**/*"
  ]
}
  1. Browserify it

Run

browserify js-src/index.js > dist/index.js

You will need to have browserify installed globally. Alternatively, install it in your devDependencies and use yarn browserify instead of browserify (in that case, you will need to remove the first 2 and last lines of the resulting file with sed -i '' '1,2d;$d' dist/index.js).

  1. Minify it

Run

minify dist/index.js > dist/index.min.js

You will need to have minify installed globally. Alternatively, install it in your devDependencies and use yarn minify instead of browserify (in that case, you will need to remove the first 2 and last lines of the resulting file with sed -i '' '1,2d;$d' dist/index.min.js).