Giter VIP home page Giter VIP logo

yolk's Introduction

Yolk

A library for building asynchronous user interfaces.

travis-ci

  • Familiar: Yolk is a small library built on top of Virtual DOM and RxJS. It exposes a very limited API so that you don't have to spend weeks getting up to speed. Yolk components are just plain functions that return JSX.

  • Everything is an observable: Yolk components consume RxJS observable streams as if they were plain values. From a websocket connection to a generator function to an event handler. If it can be represented as an observable, then it can be rendered directly into your markup.

  • Stateless: Being able to describe user interactions, control flow and plain values as observable streams means that application design becomes entirely declarative. There is no need to manually subscribe to observables in order to mutate or set component state.

Example

The following example renders a component with buttons to increment and decrement a counter.

import Yolk from `yolk`

function Counter () {

  // map all plus button click events to 1
  const handlePlus = this.createEventHandler()
  const plusOne = handlePlus.map(() => 1)

  // map all minus button click events to -1
  const handleMinus = this.createEventHandler()
  const minusOne = handleMinus.map(() => -1)

  // merge both event streams together and keep a running count of the result
  const count = plusOne.merge(minusOne).scan((x, y) => x + y, 0).startWith(0)

  return (
    <div>
      <div>
        <button id="plus" onClick={handlePlus}>+</button>
        <button id="minus" onClick={handleMinus}>-</button>
      </div>
      <div>
        <span>Count: {count}</span>
      </div>
    </div>
  )
}

Yolk.render(<Counter />, document.getElementById('container'))

Also see the Yolk implementation of TodoMVC.

API

The Yolk API is intentionally very limited so that you don't have to spend weeks getting up to speed. With an understanding of RxJS, you can begin building with Yolk immediately.

Instance API

The API for a component instance is a single method.

this.createEventHandler(mapping: any, initialValue: any): Function

Creates an exotic function that can also be used as an observable. If the function is called, the input value is pushed to the observable as it's latest value. In other words, when this function is used as an event handler, the result is an observable stream of events from that handler. For example,

function MyComponent () {
  // create an event handler
  const handleClick = this.createEventHandler()

  // use event handler to count the number of clicks
  const numberOfClicks =
    handleClick.scan((acc, ev) => acc + 1, 0).startWith(0)

  // create an element that displays the number of clicks
  // and a button to increment it
  return (
    <div>
      <span>Number of clicks: {numberOfClicks}</span>
      <button onClick={handleClick}>Click me!</button>
    </div>
  )
}

When custom components are destroyed, we want to make sure that all of our event handlers are properly cleaned up.

Top Level API

Yolk.render(instance: YolkComponent, node: HTMLElement): YolkComponent

Renders an instance of a YolkComponent inside of an HTMLElement.

Yolk.render(<span>Hello World!</span>, document.getElementById('container'))
Yolk.registerElement(name: string, fn: Function): void

Registers a custom HTML element using document.registerElement (polyfill included). This is especially useful if you're not building a single page application. For example,

function BigRedText (props) {
  return <h1 style={{color: 'red'}}>{props.content}</h1>
}

Yolk.registerElement(`big-red-text`, BigRedText)

will allow you to use <big-red-text content="Hello!"></big-red-text> in your .html files and will render out to

<big-red-text content="Hello!">
  <h1 style="color: red;">Hello!</h1>
</big-red-text>
Yolk.CustomComponent

Yolk.CustomComponent makes it easy to wrap non-Yolk behavior as a component, e.g. jQuery plugin or React component. Each component expects three (optional) methods,

  • onMount(props: object, node: HTMLElement): void
  • onUpdate(props: object, node: HTMLElement): void
  • onUnmount (node: HTMLElement): void

These methods pass in the latest values of your props so that you don't need to deal with subscribing to and disposing of Observables. For example,

class MyjQueryWrapper extends Yolk.CustomComponent {
  onMount (props, node) {
    this._instance = $(node).myjQueryThing(props)
  }

  onUpdate (props, node) {
    this._instance.update(props)
  }

  onUnmount () {
    this._instance.destroy()
  }
}

And then in your component markup,

function MyComponent () {
  const handleClick = this.createEventHandler()

  return (
    <div>
      <MyjQueryWrapper onClick={handleClick} />
    </div>
  )
}

CustomComponent expects a single child element to use as the node; otherwise, it will default to an empty div. For example, you can specify the child like so,

function MyComponent () {
  const handleClick = this.createEventHandler()

  return (
    <div>
      <MyjQueryWrapper onClick={handleClick}>
        <ul className="my-child-node">
          <li>Point 1</li>
          <li>Point 2</li>
          <li>Point 3</li>
        </ul>
      </MyjQueryWrapper>
    </div>
  )
}

Using JSX

It is highly suggested that you write Yolk with JSX. This is achieved using the Babel transpiler. You should configure the jsxPragma option for Babel either in .babelrc or in package.json,

.babelrc:

{
  "jsxPragma": "Yolk.createElement"
}

package.json:

{
  "babel": {
    "jsxPragma": "Yolk.createElement"
  }
}

Then anywhere you use JSX it will be transformed into plain JavaScript. For example this,

<p>My JSX</p>

Turns into,

Yolk.createElement(
  "p",
  null,
  "My JSX"
);

Without this pragma, Babel will assume that you mean to write JSX for React and you will receive React is undefined errors.

Support for Immutable Objects and #toJS

Yolk will not attempt to 'unwrap' objects that have a toJS function defined on them. This method is only called when a plain value is required to render something. It is particularly useful when used with libraries like Immutable.js or Freezer.js.

Supported Events

Yolk supports the following list of standard browser events,

onAbort onBlur onCanPlay onCanPlayThrough onChange onClick onContextMenu onCopy
onCueChange onCut onDblClick onDrag onDragEnd onDragEnter onDragLeave onDragOver
onDragStart onDrop onDurationChange onEmptied onEnded onError onFocus onInput
onInvalid onKeyDown onKeyPress onKeyUp onLoadedData onLoadedMetaData onLoadStart
onMouseDown onMouseMove onMouseOut onMouseOver onMouseUp onPaste onPause onPlay
onPlaying onProgress onRateChange onReset onScroll onSearch onSeeked onSeeking
onSelect onShow onStalled onSubmit onSuspend onTimeUpdate onToggle onVolumeChange
onWaiting onWheel

In addition, Yolk supports the following custom browser events,

onMount onUnmount

Supported Attributes

Yolk supports the following list of standard element attributes,

accept acceptCharset accessKey action align alt async autoComplete autoFocus autoPlay
autoSave bgColor border buffered cite className code codebase color colSpan content
contentEditable coords default defer dir dirName download draggable dropZone email
encType file for headers height hidden high href hrefLang httpEquiv icon id isMap
itemProp keyType kind label lang language low max method min name noValidate open
optimum password pattern ping placeholder poster preload pubdate radioGroup rel
required reversed rowSpan sandbox scope scoped shape span spellCheck src srcLang start
step style summary tabIndex target text title type useMap wrap allowFullScreen
allowTransparency capture charset challenge cols contextMenu dateTime disabled form
formAction formEncType formMethod formTarget frameBorder inputMode is list manifest
maxLength media minLength role rows seamless size sizes srcSet width wmode checked
controls loop multiple readOnly selected srcDoc value

Adding data-* attributes requires passing an object to the data attribute. For example,

const data = {cool: `dude`, veryRad: `gal`}

<div data={data} />

will render

<div data-cool="dude" data-very-rad="gal"></div>

Setup

To install Yolk, simply include it in your package.json,

npm install yolk --save

Or instead with Bower,

bower install yolk --save

yolk's People

Contributors

eiriksm avatar garbles avatar jadbox avatar justinwoo avatar kamilogorek avatar knpwrs avatar kumavis avatar pauloancheta avatar

Watchers

 avatar

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.