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

gza

v1.9.1

Published

Declarative custom HTML elements

Downloads

14

Readme

GZA

Declarative custom HTML elements

const gza = require('gza')

gza`
<my-element ${ {test: 'pass'} }>
  ${ settings => settings.test }
</my-element>
`
<!-- Example w/ defaults -->
<my-element></my-element>

<!-- Renders -->
<my-element>
  <render>
    pass
  </render>
</my-element>

<!-- Example w/ property -->
<my-element test="test-prop"></my-element>

<!-- Renders -->
<my-element>
  <render>
    test-prop
  </render>
</my-element>

See also markdown-element which is implemented with gza

Features

Initialization Functions

Any function defined before your element definition is an initialization function. It takes a single argument, an instance of the new element.

Only after all intialization functions have finished, including async functions, will the render function be called.

Initialization functions are only ever called once per element instance.

gza`
${async element => {
  let resp = await fetch('flowers.jpg')
  let blob = await resp.blob()
  element.src = URL.createObjectURL(blob)
}}
<my-image ${ {src: null} } >
  <img src="${settings => settings.src}"></img>
</my-image>
`

Templatized Rendering

All content and functions defined inside your element definition are used for templatized rendering.

The content and function results are used to display content in the <render> element.

Every time an element attribute or element property changes that was previously defined by the defaults, the entire element template will be run again in order to re-render.

Every time the contents of the element changes it will also call the template functions in order to re-render.

gza`
<my-element ${one: 1, two: 2, three: 3}>
  <h1>${settings => settings.one}</h1>
  <h2>${settings => settings.two}</h2>
  <h3>${settings => settings.three}</h3>
</my-element>
`
<!-- Example w/ defaults -->
<my-element></my-element>
<!-- Renders -->
<my-element>
  <render>
    <h1>1</h1>
    <h2>2</h2>
    <h3>3</h3>
  </render>
</my-element>

<!-- Property/Attribute changes will re-render -->
<script>
  let elem = document.querySelector('my-element')
  elem.one = 'one'
  elem.setAttribute('two', 'two')
  elem.setAttributeNS(null, 'three', 'three')
</script>
<!-- Re-Renders As -->
<my-element>
  <render>
    <h1>one</h1>
    <h2>two</h2>
    <h3>three</h3>
  </render>
</my-element>

ShadowDOM

Any content defined below your element definition will be attached to the shadowDOM. If you do not create a slot for "render" then the rendered content will have nowhere to display.

You can also include template functions to dynamically change the shadowDOM content and styling when properties and values change.

const nowhitespace = str => str.replace(/ /g, '')

gza`
<my-element>
  ${(settings, innerHTML) => nowhitespace(innerHTML)}
</my-element>
<style>
h3 {
  font-size: 200%;
}
</style>
<h3>${(settings, innerHTML) => nowhitespace(innerHTML)}</h3>
<slot name="render"></slot>
`
<!-- Example w/ defaults -->
<my-element>This is a test.</my-element>
<!-- Renders -->
<my-element>
  <h3>Thisisatest.</h3> <!-- This will display at 200% font size. -->
  <render>Thisisatest.</render>
</my-element>

Kitchen Sink

Here's an example of every feature currently implemented.

const gza = require('gza')

gza`
${element => { /* initialization function */
  element.i += 1
}}
${async element => { /* supports async functions */
  element.i += 1
}}
<test-kitchen ${{test: 'test', i: 0, size: 100}}> <!-- Default settings -->
  <div id="constructors">${settings => settings.i}</div> <!-- Templating -->
  <div id="propdefault">${async settings => settings.test}</div> <!-- Supports async -->
  <div id="inner">${(settings, innerHTML) => innerHTML}</div>
</test-kitchen>
<style>
::slotted(render) {
  font-size: ${settings => settings.size + '%'}; <!-- ShadowDOM Templating -->
}
</style>
<h3>Test</h3>
<slot name="render"></slot>
`
<!-- Example w/ defaults -->
<kitchen-sink>TestContent</kitchen-sink>

<!-- Renders -->
<kitchen-sink>
  <h3>Test</h3>
  <render>
    <div id="constructors">2</div>
    <div id="propdefault">test</div>
    <div id="inner">TestContent</div>
  </render>
</kitchen-sink>

<!-- Example w/ property -->
<kitchen-sink size=200>TestContent</my-element>

<!-- Renders the same as before but with font-size increased to 200%-->

Why is it called GZA?

Cause GZA the genius!