Skip to content

ndugger/cortex

Repository files navigation

cortex

Lightweight Web Component Framework

Cortex is a thin layer on top of "native" web components. It manages state differentiation, and enables orchestration though various lifecycle hooks.

The primary purpose is to enable the construction of progressive web applications through familiar abstraction. React was a very large source of inspiration for coming up with the library's feature set, but watch out; some concepts named similarly in both libraries work fundamentally differently, though the purpose is identical.

See how to enable JSX below.

npm install github:ndugger/cortex --save

Documentation

 


 

Example

import { Component, Element, createElement } from 'cortex'

class Example extends Component {

    private handleClick(event: Event): void {
        alert('button was clicked!')
    }

    public render(): Element.Child[] {
        return [
            <HTMLButtonElement onclick={ event => this.handleClick(event) }>
                <HTMLSlotElement/>
            </HTMLButtonElement>
        ]
    }

    public theme(): string {
        return [
            `.${ HTMLButtonElement.name } {
                background: blue;
                color: white;
            }`
        ]
    }
}

document.body.append(new Example())

 


 

Explanation

"Native" web components are class-based. You need to extend the base class HTMLElement in order for it to be compatible with the DOM.

The Component class acts as proxy to the HTMLElement class that also automatically registers the custom element, and adds lifecycle capabilities.

import { Component, Element, createElement } from 'cortex'

export class Example extends Component {}

There are two protected methods that you can/should override: render & theme. The render method returns an array of Element.Childs (which is a virtual representation of that component's layout). The theme method returns a string containing the CSS for that component.

export class Example extends Component {
    
    protected render(): Element.Child[] {
        return []
    }

    protected theme(): Component.Style[] {
        return []
    }
}

Since cortex uses shadow DOM under the hood, not only is your CSS properly scoped to the component, but you can also make use of slot-based content. Instead of accessing children through a property of that component, simply render an HTMLSlotElement and watch as the DOM automatically inserts your content within.

<HTMLButtonElement>
    <HTMLSlotElement/>
</HTMLButtonElement>

 


 

JSX Support

Cortex also supports JSX within the render method so you can markup your components very similarly to React.

public render(): Element.Child[] {
    return [
        <HTMLButtonElement/>
    ]
}

In order to enable JSX for cotex, you must add the following to your TypeScript compiler options:

{
    "compilerOptions": {
        "jsx": "react",
        "jsxFactory": "createElement"
    }
}

Make sure to always import createElement from cortex at the top of your modules.

import { createElement } from 'cortex'

 

Important! Cortex does not support "intrinsic elements", meaning that you must always pass a class (or function) to the JSX factory; no "literals" allowed, like div, button, a, etc (ex: <HTMLButtonElement/>).

 

If there is no standalone class for an element (like section, header, etc.), you may use <HTMLElement is='section'/>.

Because you must always pass in a class, cortex makes some opinionated decisions when it comes to certain things, like with CSS classes. Cortex will automatically apply a className that is equal to the class' name that you passed in for the element.

This means that <HTMLButtonElement/> becomes <button class='HTMLButtonElement'/> in the DOM.

This also contributes to styling your components, because you can now target your elements via their actual class name.

public theme(): Cortex.Element[] {
    return [
        `.${ HTMLButtonElement.name } {
            ...
        }`
    ]
}

 


 

SVG Support

WIP... had this working at one point, will revist in near future