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

@purtuga/component-element

v2.4.1

Published

A Custom Element based component to build widgets for the web (not frameworks)

Downloads

19

Readme

ComponentElement

A base class for building Widgets using CustomElements.

Features:

  • Normalizes the use of Props by allowing them to be set via html Attributes, or on the Element's instance.
  • Creates aliases for camelCase props so that they can be set in all lowercase or as ka-bob case.
  • All props are stored in one location (element.props).
  • change to props triggers render

Example

import {ComponentElement, prop} from "@purtuga/component-element";

export default class MyWidget extends ComponentElement {
    static get tagName() { return "my-widget"; }
    
    @prop({ attr: true }) blue = false; 
    
    @prop
    get listName() {
        return "tasks"; // default value
    }
    set listName(newValue) {
        if (!newValue) {
            console.log(`"${ newValue }" is not a valid listName`);
        }
        return this.listName;
    }
    
    render() {
        return `
<style>
h1 {
    color: red;
}
.blue {
    color: blue;
}
<h1 class="${ this.props.blue ? "blue" : ""}">Your list name is: ${this.props.listName}</h1>
`;
    }
}

Installation

$ npm install @purtuga/component-element --save

Polyfill

Include a polyfill prior to any web component being loaded. Something like this will work:

<head>
    <script>
        if (!("Promise" in window)) {
            document.write('<' + 'script src="/' + '/unpkg.com/core-js@^2/client/core.min.js"></' + 'script>');
            console.log("core-js requested");
        }
        if (!('customElements' in window)) {
            document.write('<' + 'script src="/' + '/unpkg.com/@webcomponents/webcomponentsjs@^2"></' + 'script>');
            console.log("CE pollyfill requested");
        }
    </script>
</head>
<body>

    <!-- now load your web components/app -->
</body>

Props

Props can be defined one of two ways:

A. Via Static property propsDef

tbd...

B. Via @prop Decorator

Props can be defined using the prop decorator. Props defined this way are automatically reflected in on the component instance under the props property. When defining a prop on a ComponentElement class, the property getter will be used to obtain the initial value for the property (default value), while the property setter method (if any) will be used as a filter for when the value is being changed - ex. can be used to validate the input received and in turn return a different value to be stored.

The following options exists for this decorator:

prop({
    required: true,
    attr: true
})
  • attr : {Boolean} can the prop be set via an html attribute. (reminder: html attribute values only accept {String} and {Boolean} values).

    IMPORTANT: HTML attribute are initially rendered in all lowercase. This in turn conflicts with the way properties are normally created and used in JavaScript (camelCase). ComponentElement will create a set of aliases for each property: one in all lower case, and another in kebob case.

    So a prop named listName that is set as attr: true, could be defined in html as listname (all lowercase):

    <div listname="some value here"></div>

    or list-name (kebob):

    <div list-name="some value here"></div>

    Or, through javascript, be set using ele.setAttribute("listName", "value"). In all cases, the value will be reflected in the ComponentElement's instance props under the initial value defined (in this example listName).

  • required : {Boolean} If prop value is required. elmenet.hasRequiredProps will use this to calculate its value.

Lifecycle

The following lifecycle hooks are provided on the Element's instance. These are all instance methods that can be defined on your custom element.

    didInit()
        |
    didMount()
        \
         \
          \
            willRender() -> render() -> didRender()
          /
         /
        /
    didUnmount()
        |
    didDestroy()
    
  • didInit: Called only once - when the component class is intantiated
  • didMount: Called every time component is connected to DOM
  • Render cycle, which is also executed every time props change:
    • willRender() Called prior to render(). Reutrning a boolean false will cancel render
    • render(): generate the markup for the view. Should return html (either string or DOM/DocumentFragment)
    • didRender(): Post render.
  • didUnmount(): Element disconnected from DOM
  • didDestroy(): Element's destroy callback were executed

License

MIT


TODO

  • [ ] Support same level of prop reflection as the @prop decorator