Giter Site home page Giter Site logo

base-class's Introduction

BaseClass

A simple BaseClass for creating native web components with built-in lifecycle and templating!

Todo's:

  • Write Documentation and Create Website
  • Priorized rendering (first render/initialize visible part and then everything else)
  • Create one bundle to import (with baseElement, lit-html and all components)

Getting started

Client Library

To build native web-components with all the features below, you can simply import the base-element.js into your project.

<script src="https://raw.githubusercontent.com/JeremiasEh/base-class/master/scripts/base-element.js" /><script>

SSR static pages

To enable Server-side rendering, you can simply clone this repository. In order to get your own components and pages server-side rendered, you can simply create a git submodule with your repository including:

  • static html pages
  • webcomponents (inherited from base-element)
  • any assets you like

This repository for example uses the src folder for this purpose. This of course is free configurable with the config.json.

SSR dynamic pages

To ssr dynamic web-sites, you have to use the built-in api of this server, to send the html and to receive the pre-rendered html back. The api can certainly be protected with authorization, to prevent others from using your server. Therefore you can configure the server to verify JWT-Tokens sent by the requesting party.

Add Git Submodule

To add your own Repository inside this one, simply run git submodule add. Before this, you should delete the src folder completely or use another folder for your pages, assets and components.

$ git submodule add https://your-repository.org/your-repo.git src

After this step, your own repository should appear in a src folder or however you named it. With this approach you can on the one hand update the base-class repositority, if there are some new features or bug-fixes. On the other hand you can update your own repository and you have the full control over your custom components, pages and other files.

If you use another folder structure inside your git submodule, you have to adjust the config.json (application.pagesDirectory, application.componentsDirectory, application.assetDirectories) to map it to your new folder-structure!

Functionality

  • for-loops in template with ${this.Repeat(…)}
  • conditional attributes, … with ?disabled=${this.isDisabled}
  • build-in lifecycle-methods
  • native javascript expressions
  • computed properties with native methods <span>${this.getInfotext ()}</span>
  • events / actions inside template/component with @click="${ () => this.buttonClickedEvent () }"
  • events / actions outside component with named events like data-event-custom="(componentElement, value1, value2, …) { … }" and execute them from inside the component with this.$emit ('custom', this.value1, this.value2, …);
  • detect SSR or Client-Rendering with the isServer attribute! (e.g. if (this.isServer) { /*Do some things only on server*/} else { /*Do some things only on client*/})

Example

Creating a custom web component is as easy as inherit from the BaseElement-Class and implementing the basic getter template (), attributes () functions. There you can define the template with optional style and attributes.

import BaseElement from './src/base-element.js'

class CustomButton extends BaseElement {

    get template () {
            return this.Template`
            <style>
                input {
                    border: ${this.BorderNumber ()}px solid black;
                }
            </style>
            <input ?disabled=${this.disabled} type="number" value=${this.number} name="number" /> <slot></slot>: <b>${this.number}</b>
            
            <ul>
                ${this.Repeat(
                this.list.slice (0, this.number),
                (item, idx) => this.list [idx],
                (item, idx) => this.Template`
                  <li style="background-color: ${ idx % 2 === 0 ? '#d3d3d3' : 'red' }" >${item}</li>
                `
            )}
            </ul>
            
            <button @click="${() => this.ToggleButtonClicked ()}">Toggle!</button>
        `;
        }
    
        get attributes () {
            return {
                'number': 11,
                'list': [
                    'test1',
                    'test2',
                    'test3'
                ],
                'disabled': true,
            };
        }
}

getter methods

With the init function you define the new web component. You have to define a template, otherwise simply the slot's content will be displayed.

Additionally you can define some component attributes which will be updated automatically when changing them via javascript or otherwise.

methods

  • get template () {…} - lit-html template literal - the templat of the component with also inline commands for js {{ 2+6 }} or {{ this.customAttribute }}
  • get attributes () {…} - object - the attributes this component should support (all usings in template will automatically update)

component lifecycle

component's lifecycle

On Serverside, only the methods before the element get's attatched to the DOM are getting executed with the additional serverInit () callback. (SSR-Methods: beforeCreated (), created (), serverInit ()). The serverInit-Method will be called only while rendering on server and will be executed directly after the created-Method. Here you can define some special things for server-rendering only!

Known limitations

Properties inside template style-attributes

When using component-properties inside the template, the values get's displayed and updated automatically. But when rendering the component on server-side and the browser does not support web components, all equal components will have the style-values of the last element inserted!

base-class's People

Contributors

tanglemesh avatar notwithme avatar

Stargazers

 avatar Alex Rieger avatar

Watchers

James Cloos avatar

base-class's Issues

TypeError on localhost:3000

reproduction

  • clone the project
  • run npm i
  • run node index.js
  • go to localhost:3000

console output:

Server listening on Port: 3000
Error: TypeError: this.Repeat is not a function
    at InputLabel.get template [as template] (src/components/input-label.js:15:20)
    at InputLabel.render (/Users/user/Sites/base-class/scripts/ssr-base-element.js:53:43)
    at ComponentRenderer.componentHTML (/Users/user/Sites/base-class/scripts/server/component-renderer.js:68:47)
    at Function._replaceComponentTags (/Users/user/Sites/base-class/scripts/server/html-converter.js:135:52)
    at componentNames.forEach.componentName (/Users/user/Sites/base-class/scripts/server/html-converter.js:31:56)
    at Array.forEach (<anonymous>)
    at Promise (/Users/user/Sites/base-class/scripts/server/html-converter.js:30:28)
    at new Promise (<anonymous>)
    at HTMLConverter.exportHTML (/Users/user/Sites/base-class/scripts/server/html-converter.js:23:16)
    at app.get (/Users/user/Sites/base-class/index.js:37:19)
(node:32359) UnhandledPromiseRejectionWarning: ReferenceError: pagesDir is not defined
    at htmlConverter.exportHTML.then.catch.error (/Users/user/Sites/base-class/index.js:44:52)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:32359) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:32359) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

vulnerable package

added 583 packages from 304 contributors and audited 3848 packages in 14.612s
found 1 low severity vulnerability
  run `npm audit fix` to fix them, or `npm audit` for details

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.