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

vvvjs

v1.0.6

Published

A small library that uses native-inspired apis to add dynamic functionality to webpages

Downloads

25

Readme

Note: Still testing the bundling methods for this package. Will stabilize soon. Documentation is still being created for this project.

VVV.js

VVVjs is Virtually Vanilla Javascript. It includes libraries that smooth out creating and querying elements, a simple router and a simple event bus. Combined together, VVVjs can be used as a framework for SPA's and MPA's.

Note: This library does not include reactivity.

Installation

With bundling: npm i vvvjs

For native esm

npx degit github:hyrumwhite/vvvjs/dist/vvv-native-minified ./vvvjs

or

npx degit github:hyrumwhite/vvvjs/dist/vvv-native ./vvvjs

then set up serving the folder as needed

createElement

import createElement from "vvvjs";
const { fragment, header, h2, a, main } = createElement;

const HomePageLink = () =>
  h2([
    a({
      textContent: "sethwhite.dev",
      href: "/",
      click($event) {
        console.log("heading home!");
      },
    }),
  ]);

fragment({
  parentElement: document.body,
  children: [
    header({
      class: "hero",
      children: [HomePageLink()],
    }),
    main({
      id: "main-outlet",
      style: {
        display: "flex",
        flex: "1 1 auto",
        overflow: "auto",
      },
    }),
  ],
});

API

createElement is a proxied function. This means it can be invoked directly createElement('div', options) or it can be 'destructured' into functions bound to the desired prop name.

import createElement from "vvvjs";

const banner = createElement('marquee', {textContent: 'we are the hollow men'})

//is the same as

const {marquee} = createElement;
const secondBanner = marquee({textContent: 'the stuffed men'})

//also works
const existingMarquee = document.querySelector('marquee');
const enhancedMarquee = createElement(existingMarquee, {
  textContent: 'leaning together'
})

Because of proxy traps, the destructured prop can be any valid html tag name. 'fragment' is an acceptable param/key. This will return a document fragment.

The createElement function can be passed an existing element. The options passed will be applied to this element.

const { ['epic-element']: epicElement } = createElement;
const mythicElement = createElement["mythic-element"]; //also a valid way to create the element function

//traps allow us to create arbitrary element functions
customElement.define('some-web-component', SomeComponentDefinition);
const { ['some-web-component']: someWebComponent } = createElement;
someWebComponent('headpiece filled with straw, alas!');

If you're familiar with HTMLElement attributes, properties, and methods, you already know the VVVjs API.

const {main, section, h2 } = createElement;
main({
  parentElement: document.body,
  className: 'dark'
  children:[
    section({
      children:[
        h2({
          innerHTML: `<b>I wouldn't recommend this!</b>`,
          click($event) {
            window.alert('you clicked the welcome banner!')
          }
        })
      ]
    })
  ]
})

The options passed can be a string, an array, or an object with keys representing any valid html attribute or property with some special keys. If the key is not found in the given element, i.e. 'checked' on a non-checkbox element, VVVjs assumes it should be an attribute.

Special Object Keys

parentElement: The created element will be appended to this element

style: Object or string. Applies the given style via element.style = value or Object.assign(element.style, value)

children: Expects an array of HTMLElements and will append each element in the array to the created element

shadowChildren: Expects an array of HTMLElements. A shadow DOM will be attached to the created elements and the given elements will be appended to the shadow DOM inside the created element. Note that style and link elements are valid children.

function keys: Passing a key as a function causes an event listener of type {key} to the created element.

const {input} = createElement;
input({
  parentElement: document.body,
  input($event) {
    console.log(`You entered: ${$event.target.value}`);
  }
})

defineProperties: Using this runs Object.defineProperties on the created element and passes the associated value as the second parameter. This can be used to create components that act as proxies for their children. Example:

const {input, label, span} = createElement;
export const fancyInput = (props) => {
  const inputRef = input();
  const component = label({
    shadowChildren: [
      span(props.label),
      inputRef
    ],
    defineProperties: {
      value: {
        get: () => inputRef.value,
        set: value => inputRef.value = value
      }
    }
  })
  return component;
}
//we can now interact with the fancyInput label like an input, by changing fancyInput.value

String option

Often an element just needs to display text. If an element function is invoked with a string, the string will be applied to the elements 'textContent' prop.

const {p} = createElement;
const paragraph = p('Our dried voices, when');
//creates <p>Our dried voices, when</p>

Array option

Often an element acts only as a wrapper for children. If an element function is invoked with an Array, the elements in the array will be applied as though they were passed via the 'children' key on the object options.

const {div, p} = createElement;
const wrapper = div([
  p('We whisper together'),
  p('Are quiet and meaningless'),
])

getElement

import { getElement } from "vvvjs";

const main = getElement("#main-outlet");

main.$div.style.backgroundColor = "red";

main.$$input.forEach((input) => (input.style.backgroundColor = "blue"));

main["$#footer > select"].$option[0].setAttribute("selected", true);

Router

Event Bus