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

shrekjs-framework

v1.0.6

Published

JavaScript framework

Downloads

6

Readme

ShrekJS

ShrekJS is a JavaScript framework for building front-end applications. It was created as a joke but was accidentally made into an actually usable framework. It features reactive bindings, updatable sections, conditional rendering, and others.

Disclaimer

This framework is merely a joke and an exercise. It is not meant to be used in production. It is not meant to be used at all. If you are using this framework for production, there is something wrong with you. Better use Vue or React.

This framework will make you use a whole lot of function nesting, which is bad for the environment. It teaches some bad practices, such as using CDN for everything, writing large inline scripts, and using global variables.

However, if you still would like to try it out, you can find the documentation below.

Table of Contents

Examples

All example assume that ShrekJS is installed through CDN.

Hello World

<script>
    put("Hello World!")
</script>

Nested Elements

<script>
    put(div([
        h(1, "Hi! This is a page heading"),
        tag("hr"),
        span([
            h(2, "This is a subheading"),
            p("This is a paragraph."),
            p("This is another paragraph.")
        ])
    ]))
</script>

Counter

<script>
    let count = new Bindable(0)
    put([
        span(["The counter is currently at ", count]),
        tag("br"),
        button("-", {}, () => count.value--),
        button("+", {}, () => count.value++)
    ])
</script>

Conditional Rendering

<script>
    let show = new Bindable(true)
    put([
        labeledInput("Toggle", "checkbox", {}, show),
        showIf(show, [
            h(1, "Hello World!"),
            p("This is a paragraph.")
        ])
    ])
</script>

Updatable

<script>
    list = new Bindable(['a', 'b', 'c'])
    put(updatable("for loop", () => {
        elements = []
        for (let letter of list.value) {
            elements.push([
                p(letter),
                button("Remove", {}, () => {
                    list.value = list.value.filter(l => l != letter)
                    update("for loop")
                    list.print()
                })
            ])
        }
        return elements
    }))
</script>

Reusable Component

// component.sh.js
makeComponent("myComponent", (args) => {
    return div([
        h1("My Component"),
        p(args.text)
    ])
})
<!-- index.html -->
<script src="component.sh.js"></script>
<script>
    put(
        div([
            component("myComponent", {text: "Hello World!"})
        ])
    )
</script>

Installation

ShrekJS is distributed as an npm package but only supported through CDN.

CDN

Add the following line to the <head> tag of your HTML file:

<script src="https://unpkg.com/shrekjs-framework/shrek.js"></script>

Getting Started

ShrekJS library consists of three parts: elements, bindings, and components. Elements are the basic building blocks of ShrekJS. They are the HTML elements that are rendered on the page. Bindings are the reactive data that is used to update the elements. Components are reusable pieces of code that can be used to create more complex elements.

If you install the library through CDN, you can start writing ShrekJS code right away in an inline <script> tag or in a separate .js file.

Elements

Every element in ShrekJS is a function that returns an HTML element.

You can put any element on the page by calling the following function:

put(slot)

slot - The content to be added to the root. Can be anything that will be a child of the root. For example, another element, a string, or a binding. If you would like to display multiple elements, you can pass an array of children of any type.

The default root element is the body element. You can change it with the following function:

shrek.setRoot(id)

id - The id of the element to be used as the root. Must be a string.

Basic Elements

ShrekJS comes with a few basic elements built in:

div(slot, arguments={})
span(slot, arguments={})
p(slot, arguments={})
h(num, slot, arguments={})
img(src, arguments={})
a(href, slot, inNewTab=false, arguments={})

They all create their respective HTML elements and return them.

Parameters:

slot - The content of the element. Can be anything that will be a child of the element. For example, another element, a string, or a binding. If you would like to nest multiple elements, you can pass an array of children of any type.

arguments - The attributes of the element. Can be anything that will be an attribute of the element. Must be an object.

num - The number of the header (e.g. 1 for h1). Must be a number.

src - The source of the image. Must be a string.

href - The link of the anchor. Must be a string.

inNewTab - Whether the link should open in a new tab. Must be a boolean. Defaults to false.

Input Elements

You can also create inputs with included functions

input(type, arguments={}, bindTo=undefined)

Creates an input element with the specified type. If bindTo is specified, the input value will be bound to the specified binding. arguments work the same as in the basic elements.

labeledInput(labelText, type, arguments={}, bindTo=undefined)

Creates an input element of a specified type with a preceding label. If bindTo is specified, the input value will be bound to the specified binding. arguments only apply to the input element. However, if id attribute is given, its value will also be applied to the label's for attribute. Otherwise, generated automatically.

button(slot, arguments={}, onclick=()=>{})

Creates a button element. If onclick is specified, it will be called when the button is clicked. arguments and slot work the same as in the basic elements.

button.link(slot, href, inNewTab=false, arguments={})

Creates a button element with an onclick function that redirects to the specified link. inNewTab, arguments, and slot work the same as in the basic elements.

Special Elements

ShrekJS also has a few special elements that are not standard HTML elements but are still useful.

center(slot, arguments={})

Centers nested elements on the page. Does not center the text inside. Creates a div element with margin: auto and width: fit-content in style. slot and arguments work the same as in the basic elements.

showIf(bindableCondition, slot)

Creates a div element that will only be rendered if the specified binding is truthy. Reacts to changes in the binding. slot works the same as in the basic elements.

updatable(name, slotFunction, initialArguments={})

Creates a div element that will be updated when the specified binding is updated. The contents of the element are determined by the slotFunction function. initialArguments are the arguments that will be passed to the slotFunction when the element is first rendered. name specifies the internal name of the updatable block. It must be unique.

Updatable can be updated with the following command:

update(name=undefined, arguments={})

If name is specified, the updatable block with the specified name will be updated. If name is not specified, all updatable blocks will be updated with given arguments. arguments are the arguments that will be passed to the slotFunction when the element is updated.

shrekPic()

Shrek.

Custom Elements

If you would like to create an html element that is not included in ShrekJS, you can do so with the following function:

tag(name, slot, arguments={})

Creates an element with the specified tag name. slot and arguments work the same as in the basic elements.

Bindings

Bindings are the reactive data connections that are used to update the elements on variable change and vice versa. In ShrekJS they are saved as a data type Bindable. They are created with the following constructor:

let myBindable = new Bindable(value=undefined)

value is the initial value of the binding and is optional. It can be of any type and defaults to undefined.

Reading-Writing Bindables

You can directly get and set the value of a binding with keyword value.

myBindable.value

value exposes the value of the binding through a custom property that allows you to interact with it as if it was a normal variable while keeping the binding reactive.

myBindable.value = 5
myBindable.value += 5
otherBindable.value = myBindable.value

For example, if you set a slot of some element to myBindable, the element will be updated when the value of myBindable changes.

The same goes for the other way around. If you set an input's bindTo to myBindable, the value of myBindable will be updated when the input's value changes.

Adding Observers

When you pass a Bindable to an element, the element generates an observer function that is saved into an observers list and is called when the value changes. You can also add your own custom observers to a Bindable to add custom behavior when the value changes. You can do so with the following method:

myBindable.subscribe(observer)

observer is a function that will be called when the value of the binding changes. It takes the new value as a parameter.

To print the value of a binding, you can use the following method:

myBindable.print()

Components

Components are reusable pieces of code that can be used to create more complex elements on your webpage.

Creating Components

Components are created with the following function:

makeComponent(name, componentFunction)

name is the name of the component. It must be unique. componentFunction is a function that returns an element. It takes the arguments of the component as parameters.

It is highly recommended to create each component in its own .sh.js file and load it as a script to the main html file.

Using Components

Components are used with the following function:

component(name, arguments={})

name is the name of the component. It must be the same as the name of the component that you want to use. arguments are the arguments that will be passed to the component function.