Component oriented framework with Virtual dom (fast, stable, with tooling)

Overview

Bobril Logo Bobril

Main site bobril.com

npm version

Changelog of npm version: https://github.com/Bobris/Bobril/blob/master/CHANGELOG.md

Component oriented framework inspired by ReactJs (Virtual DOM, components with state) and Mithril (small size, more complete framework). Compared to ReactJS Added speeeed, autoprefixer, CSS in JS, router, additional livecycle methods, only rAF based repaint. Bobril ignores Isomorphic JavaScript, because it would increase size and is not needed for SEO anyway (Google bot supports JavaScript). Client applications are expected to be written in TypeScript. Because it is heavily used in production, backward compatibility is king. Any new feature must be optional or its perceived value to minified size ratio must be high enough.

It is intended to be used with bobril-build.

Old Examples: http://bobris.github.io/Bobril/

For modern code look at Bobril Material: https://github.com/Bobril/Bobril-m

Tutorial videos [cz][en sub]:

Bobril tutorial

See it in vdom-benchmarks: http://vdom-benchmark.github.io/vdom-benchmark/

Chrome plugin to help you to inspect running Bobril application: https://chrome.google.com/webstore/detail/clouseau/npfemnefhbkiahihigplihehpbgkbhbj (Github source for it is here: https://github.com/klesta490/bobril-clouseau)

Features:

  • Small - whole sample applications fits into 17kb gzipped.
  • No additional dependencies
  • Fast Virtual DOM diffing
  • Interesting component lifecycle callbacks
  • Components remember state in VDom cache
  • Components does not need to be HTML Elements - where is component(0-1) to HTMLNode(0-n) mapping
  • Support for partial invalidates for even faster redraws
  • Normalization of Events
  • support for IE11 and evergreen browsers
  • batching of redrawing
  • any html element could be root
  • automatic passing of global configuration/context to children
  • automatic adding of "px" to length like inline style
  • reference to children nodes ala React
  • style as function which behaves like mini component with its own context
  • OnChange event and value attribute normalization
  • Key events
  • Mouse, Touch Events
  • SVG helpers
  • Router inspired by https://github.com/rackt/react-router/
  • Media detection
  • Focus, Blur, FocusIn, FocusOut events
  • Transparently add vendor prefixes for inline styles
  • Asap (setImmediate) and Promise A+ polyfill - simplified https://github.com/taylorhakes/setAsap and https://github.com/taylorhakes/promise-polyfill
  • Scroll notification
  • Drag and Drop - uses browser one except on IE11, multi touch, allows animating drag, state of the art as usual
  • Style - create css dynamically for even faster speed, allow recomputing styles for theming
  • PNG Sprites with dynamic change of color

Optional addins - separate npm modules:

bobril-g11n

  • Globalization - behind uses moment.js, bobril-build extracts texts for localization from TypeScript source.

bobx

  • Mobx like state management with deep integration with Bobril.

bobflux

  • Flux implementation for Bobril (Though BobX is preferred way)

bobril-m-icons

  • Bobril Material Icons

Whole simple applications including Bobril could fit into 17kb gzipped. Bobril-build does dead-code elimination and module flattening.

Uses NodeJs, NPM, TypeScript, Jasmine

MIT Licensed

How to develop

Install npm i bobril-build -g.

And then just start bb (bobril-build).

For helping writing TypeScript you can use VSCode.

If you want to work on something create bug with description, so work is not duplicated.

Comments
  • Type Timer not assignable to type Number

    Type Timer not assignable to type Number

    After recently starting a new project with Bobril (within the last 30 minutes), I am getting the the above error against this line of code:

    https://github.com/Bobris/Bobril/blob/7bce04dda6afb570b1a57afc6fe905b00fe607fb/package/index.ts#L4233

    After fishing around for a bit, waitingForPopHashChange is a numeric where setTimeout is a timer. Is this a legit error or something perhaps I messed up when installing the project?

    opened by braidn 11
  • Update documentation

    Update documentation

    Hello,

    I use Bobril for the first time and I'm looking for documentation. You soon a complete documentation ?

    • Into the videohe use b.createComponent(...) but I dont find this method!

    Thank you.

    opened by Gouigouix 9
  • First onChange event on select box

    First onChange event on select box

    Hello,

    I have implemented a select box this way :

        const cePaxSelect = b.createComponent({
            render(ctx: IBobrilCtx, me: IBobrilNode) {
                me.tag = "select";
                me.className = "natural-select";
                me.children = this.createOptions(ctx.data);
            },
            onChange(ctx: IBobrilCtx, value: string) {
                // process value here ...
                b.invalidate();
            },
            createOptions(model: IBookingModel): IBobrilChildren {
            ...
    

    The issue occured when we click on the select box, there is an onChange event that is launched, so, the first value in the list is selected. When a element is selected, I need to update the values inside this select box, but it create the issue of the click again. This does not appear on your exemple : http://bobris.github.io/Bobril/input/index.html

    I have tried to create a event component to handle the onChange event inside it :

                me.component = {
                    onChange(ctx: IBobrilCtx, value: string) {
                        console.log("select change : " + value);
                    }
                };
    

    but nothing occured.

    thank you.

    opened by ghost 8
  • Validation on firstFocus

    Validation on firstFocus

    i create a textbox input and the validation work only on:

    • Submit
    • Always

    and i want with first focus

     <reference path='../../Libraries/bobril/library.d.ts'/>
    
      <reference path='../../Libraries/dc-helpers/library.ts'/>
     <reference path='../../Libraries/bobril-onchange/library.d.ts'/>
     <reference path='../../Libraries/validation/library.ts'/>
      <reference path="../../Libraries/bobril-focus/library.d.ts"/>
    

    declare let textboxStyle: IBobrilStyleDef; declare let textboxInvalidStyle: IBobrilStyleDef; declare let labelStyle: IBobrilStyleDef;

    const enum TextboxType { TEXT = "text", PASSWORD = "password", SEARCH = "search" }

    const enum Autocapitalize { NONE = "none", SENTENCES = "sentences", WORDS = "words", CHARACTERS = "characters" }

    interface IData { datactx: IDataCtx; id: string; placeholder: string; type: TextboxType; maxlength: number; autocapitalize: Autocapitalize; }

    interface ICtx extends IBobrilCtx { data: IData; firstFocus: boolean; }

    interface IDataCtx { setValue(value: string): void; getValue(): string; } let applyInvalidStyle: boolean = true; const divComponent: IBobrilComponent = {

    id: "DivComponent",
    init(ctx: ICtx, me: IBobrilCacheNode): void {
        initValidatedInput(ctx, me, "Value");
    },
    render(ctx: ICtx, me: IBobrilNode): void {
        me.tag = 'div';
        applyInvalidStyle = !isValid(ctx)
            && ctx.cfg
            && ctx.cfg.shouldShowValidation(ctx);
        me.children = [createInputComponent(ctx), b.style!({ tag: 'label', children: ctx.data.placeholder, attrs: { for: ctx.data.id } }, labelStyle)]
    },
    onChange(ctx: ICtx, value: string): void {
        ctx.data.datactx.setValue(value);
    },
    onBlur(ctx: ICtx): void {
        if (!ctx.firstFocus) {
            ctx.firstFocus = true;
            b.invalidate();
        }
    }
    

    }; function createInputComponent(ctx: ICtx): IBobrilNode { return { data: ctx.data, component: inputTextComponent } } const inputTextComponent: IBobrilComponent = { id: "TextBoxComponent",

    render(ctx: ICtx, me: IBobrilNode): void {
        const d = ctx.data;
        me.tag = "input";
        me.attrs = b.assign(
            me.attrs || {}, {
            id: d.id,
            name: d.id,
            placeholder: ' ',
            value: d.datactx.getValue(),
            maxlength: d.maxlength
        },
            getReadOnlyStatus(ctx) ? { readonly: true } : {}
        );
    
        b.style!(me, textboxStyle, applyInvalidStyle && textboxInvalidStyle)
    },
    onChange(ctx: ICtx, value: string): void {
        if (!ctx.firstFocus) {
            ctx.firstFocus = true;
            b.invalidate();
        }
        ctx.data.datactx.setValue(value);
    },
    onBlur(ctx: ICtx): void {
        if (!ctx.firstFocus) {
            ctx.firstFocus = true;
            b.invalidate();
        }
    }
    

    } var getID = (): string => { return Math.random().toString(36).substr(2, 9); } export function textBoxFactory( type: TextboxType, placeholder: string, maxLength: number, autocapitalize: Autocapitalize, dataCtx: IDataCtx ): IBobrilNode { const ID = getID(); return { data: { placeholder, type, id: ID, maxlength: maxLength >= 0 ? maxLength : null, autocapitalize, datactx: dataCtx }, component: divComponent }; }

    opened by YossiBenZaken 6
  • If possible, make building without bobril-build possible.

    If possible, make building without bobril-build possible.

    At the moment, the bobril NPM package doesn't contain compiled output. It only contains index.ts. What is worse is that the package.json references main: 'index.js' which doesn't exist in the package (I'm surprised NPM let you publish like this).

    If it is possible, it would be nice to be able to use this without having to use the custom tooling. I believe at the least this requires publishing NPM packages with pre-compiled index.js (this may require other changes as well, not sure).

    opened by MicahZoltu 6
  • clear NodeArray and Node setters when routes length is changed

    clear NodeArray and Node setters when routes length is changed

    Current state:

    • All node setters are filled with max ID depends on routes count (all nodes are set to the same array field)
    • only last item of this array are actually used.

    Problem description:

    • When count of routes is decreased, node setters are still set to previous max ID
      • It means that this ID of nodeArray is not used bcs of clear -> canDeactivate is not called
    • When count of routes is increased, node setters are changed just for few new higher setters
      • It means that there is posibility to have obsolete node in nodeArray -> canDeactivate is called even if node is not rendered

    Solution:

    • Reset nodeArray and node setters when count of routes is changed
    • Thanks to this, nodeArray will have only last route item every time, so just the last canDeactivate will be called.

    Solution to the future:

    • Should be nodeArray filled with all nodes used in routes?
      • Then canDeactivate can be called for all routes which are deactivated
      • We need to know future routes before first iteration of routing is called.
      • We need to keep nodeArray updated all the time.
    opened by Petaniss 6
  • Isomorphic capabilities?

    Isomorphic capabilities?

    First I want to say, great work on Bobril, it's something I've been utilising for a framework I'm currently designing.

    The only lacking feature I see is isomorphic support for NodeJS? So, like React, components can be rendered on the server and, upon the client loading the rendered output, initialise from the pre-rendered DOM. React makes use of data-reactid to link up the nodes to their respective virtual dom counterparts, so I'd imagine something similar could be applied to Bobril.

    I believe this a key feature that would certainly add massively to Bobril and its uptake in the community.

    opened by trueadm 6
  • Error: Module bobril in src/index not registered

    Error: Module bobril in src/index not registered

    Hi, I have an issue with loader of nodejs modules. I have created a sandbox project to visualize the problem The problem occurs, when I import typescript file, that is not in the hiearchy of the project directories.

    The project structure: image

    There are two projects. The one is located in src and the second in otherProject. Each of this projects has own package.json.

    I want to import an utils.ts class in src project.

    If I run bb command in src project, than bobril sources in the browser looks like: image

    The problem is, that the loader wants to load the module bobril through the key: "node_modules/bobril/index" From this map: image It will fall to this exception: image

    So, in the chrome browser console this exception occured:

    Uncaught Error: Module bobril in src/index not registered
        at Function.R.r (loader.js:27)
        at loader.js:31
        at index.ts:1
        at Function.R.r (loader.js:31)
        at (index):16
    

    I need this, to create a sandbox (example) project, to test the core functionality of another project.

    Sandbox code to see the error: bobril-issue-sandbox.zip

    Any idea?

    Thanks :)

    opened by Xrew 2
  • OptGroup label not handled by IBobrilAttributes

    OptGroup label not handled by IBobrilAttributes

    I need to use optGroups in Selects but the label attribute is not rendered... How could I do it? thank you !

    fact is it's perfecty working... sorry for that

    opened by julienCarr 2
  • Examples updated to be compilable by tsc 2.1, added small script to d…

    Examples updated to be compilable by tsc 2.1, added small script to d…

    tsc 2.1.5 used tsc is called in script without creating source maps (no sourceMappingURL is in js now) Commited only changed js from folders when was done some change.

    opened by karasek 2
  • How to convert mouse click page position to element position?

    How to convert mouse click page position to element position?

    IBobrilMouseEvent contains page positions x and y. I need element postion.

    My current solution:

    const position = b.convertPointFromPageToNode(ctx.me, x, y);
    const scroll = b.getWindowScroll();
    let cell = ctx.cellPositonConverter.getCellFromPositon(position[0] + scroll[0], position[1] + scroll[1]);
    

    Is there any better way to convert it to element position with scroll support?

    THX Pepa

    opened by JosefBackovsky 2
Owner
Boris Letocha
Whole life developer, architect
Boris Letocha
A Fast & Light Virtual DOM Alternative

hyper(HTML) ?? Community Announcement Please ask questions in the dedicated discussions repository, to help the community around this project grow ♥ A

Andrea Giammarchi 3k Dec 30, 2022
Million is a lightweight (<1kb) Virtual DOM. It's really fast and makes it easy to create user interfaces.

?? Watch Video ?? Read the docs ?? Join our Discord What is Million? Million is a lightweight (<1kb) Virtual DOM. It's really fast and makes it easy t

Derek Jones 5 Aug 24, 2022
Turn any dynamic website (especially wordpress) into a fast, secure, stable static site

Static site publisher Turn any dynamic website (especially wordpress) into a fast, secure, stable static site Reduced complexity - no need to run simp

Alex Ivkin 7 Apr 6, 2022
Framework for HTML5 Canvas oriented 2D video games

Canvas Engine http://canvasengine.net Description Framework to create video games in HTML5 Canvas Get Started Follow the steps below to start: Downloa

Samuel Ronce 378 Dec 2, 2022
minimalist virtual dom library

petit-dom A minimalist virtual DOM library. Supports HTML & SVG elements. Supports Render functions and Fragments. Custom components allows to build y

Yassine Elouafi 485 Dec 12, 2022
Pure and simple virtual DOM library

Maquette Maquette is a Javascript utility which makes it easy to synchronize the DOM tree in the browser with your data. It uses a technique called 'V

AFAS Software 736 Jan 4, 2023
Builds components using a simple and explicit API around virtual-dom

Etch is a library for writing HTML-based user interface components that provides the convenience of a virtual DOM, while at the same time striving to

Atom 553 Dec 15, 2022
Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom.

Atomico simplifies learning, workflow and maintenance when creating webcomponents. Scalable and reusable interfaces: with Atomico the code is simpler

Atomico 898 Dec 31, 2022
Intelligent Tailwind CSS tooling for coc.nvim

coc-tailwindcss3 fork from a vscode-tailwindcss Intelligent Tailwind CSS tooling for coc.nvim. Motivation There are two coc.nvim extensions to "tailwi

yaegassy 110 Jan 1, 2023
A Typescript Hardhat-based template to develop evm-based smart contracts with all the tooling you need.

EVM-based Smart Contract Scaffold A Typescript Hardhat-based template to develop evm-based smart contracts with all the tooling you need. Features Use

Flair 8 Oct 24, 2022
Official moon configurations for popular JavaScript developer tooling.

moon development configs This repository is a collection of moon owned and maintained configurations and presets for common developer tools -- primari

moonrepo 8 Nov 10, 2022
Connect Web Integration illustrates the integration of Connect-Web in various JS frameworks and tooling

Connect Web Integration Connect Web Integration is a repository of example projects using Connect-Web with various JS frameworks and tooling. It provi

Buf 43 Dec 29, 2022
An NPM package to help you get started with modern javascript tooling easier & faster

MODERNIZE.JS Creating config files for webpack and babel can be an hell of stress, this NPM package helps you get started with writing code as soon as

Kelechi Okoronkwo 5 Sep 22, 2022
Custom Vitest matchers to test the state of the DOM, forked from jest-dom.

vitest-dom Custom Vitest matchers to test the state of the DOM This library is a fork of @testing-library/jest-dom. It shares that library's implement

Chance Strickland 14 Dec 16, 2022
An extension of DOM-testing-library to provide hooks into the shadow dom

Why? Currently, DOM-testing-library does not support checking shadow roots for elements. This can be troublesome when you're looking for something wit

Konnor Rogers 28 Dec 13, 2022
women who code - object oriented programming exercise

Table of contents General info Technologies Setup General info Authorizer APP Technologies Project is created with: Typescript: 4.2 Setup Requirements

null 3 Oct 1, 2022
Serialization library for data-oriented design structures in JavaScript

Data-oriented Serialization for SoA/AoA A zero-dependency serialization library for data-oriented design structures like SoA (Structure of Arrays) and

null 11 Sep 27, 2022
A complete guide for learning Object Oriented Programming Pillars, SOLID Principles and Design Patterns with TypeScript!

Object Oriented Programming Expert With TypeScript This repository is a complete guide and tutorial for the principles and techniques of object-orient

Ahmad Jafari 44 Dec 29, 2022
CloudSecWiki is a cloud security oriented knowledge base maintained by HuoCorp.

CloudSecWiki CloudSecWiki is a cloud security oriented knowledge base maintained by HuoCorp. CloudSecWiki web address:cloudsec.huoxian.cn Local Deploy

HuoCorp 26 Dec 4, 2022