Skip to content

aliafshar/yip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

yip

Github | Docs | Demo | Tests | License

Tiny custom element toolbox for the web.

Yip is a JavaScript library/demo which provides:

  • Creating and registering new custom elements
  • Shadow DOM manipulation and generation library
  • Event handling and emitting

For interacting with the Shadow DOM, there are a number of features:

  • Create and add DOM
  • Create and manage the <slot>
  • Add stylesheets, scripts or templates
  • Support any template engine without a plugin

Note: Yip uses Custom Elements v1 API. Polyfilling that to older browsers is left as an exercise for the brave user.

Start now

To get started we are going to create a custom element my-note that will render as an HTML <aside> element. That's all.

First, subclass yip.Element to create your custom element, then call yip.register to register your new custom element.

Now you can describe how to build the DOM for your element by overriding yipBuild. For our <my-note> use-case, you would build it like:

class Note extends yip.Element {
  yipBuild() {
    this.yipAddElement('aside');
  }
}

yip.register('my-note', Note);

Now you can use your elements with:

<my-note>yo!</my-note>

And they will render as:

<aside>yo!</aside>

or in reality, looks like:

<my-note>[#shadow]<aside><slot>yo!</slot></aside>[/shadow]</my-note>

But that's the whole point of the shadow DOM, and slots and things.

Applying Element Classes and Attribute Handling

You might want to add attribute handling to your element. The attributes are your API. So, say I want to handle an attribute warning in order to read:

<my-note warning>meep!</my-note>

I might likely want to apply a class to the child aside in order to affect how it looks. Let's apply the warning-text class.

To do this call yipApplyClasses:

class Note extends yip.Element {
  yipBuild() {
    this.yipAddElement('aside');
    this.yipApplyClasses({'warning-text': this.attributes.warning});
  }
}

yip.register('my-note', Note);

Now, using the markup

<my-note>yo!</my-note>
<my-note warning>meep!</my-note>
<my-note error>ohnoes!</my-note>

Using templates

You might want a more complicated UI, and decide to write it in a template:

const t = `<aside>
            <div class="aside-content">
              <slot></slot>
            </div>
            <div cass="aside-actions">
              <button>Ok</button>
              <button>Not Ok</button>
            </div>
          </aside>`;

You can then use this template:

class Note extends yip.Element {
  yipBuild() {
    this.yipAdd(t);
  }
}

yip.register('my-note', Note);

Applying an external template transformer

You might decide that you want more complicated templating. Plug in whatever you like by overriding yipRenderTemplate. For example to use doT templates:

class Note extends yip.Element {
  yipTemplate() {
    return doT.template(t)({'element': this});
  }
  yipBuild() {
    this.yipAdd(this.yipTemplate());
  }
}

yip.register('my-note', Note);

Now we can have all kinds of crazy templates. The example above passes the element into the template, so it can get used as the it.element by doT.

const t = `<template id="my-note-template">
            <aside>
              Is this a warning?
              {{= it.element.attributes.warning  }}
            </aside>`;

Bring your own templating system, and hook it in. No need for plugins or anything.

Adding element-specific styles

First from a loaded external stylesheet.

class Note extends yip.Element {
  yipBuild() {
    this.yipAddStyleLink('css/mystyles.css');
  }
}

Child handling

Because you are in the shadow DOM, an Element's children will not return what you want. What you usually want is the children of the slot. For this we added yipChildren, an attribute that returns the assigned nodes of the element's slot.

Emiting custom events

Elements should emit events. You can easily dispatch an event on your custom element, like:

el.addEventListener('action-clicked', () => {});
el.yipEmit('action-clicked');

Connecting internal events

Just connect them in yipBuild sometime after you have created the elements.

Using Slots

Slots are amazing. They tell the browser where in your shadow DOM children of your element should be added. You should probably define a <slot> element in every template you pass.

You can of course have multiple slots. Yip will only manage the first (default) slot. Please read an article about slots if you care.

If you call yipAddElement a slot will be added for you.


Note: yip is not an official Google product. Didn't wanna be one anyway, so there.

About

Tiny custom elements toolbox for the web.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published