Skip to content

Latest commit

 

History

History
429 lines (296 loc) · 10.6 KB

README.md

File metadata and controls

429 lines (296 loc) · 10.6 KB

snuggsi ツ - Easy Web Components in ~1kiloByte

NPM monthly downloads Travis CI build Brotli size npm version dependency status license Pull requests welcome!

All you need is a browser and basic understanding of HTML, CSS, & Javascript classes to be productive!

Performance is the art of avoiding work - #FreeJewelry 💍 💎

Why ?

  1. Because You (probably) don't need a Javascript Framework

  2. You prefer convention over configuration & Web Components are ready for production

  3. Custom Elements v1 has full support for every modern browser including Internet Explorer 11+ / Edge

Easy Installation

Made with 💖 Vanilla JS™ No need to learn Node.js, Webpack, Babel, or Gulp. #UseThePlatform

snuggsiツ works in production or in a plain 'ol HTML file!

Simply place the following script within your webpage:

<!-- http(s): protocol required to run locally -->
<script src=//unpkg.com/snuggsi></script>

Et Voila (that's it!)

Browser Support

Support IE11+ Edge* Chrome* Firefox* Safari 9+ Chrome (Android)* iOS Safari*
Templates
Custom Elements
Slot Replacement
Remote Components

*Indicates the current version of the browser

⚠️ Warning ⚠️ We shall provide our best effort to support IE 11+ through EOL

Please read Microsoft Internet Explorer end-of-life announcement for further details.

Quick Tour

Play Hello World Demo

The following is a snippet from examples/hello-word

See examples for more details

<hello-world>
 Hello {planet}
</hello-world>

<script src=https://unpkg.com/snuggsi></script>
<script>

// Element Definition -----------------------------

Element `hello-world`

// Class Description ------------------------------

(class extends HTMLElement {

  onclick ()
    // "automagic" event registration
    { alert (this.textContent) }

  get planet ()
    // "automagic" token binding
    { return 'world 🌎' }
})

</script>

The <template> is used to define custom element content for use within multiple elements.

Useful when we need to:

  1. Separate a custom element definition into a Remote Component.
  2. Bind a context to the template using An Array or POJO (Plain Ol' Javascript Object)
  3. Append rendered template to the document.
    • If context is an object bind a single <template>
    • If context is a collection (i.e. an Array) bind a tandem <template> fragment per item

<template> With Object Context

<template name=developer>
  <!-- `{name}` will bind to `context` property `name` -->
  <h1>{name}</h1>
</template>

<script src=//unpkg.com/snuggsi></script>
<script>

const
  template = Template `developer`
, context  = { name: 'That Beast' }

template.bind (context)

</script>

Resulting HTML

<template name="developer">
<!-- invisible
  <h1>{name}</h1>
 -->
</template>

<h1>That Beast</h1><!-- template is used as head for tail insertion -->

<template> With Object Array Context

Each <template name> will be mapped over each context item within the array. When the array items are objects each property will map to a respective {token} of the same name.

Note: The # symbol is used to retrieve the collection's current index of iteration.

<ul>
  <template name=item>
    <li>Hello {name}! Your index # is {#}
  </template>
</ul>

<script src=//unpkg.com/snuggsi></script>
<script>

// when context is a collection
const
  template = Template `item`
, context  = [ {name: 'DevPunk'}, {name: 'Snuggsi'} ]

// internal template render for each item in context
template.bind (context)

</script>

Resulting HTML

<ul>
  <template name="item">
  <!-- invisible
    <li>Hello {name}! Your index # is {#}
  -->
  </template>

  <li>Hello DevPunk! Your number index # is 0</li>
  <li>Hello Snuggsi! Your number index # is 1</li>
</ul>

<template> With Scalar Array Context

Each <template name> will be mapped over each context item within the array. When the array items are scalar (i.e. strings, numbers, booleans) each item will map to a {self} helper token.

Note: The # symbol is used to retrieve the collection's current index of iteration.

<dl>
  <template name=recipe>
    <dt> Step {#}.
    <dd> {self}.

  </template>
</dl>

<script src=//unpkg.com/snuggsi></script>
<script>

// when context is a collection of scalars
const
  template = Template `recipe`
, context  = [
    "Preheat oven"
  , "Place pre-made cake in oven"
  , "Don't burn the cake"
  , "Nom Nom"
  ]

// internal template render for each item in context
template.bind (context)

</script>

Resulting HTML

<dl>
  <template name="recipe">
  <!-- invisible
    <dt> Step {#}.
    <dd> {self}.

  -->
  </template>

  <dt> Step 1.</dt>
  <dd> Preheat oven.</dd>

  <dt> Step 2.</dt>
  <dd> Place pre-made cake in oven.</dd>

  <dt> Step 3.</dt>
  <dd> Don't burn the cake!</dd>

  <dt> Step 4.</dt>
  <dd> Nom Nom!</dd>

</dl>

Component - a part or element of a larger whole.

snuggsiツ provides conventions around <link>able HTML resources when components grow in size and dependencies.

A snuggsiツ "Component" supports the following features:

  • Self Documenting.
  • Named <slot> composition & replacement.
  • Components written in pure HTML.
  • Usage of a component <link> requires no JavaScript😮.
  • A default <template> element used as a light DOM for custom element definitions.
  • Resource such as scripts, stylesheets, fonts, and other resources can be declared for use within master document via the <link> tag. (Learn More)

Master Document index.html

<!doctype html>

<title>Remote Component Example</title>

<link
  as=fetch
  id=foo-bar
  rel=preload
  href=foo-bar.html
>

<script src=//unpkg.com/snuggsi></script>


<foo-bar>
  <p slot=content>The quick brown fox jumped over the lazy dog
</foo-bar>

Default <template> in foo-bar.html

<template onclick=onfoo>

  <h1>foo-bar custom element</h1>

  <slot name=content>Some Default Content</slot>

  <ul>
    <template name=bat>
      <li>Item {#} - Value {self}
    </template>
  </ul>

</template>


<script>

Element `foo-bar`

(class extends HTMLElement {

  onfoo (event)
    { alert `Registered on foo-bar` }

  get bat ()
    { return ['football', 'soccer', 'baseball'] }
})

</script>

Resulting Master Document index.html

<!doctype html>

<html>
  <head>
    <title>Remote Component Example</title>

    <link as="fetch" id="foo-bar" rel="preload" href="foo-bar.html">

    <script src="https://unpkg.com/snuggsi"></script>
  </head>

  <body>
    <foo-bar onclick="onfoo">
      <h1>foo-bar custom element</h1>

      <p slot="content">The quick brown fox jumped over the lazy dog</p>

      <ul>
        <template name="bat">
        <!-- invisible
          <li>Item {#} - Value {self}
        -->
        </template>

        <li>Item 0 - Value football</li>
        <li>Item 1 - Value soccer</li>
        <li>Item 2 - Value baseball</li>
      </ul>
    </foo-bar>

    <script>

    Element `foo-bar`

    (class extends HTMLElement {

      onfoo (event)
        { alert `Registered on foo-bar` }

      get bat ()
        { return ['football', 'soccer', 'baseball'] }
    })

    </script>
  </body>
</html>

Further Learning

Build Process

snuggsiツ is able to use modern compression algorithms to create bundles as small as ~1500 OCTETS (or one 1500byte Ethernet packet frame)

Read More