Skip to content

WorldMaker/butterfloat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Butterfloat

Butterfloat is a Knockout-inspired view engine using modern ESM via Typescript and pure RxJS observables.

"The greatest view engine the web has ever seen."

Getting Started starts a gentle tour of Butterfloat features.

A Usage Example

A complex component with embedded state may look something like this:

import { ComponentContext, ObservableEvent, butterfly, jsx } from 'butterfloat'
import { map } from 'rxjs'

interface GardenProps {}

interface GardenEvents {
  rake: ObservableEvent<MouseEvent>
}

function Garden(
  props: GardenProps,
  { bindEffect, events }: ComponentContext<GardenEvents>,
) {
  const [money, setMoney] = butterfly(1)
  const [labor, setLabor] = butterfly(0)

  const moneyPercent = money.pipe(
    map((money) => money.toLocaleString(undefined, { style: 'percent ' })),
  )

  const laborPercent = labor.pipe(
    map((labor) => labor.toLocaleString(undefined, { style: 'percent' })),
  )

  bindEffect(events.rake, () => {
    setMoney((money) => money - 0.15)
    setLabor((labor) => labor + 0.3)
  })

  return (
    <div class="garden">
      <div class="stat-label">Money</div>
      <progress
        title="Money"
        bind={{ value: money, innerText: moneyPercent }}
      />
      <div class="stat-label">Labor</div>
      <progress
        title="Labor"
        bind={{ value: labor, innerText: laborPercent }}
      />
      <div class="section-label">Activities</div>
      <button type="button" events={{ click: events.rake }}>
        Rake
      </button>
    </div>
  )
}

This may look like React at first glance, especially the intentional surface level resemblance of butterfly to useState and bindEffect to useEffect. This exact example is refactored in ways that a React component can't be (moving the butterfly state to its own "view model") in the State Management documentation, but it is suggested you take the scenic route and start with Getting Started.

Other Examples

Fresh projects built with Butterfloat:

Example projects migrated from Knockout:

About

The greatest view engine for the modern web

Topics

Resources

License

Stars

Watchers

Forks

Contributors 3

  •  
  •  
  •