Giter VIP home page Giter VIP logo

component's Introduction

Note: This project is still in development. I would not call it stable just yet. If you wish to collaborate then feel free to reach out to me on twitter or just raise an issue and we can start from there.

Component

Component a javascript library to build stateful, reactive UI components. It can be used to build your entire web application or it can be used to build reusable UI components in your existing work.

Installation

Component works by using a babel plugin to convert the JSX you write into templates and functions. So you will need to install babel and babel-load. There is a working example project in this repository that uses webpack, babel and typescript.

Clone this repository and add it as a dependency to your npm project. You will also need to add babel dependencies becuase the JSX compiler is written as a babel plugin.

{
    "dependencies": {
        "component": "git+http://github.com/georgeshanti/component"
    },
    "devDependencies": {
        "babel-loader": "^9.1.2",
        "@babel/core": "^7.20.5"
    }
}
{
    "plugins": ["component/babel-plugin-component"]
}

Basic Usage

This section will show you only some of the concepts but to build a full web app you will need to go through a lot more of this for which I will setup a Getting Started guide soon.

Let's look at how we can build multiple components and compose them together. This will look very familiar if you're used to other reactive UI libraries.

import { Component, attach } from "component";

class HelloWorld extends Component<{name: string}>{
    count: number = 0;

    constructor(props: {name: string}){
        super(props);
    }

    click(){
        this.count++;
        this.rerender();
    }

    render(): any {
        return (
            <div>
                <p>Hello, {this.props.name}!</p>
                <p>Button has been clicked {count} times!</p>
                <button onClick={this.click.bind(this)}>Increment</button>
            </div>
        );
    };
}

class App extends Component<{}>{

    constructor(props: {[key: string]: any}){
        super(props);
        this.child = new Tree({});
    }

    render() {
        return (
            <div>
                This is our root app and we can place HTML elements like <b>'This bold text'</b> or this <input type="submit">Button</button><br/>
                We can even embed other components we built like HelloWorld
                <HelloWorld name="George Thomas Shanti"/>
            </div>
        );
    };
}

attach(document.getElementById("root")!, <App />);

export{};

Component does not use a special field to store state like in React. State of an object is normally just the values of its fields. So component takes this very simple approach, your components state is just whatever fields you add to them and instead of a setState() function there is just a renderElement() function that does what it says.

Extensibility

Use Component as just a library for reusable UI components

You can build any number of UI elements and compose them together to make large components and extract the root HTML elements of these components. This allows you to use these build these components and take it's root HTML element an place them in your place. Let's look at how you can do that.

let app: App = new App();

/* This will render the component into an HTML element */
app.renderElement();

/* This will return the HTML Element associated with the component */
let htmlElement: HTMLElement = app.getDomElement();

/* And now we can place this component anywhere we want in the page */
document.getElementById("root").appendChild(htmlElement);

Use other libraries within Component

You can also embed any HTML Element you want into a component and not have to worry about Component's system interfering with it. So you can use any other library you want as long as it acts only on it's given HTML Element and it's children and not it's parent elements, that will obviously cause problems with the Component you embed it in. This is achieved by using the SubElement component

import { Component, Sub } from "component";

class OtherLibrary extends Component<{}>{
    let otherLibraryElement: HTMLElement;

    constructor(props: {}){
        super(props);

        /* If it needs just the HTML Element */
        otherLibraryElement = document.createElement('div');
        OtherLibraryFunction(otherLibraryElement);
        
        /* If it needs an HTML Element with a specific id or something */
        otherLibraryElement = document.createElement('div');
        otherLibraryElement.setAttribute('id', 'otherLibraryId')
        OtherLibraryFunction.init();
    }

    render(): any {
        return (
            <div>
                <p>This component uses some other library as well</div>
                <SubElement child={this.otherLibraryElement} />
            </div>
        );
    };
}

Combine both aspects ๐Ÿ‘€

If you think about it a little then you'll realise that you can move Components around the HTML tree while still preserving it's state. There's another component specifically made for this, SubComponent.

import { Component, Sub } from "component";

class App extends Component<{}>{
    let helloWorld: HelloWorld;
    let position: boolean = true;

    constructor(props: {}){
        super(props);
        
        helloWorld = new HelloWorld({name: 'George Thomas Shanti'});
    }

    click(){
        this.position = !this.position;
        this.renderElement();
    }

    render(): any {
        return (
            <div>
                {this.position?<SubComponent child={this.helloWorld}/>:null}
                <Button onClick={this.click.bind(this)} />
                {!this.position?<SubComponent child={this.helloWorld}/>:null}
            </div>
        );
    };
}

Clicking the button will move the HelloWorld component between being before and after the button. Any state you choose to store in HelloWorld component will be preserved.

Some things to figure out

  • Still need to make the output code less verbose which I will do in the coming weeks.
  • Figuring out better lifecycle methods. It's still pretty crude at the moment.
  • Completing the list html elements the parser recognises and a better way to define the accepatble attributes for each one.

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.