├── .gitignore
├── .npmrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── component.js
├── example
├── .npmrc
├── component.js
├── index.js
├── package.json
├── store.js
├── test.js
└── view.js
├── h.js
├── html.js
├── index.js
├── package.json
└── test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | coverage/
3 | dist/
4 | tmp/
5 | .sauce-credentials.json
6 | sauce_connect.log
7 | npm-debug.log*
8 | coverage.json
9 | .DS_Store
10 | *.swp
11 | .zuulrc
12 | generate
13 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | node_js:
2 | - '6'
3 | - '7'
4 | - '8'
5 | sudo: false
6 | language: node_js
7 | env:
8 | - CXX=g++-4.8
9 | addons:
10 | apt:
11 | sources:
12 | - ubuntu-toolchain-r-test
13 | packages:
14 | - g++-4.8
15 | script: npm run test
16 | # after_script: npm i -g codecov.io && cat ./coverage/lcov.info | codecov
17 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## `3.0.0`
2 | - parity with choo 6.6.0
3 | - lib namespace kept as `choo` for compatability with `choo-devtools`
4 |
5 | ## `2.0.0`
6 | ### breaking changes
7 | - adopted the choo v5 API ✨
8 | - exposes `html`, `h`, and `component` aliases
9 |
10 | ---
11 |
12 | ## `1.1.0`
13 | - old skool rooch
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Yoshua Wuyts
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
choop
2 |
3 |
4 | 🚂🚋🚋🚋🚋🚋 + ⚛
5 |
6 |
7 | Full on choo architecture on top of the tiny preact engine.
8 |
37 |
38 |
39 |
40 | Ever wondered what would happen if [`preact`](https://github.com/developit/preact) and [`choo`](https://github.com/yoshuawuyts/choo) got a baby?
41 |
42 | Welp, wonder no longer - here's the answer. Full on `choo` architecture plus a couple `preact` goodies like [`h()`](https://preactjs.com/guide/differences-to-react#what-s-included-) and [components](https://preactjs.com/guide/lifecycle-methods). No JSX, only template strings via [hyperx](https://github.com/substack/hyperx). But you can use JSX if you want to. We even get almost all of the React ecosystem through [preact-compat](https://github.com/developit/preact-compat) 🎉🎉🎉🎉
43 |
44 | ## Example
45 |
46 | ```js
47 | var html = require('choop/html')
48 | var devtools = require('choo-devtools')
49 | var choop = require('choop')
50 |
51 | var app = choop()
52 | app.use(devtools())
53 | app.use(countStore)
54 | app.route('/', mainView)
55 | app.mount('body')
56 |
57 | function mainView (state, emit) {
58 | return html`
59 |
60 |
count is ${state.count}
61 |
62 |
63 | `
64 |
65 | function onclick () {
66 | emit('increment', 1)
67 | }
68 | }
69 |
70 | function countStore (state, emitter) {
71 | state.count = 0
72 | emitter.on('increment', function (count) {
73 | state.count += count
74 | emitter.emit('render')
75 | })
76 | }
77 | ```
78 |
79 | See? Same same as `choo`!
80 |
81 | Only difference is `preact` will append our app to the element passed into `mount`. So instead of our main view returning `` we return `` (or whatever we want the root to be).
82 |
83 | ## Components
84 |
85 | You can create stateful components right out of the box with `choop`:
86 |
87 | ```js
88 | var Component = require('choop/component')
89 | var html = require('choop/html')
90 |
91 | class ClickMe extends Component {
92 | constructor () {
93 | super()
94 | this.state = { n: 0 }
95 | this.handleClick = () => {
96 | this.setState({ n: this.state.n + 1 })
97 | }
98 | }
99 | render (props, state) {
100 | return html`
101 |
102 |
clicked ${state.n} times
103 |
104 |
105 | `
106 | }
107 | }
108 | ```
109 |
110 | And then render them in your views using `h()`:
111 |
112 | ```js
113 | var html = require('choop/html')
114 | var h = require('choop/h')
115 |
116 | var ClickMe = require('./ClickMe')
117 |
118 | function view (state, emit) {
119 | return html`
120 |
121 | ${h(ClickMe)}
122 |
123 | `
124 | }
125 | ```
126 |
127 | Optionally pass data a.k.a. `props`:
128 |
129 | ```js
130 | h(MyComponent, { someData: 'beep' })
131 | ```
132 |
133 | You can use `props` or an additional constructor function to pass `emit` into your components.
134 |
135 | **`state.cache`**
136 |
137 | `choo` version `6.11.0` introduced a `state.cache` helper for managing `nanocomponent` instances. This is not included in `choop` since component instance management is taken care of by `preact`.
138 |
139 | ## More Examples
140 |
141 | - **Basic**: https://esnextb.in/?gist=f9f339a9d108f156aa885bca96723d36
142 | - **Using JSX**: https://esnextb.in/?gist=84fd53fc0ea53240da89bef9573c9644
143 | - **Rendering `choop` (`preact`) component**: https://esnextb.in/?gist=28005d951a7347fb652eab669c5ffa1e
144 | - **Rendering `Nanocomponent`**: https://esnextb.in/?gist=01daeea0b216632edf3f0e27b8f0b89a
145 | - **Rendering `React` component**: https://choop-react.glitch.me/ ([source](https://glitch.com/edit/#!/choop-react?path=public/client.js:1:0))
146 |
147 | ## FAQ
148 |
149 | ### Should I use this?
150 | Sometimes you gotta use `react`, and the best thing to do in that case might be to jump on the `preact` train, grab a bag of architecture and go to town. This might not be for me, but perhaps it's useful for you. Here you go! 🎁
151 |
152 | ### What's the real difference here?
153 | [`nanomorph`](https://github.com/choojs/nanomorph) is replaced by [`preact`](https://github.com/developit/preact)
154 |
155 | ### How do I run react widgets in choop?
156 | Like [this](https://github.com/preact-compat/react):
157 |
158 | ```
159 | npm i -S preact preact-compat
160 | npm i -S preact-compat/react preact-compat/react-dom
161 | ```
162 |
163 | ### What's the size?
164 |
165 | Something like `8.7 kB`
166 |
167 | ### What about choo?
168 | Yeah, what about me? (_drumroll_)
169 |
170 | ## Installation
171 | ```sh
172 | $ npm install choop
173 | ```
174 |
--------------------------------------------------------------------------------
/component.js:
--------------------------------------------------------------------------------
1 | var Preact = require('preact')
2 | class Component extends Preact.Component {}
3 | module.exports = Component
--------------------------------------------------------------------------------
/example/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
--------------------------------------------------------------------------------
/example/component.js:
--------------------------------------------------------------------------------
1 | var choop = require('..')
2 | var html = require('../html')
3 | var h = require('../h')
4 | var Component = require('../component')
5 |
6 | class ClickMe extends Component {
7 | constructor (props) {
8 | super(props)
9 | this.state = { n: 0 }
10 | this.handleClick = () => {
11 | this.setState({ n: this.state.n + 1 })
12 | }
13 | }
14 | render (props, state) {
15 | return html`
16 |