DEV Community

Cover image for Todo App Using A New Web Component Framework
Harsh Singh
Harsh Singh

Posted on

Todo App Using A New Web Component Framework

A Demo App Made Using Tatva.js. Tatva is Web Component Framework that requires no build step. It uses a tiny implementation of Virtual Dom.

How is it different from Stencil.js?

  • No build step required. load the framework directly from CDN.
  • Does not uses JSX. Instead uses Hyperscript functions.
  • Does not uses non-standard decorators. Write Web Components in Pure Javascript.

Similarities with other frameworks

  • Uses Lifecycle events similar to React, but in Web Component-ish way. instead of componentDidMount and componentDidUnmount, use componentDidConnect and componentDidDisconnect.
  • Uses Virtual DOM
  • State Management is similar to React Class Components
  • Minimal PropTypes implementation for automatically converting attributes that are set on the component.

Unique features

  • Tatva utilizes the Web Component API for handling props and Lifecycle events, instead of implementing its own. it just combines Virtual DOM with the already existing Web Component API.
  • If you want to update the component when an attribute changes, just put the attribute name in the observedAttributes list.

Todo App Demo

import { Component, h, text } from "https://unpkg.com/tatva@latest";

class TodoApp extends Component {

    state = {
        todo: '',
        todos: []
    }

    setTodo(e) {
        this.setState(state => ({
            ...state,
            todo: e.target.value
        }))
    }

    addTodo(id, todo) {
        this.setState(state => ({ 
            ...state, 
            todos: [...this.state.todos, { id, todo }],
            todo: ''
        }))
    }

    removeTodo(todoId) {
        this.setState(state => ({
            ...state,
            todos: this.state.todos.filter(({ id }) => id !== todoId)
        }));
    }

    handleFormSubmit(e) {
        e.preventDefault();

        this.addTodo(crypto.randomUUID(), this.state.todo);
    }

    render() {
        return (
            h('main', {},
                h('form', { onsubmit: e => this.handleFormSubmit(e) },
                    h('input', {
                        oninput: e => this.setTodo(e),
                        placeholder: 'Enter Todo',
                        value: this.state.todo
                    })
                ),
                !this.state.todos.length
                    ? h('p', {}, text('No Todos.'))
                    : h('ul', {},
                        ...this.state.todos.map(({ id, todo }) => 
                            h('li', { key: id },
                                text(todo),
                                h('button', 
                                    { onclick: () => this.removeTodo(id) }, 
                                    text('Remove')
                                )
                            )
                        )
                    )
            )
        )
    }

}

customElements.define('todo-app', TodoApp);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)