Code Monkey home page Code Monkey logo

riot's Introduction

Riot logo

Simple and elegant component-based UI library

Build Status MIT License Join the discord community channel Join the chat (ja) at https://riot-jp-slackin.herokuapp.com/ OpenCollective Backers OpenCollective Sponsors

NPM version NPM downloads jsDelivr Hits Coverage Status Riot Size Code Quality

Sauce Test Status

Custom components • Concise syntax • Simple API • Tiny Size

Riot brings custom components to all modern browsers. It is designed to offer you everything you wished the native web components API provided.

Tag definition

<timer>
  <p>Seconds Elapsed: { state.time }</p>

  <script>
    export default {
      tick() {
        this.update({ time: ++this.state.time })
      },
      onBeforeMount(props) {
        // create the component initial state
        this.state = {
          time: props.start,
        }

        this.timer = setInterval(this.tick, 1000)
      },
      onUnmounted() {
        clearInterval(this.timer)
      },
    }
  </script>
</timer>

Open this example on Plunker

Mounting

// mount the timer with its initial props
riot.mount('timer', { start: 0 })

Nesting

Custom components let you build complex views with HTML.

<timetable>
  <timer start="0"></timer>
  <timer start="10"></timer>
  <timer start="20"></timer>
</timetable>

HTML syntax is the de facto language on the web and it's designed for building user interfaces. The syntax is explicit, nesting is inherent to the language and attributes offer a clean way to provide options for custom tags.

Performant and predictable

  • Absolutely the smallest possible amount of DOM updates and reflows.
  • Fast expressions bindings instead of virtual DOM memory performance issues and drawbacks.
  • One way data flow: updates and unmounts are propagated downwards from parent to children.
  • No "magic" or "smart" reactive properties or hooks
  • Expressions are pre-compiled and cached for high performance.
  • Lifecycle methods for more control.

Close to standards

  • No proprietary event system.
  • Future proof thanks to the javascript module syntax.
  • The rendered DOM can be freely manipulated with other tools.
  • No extra HTML root elements, data- attributes or fancy custom attributes.
  • No new syntax to learn.
  • Plays well with any frontend framework.

Use your dearest language and tools

Powerful and modular ecosystem

The Riot.js ecosystem is completely modular, it's designed to let you pick only the stuff you really need:

CDN hosting

How to contribute

If you are reading this it's already a good sign and I am thankful for it! I try my best working as much as I can on riot but your help is always appreciated.

If you want to contribute to riot helping the project maintenance please check first the list of open issues to understand whether there is a task where you could help.

Riot is mainly developed on UNIX systems so you will be able to run all the commands necessary to build and test the library using our Makefile. If you are on a Microsoft machine it could be harder to set up your development environment properly.

Following the steps below you should be able to properly submit your patch to the project

1) Clone the repo and browse to the riot folder

$ git clone [email protected]:riot/riot.git && cd riot

2) Set up your git branch

$ git checkout -b feature/my-awesome-patch

3) Install the npm dependencies

$ npm i

4) Build and test riot using the Makefile

# To build and test riot
$ make riot

# To build without testing
$ make raw

5) Pull request only against the dev branch making sure you have read our pull request template

6) Be patient

Credits

Riot is actively maintained with ❤️ by:


Gianluca Guarini

Many thanks to all smart people from all over the world who helped improving it.

Official Website

https://riot.js.org

Backers

Support us with a monthly donation and help us continue our activities. Become a backer

Backers

Sponsors

Become a sponsor to get your logo on our README. Become a sponsor

Sponsors

Thanks

Special thanks to Browserstack and JetBrains for their support

jetbrains browser stack

riot's People

Contributors

3den avatar 5angel avatar a-moses avatar amarcruz avatar andreasheintze avatar andynemzek avatar andyvanee avatar antonheryanto avatar ashbrener avatar aurri avatar avnerus avatar cognitom avatar crisward avatar emehrkay avatar gianlucaguarini avatar gpoitch avatar gregorypratt avatar karak avatar marciojcoelho avatar nippur72 avatar pakastin avatar r4j4h avatar rogueg avatar rsbondi avatar shime avatar speier avatar tipiirai avatar txchen avatar vitogit avatar wellguimaraes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

riot's Issues

Avoid observable circular references

This is no big deal, but I noticed that $.observable misses a way to break circular events, something that I think is important in every Observable/Emitter implementation is sometimes useful to tie two observables together.

This is the failing test:

it("does not call trigger infinitely", function() {
    var counter = 0,
      otherEl = $.observable({});

    el.on("update", function(value) {
      if (counter++ < 1) { // 2 calls are enough to know the test failed
        otherEl.trigger("update", value);
      }
    });

    otherEl.on("update", function(value) {
      el.trigger("update", value);
    });

    el.trigger("update", "foo");

    assert.equal(1, counter);
  });

The usual way to fix this is to add a flag (i.e triggering) that controls that no event gets triggered twice in the same cycle.

Let me know if you actually want this implemented or you want to leave it as-is.

off() cannot remove specific event handlers

function listener() { alert(1); }
var obj = {};
$.observable(obj);

obj.on('boo', listener);
obj.off('boo', listener);
obj.emit('boo'); // should not alert

Even though listener is passed into obj.on, jq.on receives an anonymous function. This makes it impossible for jq.off to match listener.

How best way to convert a JQuery component?

This fantastic project! Simplicity reigns.

How am coming architecture Jade + Expressjs'm a little confused on what is the best way to convert my compomentes JQuery for Riot, since the View is responsible for receiving user events.

Please ideas and explanations.

Thank you

Inheritance with the prototype chain

Can you remake riot.js for inheritance with the prototype chain?
I just want to do:

var MyClass = function () {};
MyClass.prototype = Object.Create($.prototype);
var myModule = new MyClass();
myModule.on('created', function() { alert('My Module is created!') });
myModule.trigger('created');

Removing event listener during triggering compromises callbacks

If you remove yourself as listener from an object when you are being called due to a triggering, the callback array will be altered resulting in the next callback being skipped.

This can result in very confusing bugs, which it did for me.

I realize that accomodating this scenario correctly may have performance downsides. For example, if you set a flag on callbacks to be removed, and remove them after, it is obviously going to be slower in the average case. Maybe there is a performant way?

If not, maybe there is a way to raise an exception or assume some form of error state if an event listener is removed during the looping over callbacks?

I would much prefer to crash and burn in this scenario, than to have the next event listener silently not being called, resulting in very subtle bugs.

Otherwise I'm enjoying the simplicity, elegance and speed of Riot. :)

nested object rendering

Hi.
I found it as tough constraint that I can't pass nested objects into the riot template renderer.
Consider a simple two levels of nested object such as the following model object ("data" is just for initialization from store for example):

function Items(data) {
this.name = data.name;
this.price = data.price;
this.details = { 'id': data.details.id, 'image': data.details.image }
...
}

When tested with a template, only the flat properties (such as name and price) would work for me, but the nested ones like so: details.id - would not.
when I looked at the renderer function (regex) I realized it won't work since it does not expect a dot nor a key['name'] format.

Thoughts?
Must I use only Flat properties in model? in other frameworks of-course it is possible.
I don't think it would break the constraint mentioned in Riot blog about the architecture of flat templates to have nested variables. it is not adding any logic

TIA
Tomer

render for restricted Content Security Policy like chrome apps

any solution for riot.render for environment where uses of eval() and eval-like constructs such as new Function() restricted as previously requested in #45 and i have uses it temporary for render function

var regEx = /\{\s*(\w+)\s*\}/g;
riot.render = function(template, data) {
  return typeof data === 'object' && typeof template === 'string' && 
    template.replace(regEx, function(tag, match) { return data[match] || ''; });
};

but this very minimum and not support x.y.z object access

Muutools typo

Note that Riot is not dependent on jQuery. You can use other DOM libraries too such as DOJO or Muutools or you can go with Facebook React.

https://muut.com/riotjs/docs/

Should it be "Mootools" instead?

Urls without #hash

Is it possible to have urls like:
domain.com/users?

I tried to read all of your documentations, but didnt find nothing about this

$.render - Consider using not using an eval type function creation, not needed.

The render code uses new Function("_", "function body as string") but this really is not needed. Moreover this is approach requires sandboxing in new Chrome editions or where the security settings are turned up.

This may not make sense if you intend to do the following

  1. You want to support Javascript injection like John Resig's examples, although your general examples and code to date does not indicate so. His example mixes JS and HTML like jsp/asp.
  2. You will add extremely complex syntax in the future ala Handlebars, which would seem to go against the manifesto. "Riot views are as dummy as possible. No conditional statements, loops, or data binding. No custom attributes or custom elements."
  3. Support server-side template pre-compilation AND you can show a huge performance benefit.

So, then why not pre-process the template in a closure and then create a new function which is statically defined, not evaluated string, that does the string matching and replacing.

People may point out and say hey this could be slower, not really. You don't have to do all the line replaces then because the text is never going to be javascript code. Save time there. You can define the regex within the closure and then it will not need to be created every template evaluation, save time there. eval is not even that fast to being with. It works across more browsers. You could add features to strip out script tags providing security beyond what other templating engines offer. It is dead easy and simple for developers to understand.

Also if we are really looking for time savings do not use the entire TEMPLATE text as the property name. That is one large string compare for no good reason. It requires a little extra code, and an API change to provide a name. However, for larger programs I do not watch to pass the entire template around anyhow. I want to pass the template by reference, and best case I then just wrap this with a name lookup based one and store the templates twice in JS.

I have worked up some stub code this morning, https://github.com/TedMN/riotjs/blob/master/ext/render.js . My style is slightly different but the concepts referenced above are sudo implemented, I have not even run it. However, I have written stuff like this before. Finally, you could also expose the templating function as a generic string replace function. It can be super handy with urls etc. For one app we had config attributes for AJAX urls as they were complex and changed by env. So for example: www.example.com/{1}/{2}?support={3}, but you could also do www.example.com/{entity}/{id}?support={isSupportMode}.

Finally, I do think there is an enhancement to some how use jQuery's looping and set based processing to do looping, bulk processing and conditionals on your template processing. With riot's objective of leveraging jQuery it might be interesting to capitalized on that in a clean, minimalist, way.

jQuery load is deprecated plus other opportunities, need context to fix.

I have forked the riotjs project today and attempted to help increase minification, optimize, reduce, etc. I have the code sitting: https://github.com/TedMN/riotjs/blob/master/jquery.riot.js

However, before I create a pull request I want to address the jQuery.load with timeout part of the code. I am sure I can find a way around it and make it more compact as well. However, can anyone provide me with the context?
Ideas:

  1. document ready
  2. use jquery one event binding to avoid boolean variable
  3. understand event flow to avoid timeout since all it does is wait effectively no time. This means it really is waiting for some thing it cannot track that well. What is it?

I have also commented smaller pushes to my fork around variables to help with minification, moving variables up in the process, and putting the initialization/load at the bottom after things are defined.

How do you write riot.js extensions á la jQuery?

How do you write riot.js extensions á la jQuery?
There is no information on your blog on howto add functionality to riot.js. Is that your intention, I mean do you encourage people to write general javascript libraries instead of creating a community around riot.js? I hope your share this information on your blog too, I'm sure that more people than just me are interested in this.

Official Release

https://moot.it/riotjs/ in the bottom says:
Official Release (v1.0) February 2014
:)))

now it is the end of the march :)

btw, thanks for riot.js! the best thing i saw. i'm using it (v0.98) in my projects. thank you!

project coded with riotjs

Hi,
I created this mini project multip-table using your framework with the target of reducing the total weight of the project. And the result was so good that the whole project ended up only 40.0KB on production build.
riotjs is really cool as a micro framework.

how can i render a nesting json ?

i start a project using riot.js ,now i want render a json data like

{
    daily_id:1
    content:"whatever",
    user:{
        name:"oubushixb"
    }
}

template like
<p>{daily_id}</p>
<p>{content}</p>
<a>{user.name}</a>

todomvc example feature lacking

  • When toggling todos with a filter active, the toggled todos should be shown/hidden according to current filter.
  • Should finish editing when input is blurred
  • Should revert editing if "esc" is pressed when editing

support browsers without HTML5 History API

As far as I can tell, $.route doesn't support browsers without HTML5 History API. This means IE10+ is required. Three examples of libraries that do support routing for IE8+:

All of the above support IE8+, using hashchange event. Additionally, Directory and Backbone support IE7+, using <iframe>-based emulation.

P.S. What browser versions does riot.js intend to support?

insert HTML via $.render()

$.render() needs a syntax for inserting raw (literal) HTML without escaping, for example <div>{$content}</div> where the $ symbol would suppress escaping - for one, this would make it possible to compose templates by inserting a rendered result into another template.

$.observable no longer based on jQuery events?

The Riot.js introduction says that $.observable events are based on jQuery events. However, the source code shows otherwise.

What was the reasoning behind moving away from jQuery's events? As the introduction states, "a good event library is the single most important feature in a client-side framework". In light of this, what is your vision for the eventual scope of Riot.js events?

Memory leak for one() events in observable.trigger

expected:
observable.trigger for one() event will remove reference to event handler

actual behavior:
observable.trigger keeps reference to already fired event handlers.

proposed solution:
single-time events should be removed from callbacks[name] array after firing.

Suggestion: Maybe add optional scope to observable callbacks

Hi,

Just leaving this here to see what you think about it:

I added an optional scope to the observable callbacks in my app. Since a triggered callback function is run in the context of the triggering object I ran into scoping issues when doing something like this:

var gamePresenter = {
    init: function(user) {
       // User is an observable object
        user.on('didUpdateStats', this.renderPlayerStats);
    },
    render: function(template, data) {
        // Render...
    }
    renderPlayerStats: function(stats) {
       // This function will be executed in the scope of the user object
       // resulting in "render" being undefined
       this.render('someTemplate', stats);
    }
}

Of course I could refactor the code to not use "this", but for me an easy solution was to add the scope as a third parameter:

    // riot.observable.on
    el.on = function(events, fn, scope) {
        if (typeof fn === "function") {
          fn.scope = scope;
          ...

   // riot.observable.one
    el.one = function(name, fn, scope) {
        if (fn) fn.one = true;
        return el.on(name, fn, scope);
    };

   // ...and finally riot.observable.trigger
   ...
   fn.apply(fn.scope || el, fn.typed ? [name].concat(args) : args);
   ...

So now I can do this to avoid scoping issues:

    user.on('didUpdateStats', this.renderPlayerStats, this);

What do you think? Does this make any sense?

What's up with the global vars in $.render?

Is there any way to avoid this? I'm trying to get riot to play nice with browserify, and this presents a problem. Also it seems janky. Right now I'm just wrapping riot and dumping the whole thing into the global scope, I guess it works ok.

square brackets notation in riot.render

Add support for square brackets notation in riot.render function to access object properties with arbitrary string keys like {entry.user[“first:name”]}

needs documentation without the commentary

The canonical link for documentation ( https://muut.com/riotjs/docs/ ) reads as more of a rant about the state of current client-side application design and manifesto about good design. While I agree with the sentiments expressed, I feel that the commentary actively gets in the way of using the this documentation as either a learning tool or as reference material. Have you considered breaking out the reference material to a separate page?

No way to remove specific listeners => memory leaks?

I tried to use Riot.js observable with React components. But I can't find a way to remove specific listeners. I think memory will leak without doing it. Am I right? Example:

var Bus = observable({});

var component = React.createClass({
  login: function() {
    // do stuff
  },
  componentDidMount: function() {
     Bus.on("login", this.login);
  },
  componentWillUnmount: function() {
    // how to remove this.login listener here?
  },
  // ...
}

Template usage docs?

Can someone point me to the template usage docs? I would like to know, for example, how to extend templates or create partials. Thanks

API documentation

Please provide the API docs with examples, possibly using GitHub Wiki.

From what I can see in the source code, Riot.js has only three main functions:

  • $.observable(element) returning element with 4 methods:
    • el.on(events, callback)
    • el.one(event, callback)
    • el.off(events)
    • el.trigger(event)
  • $.render(template, data) returning string
  • $.route(to) taking either string or function

Is this a complete list or will there be more functions in version 1.0? How about changing the route definition to this form: $.route(to, callback), i.e: $.route('add', function() {...}).route('show/:param', function(param) {...});

Duplicate event callbacks are not removed

Is the purpose of the off method to remove the callback function if it is registered multiple times? If so, the code looks wrong to me since after removing the function once, the index is incremented and the subsequent entry is skipped. Consider the following:

> var arr = [ 'one', 'two', 'three', 'three', 'four', 'five', 'five', 'six' ];
undefined
> for (var i = 0, cb; (cb = arr && arr[i]); ++i) {
       if (cb === 'three') arr.splice(i, 1);
   }
["three"]
> arr
["one", "two", "three", "four", "five", "five", "six"]

As you can see, the second 'three' is not removed. Contrast with:

> var arr = [ 'one', 'two', 'three', 'three', 'four', 'five', 'five', 'six' ];
undefined
> for (var i = arr && arr.length-1, cb; (cb = arr && arr[i]); --i) {
       if (cb === 'three') arr.splice(i, 1);
   }
["three"]
> arr
["one", "two", "four", "five", "five", "six"]

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.