react-jsbox
Advanced tools
Comparing version 1.2.4-beta to 1.2.5-beta
{ | ||
"name": "react-jsbox", | ||
"version": "1.2.4-beta", | ||
"version": "1.2.5-beta", | ||
"description": "A custom React renderer for writing JSBox apps in React.", | ||
@@ -34,8 +34,8 @@ "keywords": [ | ||
"devDependencies": { | ||
"@babel/core": "^7.10.4", | ||
"@babel/core": "^7.10.5", | ||
"@babel/plugin-proposal-class-properties": "^7.10.4", | ||
"@babel/plugin-transform-runtime": "^7.10.4", | ||
"@babel/plugin-transform-runtime": "^7.10.5", | ||
"@babel/preset-env": "^7.10.4", | ||
"@babel/preset-react": "^7.10.4", | ||
"@babel/runtime": "^7.10.4", | ||
"@babel/runtime": "^7.10.5", | ||
"babel-eslint": "^10.1.0", | ||
@@ -47,6 +47,6 @@ "babel-preset-minify": "^0.5.1", | ||
"eslint-plugin-jsbox": "^0.1.1", | ||
"eslint-plugin-react-hooks": "^4.0.5", | ||
"eslint-plugin-react-hooks": "^4.0.8", | ||
"prettier": "^2.0.5", | ||
"react": "^16.13.1", | ||
"rollup": "^2.18.2", | ||
"rollup": "^2.22.0", | ||
"rollup-plugin-babel": "^4.4.0", | ||
@@ -53,0 +53,0 @@ "rollup-plugin-cleanup": "^3.1.1", |
655
README.md
<h1 align="center">Welcome to react-jsbox 👋</h1> | ||
<p> | ||
<img src="https://img.shields.io/badge/version-0.0.57-blue.svg?cacheSeconds=2592000" /> | ||
<img src="https://img.shields.io/badge/version-1.2.4-beta-blue.svg?cacheSeconds=2592000" /> | ||
</p> | ||
> A Custom React renderer for writing JSBox apps in React. | ||
> A custom React renderer for writing JSBox apps in React. | ||
@@ -22,86 +22,70 @@ npm: <https://www.npmjs.com/package/react-jsbox> | ||
import React from 'react' | ||
import ReactJSBox from 'react-jsbox' | ||
const {width, height} = $device.info.screen | ||
import { render } from 'react-jsbox' | ||
// Create a root Container: | ||
$ui.render({ | ||
props: { | ||
title: '', | ||
debugging: true | ||
}, | ||
views: [ | ||
{ | ||
type: 'view', | ||
props: { | ||
id: 'root' | ||
}, | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
} | ||
} | ||
] | ||
}) | ||
// Create React Components: | ||
class App extends React.PureComponent { | ||
constructor(props) { | ||
super(props) | ||
this.state = { | ||
count: 0 | ||
constructor(props) { | ||
super(props) | ||
console.log(props) | ||
this.state = { | ||
count: 0 | ||
} | ||
} | ||
this._listTemplate = { | ||
props: { | ||
bgcolor: $color('#fff') | ||
}, | ||
views: [ | ||
{ | ||
type: 'label', | ||
props: { | ||
bgcolor: $color('#474b51'), | ||
textColor: $color('#abb2bf'), | ||
align: $align.center, | ||
font: $font('iosevka', 24) | ||
}, | ||
layout: $layout.fill | ||
render() { | ||
const { width, height } = this.props | ||
const styles = { | ||
container: $rect(0, 0, width, height), | ||
text: $rect(0, height * 0.25 - 15, width, 30), | ||
list: $rect(0, height * 0.5, width, 140) | ||
} | ||
] | ||
return ( | ||
<view frame={styles.container}> | ||
<label | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={String(this.state.count)} | ||
autoFontSize={true} | ||
/> | ||
<list | ||
frame={styles.list} | ||
scrollEnabled={false} | ||
data={['INCREASE', 'DECREASE', 'RESET']} | ||
events={{ | ||
didSelect: (sender, { row }, data) => | ||
this.setState({ | ||
count: this.state.count + [1, -1, -this.state.count][row] | ||
}) | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
} | ||
render() { | ||
return ( | ||
<view frame={styles.container}> | ||
<label | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={String(this.state.count)} | ||
autoFontSize={true} | ||
/> | ||
<list | ||
frame={styles.list} | ||
radius={10} | ||
bgcolor={$color('#ededed')} | ||
data={['INCREASE', 'DECREASE', 'RESET']} | ||
template={this._listTemplate} | ||
events={{ | ||
didSelect: (sender, {row}, data) => | ||
this.setState({ | ||
count: this.state.count + [1, -1, -this.state.count][row] | ||
}) | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
} | ||
const styles = { | ||
container: $rect(0, 0, width, height - 40), | ||
text: $rect(0, 64, width, 30), | ||
list: $rect(0, 200, width, height - 280) | ||
} | ||
// Create React elements and render them: | ||
ReactJSBox.render(<App />, $('root')) | ||
// Create JSBox root container and render the React component into it | ||
$ui.render({ | ||
props: { | ||
title: '', | ||
debugging: true | ||
}, | ||
views: [ | ||
{ | ||
type: 'view', | ||
props: { | ||
id: 'root' | ||
}, | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
}, | ||
events: { | ||
layoutSubviews(view) { | ||
const { width, height } = view.frame | ||
render(<App width={width} height={height} />, view) | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
``` | ||
@@ -112,88 +96,88 @@ | ||
```jsx | ||
import * as React from 'react' | ||
import * as ReactJSBox from 'react-jsbox' | ||
const { width, height } = $device.info.screen | ||
import React from 'react' | ||
import { render } from 'react-jsbox' | ||
// Create a root Container: | ||
$ui.render({ | ||
props: { | ||
title: '', | ||
debugging: true | ||
}, | ||
views: [ | ||
{ | ||
type: 'view', | ||
props: { | ||
id: 'root' | ||
}, | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
} | ||
class App extends React.PureComponent { | ||
constructor(props) { | ||
super(props) | ||
this.state = { | ||
text: '' | ||
} | ||
this._input = React.createRef() | ||
this._handleTextChange = this.handleTextChange.bind(this) | ||
} | ||
] | ||
}) | ||
// Create React component: | ||
class App extends React.PureComponent { | ||
constructor(props) { | ||
super(props) | ||
this.state = { | ||
text: '' | ||
handleTextChange(sender) { | ||
this.setState({ text: sender.text }) | ||
} | ||
this._input = React.createRef() | ||
this._handleTextChange = this.handleTextChange.bind(this) | ||
} | ||
handleTextChange(sender) { | ||
this.setState({ text: sender.text }) | ||
} | ||
componentDidMount() { | ||
this._input.current.focus() | ||
} | ||
componentDidMount() { | ||
this._input.current.focus() | ||
} | ||
render() { | ||
return ( | ||
<view | ||
id="container" | ||
frame={styles.container} | ||
bgcolor={$color('#2ac')} | ||
events={{ | ||
tapped: () => this._input.current.blur() | ||
}} | ||
> | ||
<label | ||
id={'text'} | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={this.state.text || 'Hello World!'} | ||
textColor={$color('#fff')} | ||
autoFontSize={true} | ||
/> | ||
<input | ||
id={'textInput'} | ||
// use ref to access JSBox view instance | ||
ref={this._input} | ||
frame={styles.textInput} | ||
font={$font('ArialRoundedMTBold', 24)} | ||
tintColor={$color('orange')} | ||
placeholder={'Type here...'} | ||
events={{ | ||
changed: this._handleTextChange | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
render() { | ||
const { width, height } = this.props | ||
const styles = { | ||
container: $rect(0, 0, width, height - 40), | ||
text: $rect(0, 64, width, 30), | ||
textInput: $rect(10, 160, width - 20, 48) | ||
} | ||
return ( | ||
<view | ||
id="container" | ||
frame={styles.container} | ||
bgcolor={$color('#2ac')} | ||
events={{ | ||
tapped: () => this._input.current.blur() | ||
}} | ||
> | ||
<label | ||
id={'text'} | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={this.state.text || 'Hello World!'} | ||
textColor={$color('#fff')} | ||
autoFontSize={true} | ||
/> | ||
<input | ||
id={'textInput'} | ||
// use ref to access JSBox view instance | ||
ref={this._input} | ||
frame={styles.textInput} | ||
font={$font('ArialRoundedMTBold', 24)} | ||
tintColor={$color('orange')} | ||
placeholder={'Type here...'} | ||
events={{ | ||
changed: this._handleTextChange | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
} | ||
const styles = { | ||
container: $rect(0, 0, width, height - 40), | ||
text: $rect(0, 64, width, 30), | ||
textInput: $rect(10, 160, width - 20, 48) | ||
} | ||
// Create React elements and render them: | ||
ReactJSBox.render(<App />, $('root')) | ||
$ui.render({ | ||
props: { | ||
title: '', | ||
debugging: true | ||
}, | ||
views: [ | ||
{ | ||
type: 'view', | ||
props: { | ||
id: 'root' | ||
}, | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
}, | ||
events: { | ||
layoutSubviews(view) { | ||
const { width, height } = view.frame | ||
render(<App width={width} height={height} />, view) | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
``` | ||
@@ -206,89 +190,74 @@ | ||
```jsx | ||
import React from 'react' | ||
import ReactJSBox from 'react-jsbox' | ||
const {width, height} = $device.info.screen | ||
import React, { useMemo } from 'react' | ||
import { render } from 'react-jsbox' | ||
// Create a root Container: | ||
$ui.render({ | ||
props: { | ||
title: '', | ||
debugging: true | ||
}, | ||
views: [ | ||
{ | ||
type: 'view', | ||
props: { | ||
id: 'root' | ||
}, | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
} | ||
} | ||
] | ||
}) | ||
function App({ width, height }) { | ||
const [state, dispatch] = React.useReducer(counterReducer, { count: 0 }) | ||
const styles = useMemo( | ||
() => ({ | ||
container: $rect(0, 0, width, height), | ||
text: $rect(0, height * 0.25 - 15, width, 30), | ||
list: $rect(0, height * 0.5, width, 140) | ||
}), | ||
[width, height] | ||
) | ||
return ( | ||
<view frame={styles.container}> | ||
<label | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={String(state.count)} | ||
autoFontSize={true} | ||
/> | ||
<list | ||
frame={styles.list} | ||
scrollEnabled={false} | ||
data={['INCREASE', 'DECREASE', 'RESET']} | ||
events={{ | ||
didSelect: (sender, indexPath, data) => dispatch({ type: data }) | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
const counterReducer = (state, action) => { | ||
switch (action.type) { | ||
case 'INCREASE': | ||
return {...state, count: state.count + 1} | ||
case 'DECREASE': | ||
return {...state, count: state.count - 1} | ||
case 'RESET': | ||
return {...state, count: 0} | ||
default: | ||
throw new Error() | ||
} | ||
switch (action.type) { | ||
case 'INCREASE': | ||
return { ...state, count: state.count + 1 } | ||
case 'DECREASE': | ||
return { ...state, count: state.count - 1 } | ||
case 'RESET': | ||
return { ...state, count: 0 } | ||
default: | ||
throw new Error() | ||
} | ||
} | ||
const App = () => { | ||
const [state, dispatch] = React.useReducer(counterReducer, {count: 0}) | ||
const listTemplate = { | ||
$ui.render({ | ||
props: { | ||
bgcolor: $color('#fff') | ||
title: '', | ||
debugging: true | ||
}, | ||
views: [ | ||
{ | ||
type: 'label', | ||
props: { | ||
bgcolor: $color('#474b51'), | ||
textColor: $color('#abb2bf'), | ||
align: $align.center, | ||
font: $font('iosevka', 24) | ||
}, | ||
layout: $layout.fill | ||
} | ||
{ | ||
type: 'view', | ||
props: { | ||
id: 'root' | ||
}, | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
}, | ||
events: { | ||
layoutSubviews(view) { | ||
const { width, height } = view.frame | ||
render(<App width={width} height={height} />, view) | ||
} | ||
} | ||
} | ||
] | ||
} | ||
return ( | ||
<view frame={styles.container}> | ||
<label | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={String(state.count)} | ||
autoFontSize={true} | ||
/> | ||
<list | ||
frame={styles.list} | ||
radius={10} | ||
bgcolor={$color('#ededed')} | ||
data={['INCREASE', 'DECREASE', 'RESET']} | ||
template={listTemplate} | ||
events={{ | ||
didSelect: (sender, indexPath, data) => dispatch({type: data}) | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
const styles = { | ||
container: $rect(0, 0, width, height - 40), | ||
text: $rect(0, 64, width, 30), | ||
list: $rect(0, 200, width, height - 280) | ||
} | ||
// Create React elements and render them: | ||
ReactJSBox.render(<App />, $('root')) | ||
}) | ||
``` | ||
@@ -301,16 +270,16 @@ | ||
```jsx | ||
import {useEffect, useState} from 'react' | ||
import { useEffect, useState } from 'react' | ||
const useCache = (key, initialValue) => { | ||
const [state, setState] = useState(() => { | ||
const cacheValue = $cache.get(key) | ||
if (cacheValue === undefined) { | ||
$cache.set(key, initialValue) | ||
return initialValue | ||
} | ||
return cacheValue | ||
}) | ||
useEffect(() => $cache.set(key, state)) | ||
const [state, setState] = useState(() => { | ||
const cacheValue = $cache.get(key) | ||
if (cacheValue === undefined) { | ||
$cache.set(key, initialValue) | ||
return initialValue | ||
} | ||
return cacheValue | ||
}) | ||
useEffect(() => $cache.set(key, state)) | ||
return [state, setState] | ||
return [state, setState] | ||
} | ||
@@ -324,103 +293,86 @@ | ||
```jsx | ||
import React from 'react' | ||
import ReactJSBox from 'react-jsbox' | ||
import React, { useMemo } from 'react' | ||
import { render, useCache } from 'react-jsbox' | ||
import useCache from './useCache' | ||
import rootContainer from './Containers/root' | ||
const {width, height} = $device.info.screen | ||
const App = () => { | ||
const [count, setCount] = useCache('count', 0) | ||
const listTemplate = { | ||
views: [ | ||
{ | ||
type: 'label', | ||
props: { | ||
bgcolor: $color('#474b51'), | ||
textColor: $color('#abb2bf'), | ||
align: $align.center, | ||
font: $font('iosevka', 24) | ||
}, | ||
layout: $layout.fill | ||
} | ||
] | ||
} | ||
function App({ width, height }) { | ||
const [count, setCount] = useCache('count', 0) | ||
return ( | ||
<view frame={styles.container}> | ||
<label | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={String(count)} | ||
autoFontSize={true} | ||
/> | ||
<list | ||
frame={styles.list} | ||
scrollEnabled={false} | ||
radius={5} | ||
bgcolor={$color('#ededed')} | ||
data={['INCREASE', 'DECREASE', 'RESET']} | ||
template={listTemplate} | ||
events={{ | ||
didSelect: (sender, {row}, data) => setCount(count => count + [1, -1, -count][row]) | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
const styles = useMemo( | ||
() => ({ | ||
container: $rect(0, 0, width, height), | ||
text: $rect(0, height * 0.25 - 15, width, 30), | ||
list: $rect(0, height * 0.5, width, 140) | ||
}), | ||
[width, height] | ||
) | ||
const styles = { | ||
container: $rect(0, 0, width, height - 40), | ||
text: $rect(0, 64, width, 30), | ||
list: $rect(0, (height - 40) * 0.3, width, 132) | ||
return ( | ||
<view frame={styles.container}> | ||
<label | ||
frame={styles.text} | ||
align={$align.center} | ||
font={$font('ArialRoundedMTBold', 26)} | ||
text={String(count)} | ||
autoFontSize={true} | ||
/> | ||
<list | ||
frame={styles.list} | ||
scrollEnabled={false} | ||
data={['INCREASE', 'DECREASE', 'RESET']} | ||
events={{ | ||
didSelect(sender, { row }) { | ||
setCount(x => x + [1, -1, -x][row]) | ||
} | ||
}} | ||
/> | ||
</view> | ||
) | ||
} | ||
// Create a root Container: | ||
$ui.render(rootContainer) | ||
// Create React elements and render them: | ||
ReactJSBox.render(<App />, $('root')) | ||
``` | ||
#### JsxLiteral | ||
```javascript | ||
const htm = require("htm") | ||
const { createElement, useState } = require("react") | ||
const ReactJSBox = require("react-jsbox") | ||
const jsx = htm.bind(createElement) | ||
const { width, height } = $device.info.screen | ||
const listTemplate = { | ||
views: [ | ||
{ | ||
type: "label", | ||
props: { | ||
bgcolor: $color("#474b51"), | ||
textColor: $color("#abb2bf"), | ||
align: $align.center, | ||
font: $font("iosevka", 24) | ||
}, | ||
layout: $layout.fill | ||
} | ||
] | ||
} | ||
$ui.render({ | ||
props: { | ||
title: "JsxLiteralExample" | ||
title: '', | ||
debugging: true | ||
}, | ||
views: [ | ||
{ | ||
type: "view", | ||
type: 'view', | ||
props: { | ||
id: "root" | ||
id: 'root' | ||
}, | ||
layout: $layout.fill | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
}, | ||
events: { | ||
layoutSubviews(view) { | ||
const { width, height } = view.frame | ||
render(<App width={width} height={height} />, view) | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
``` | ||
function JsxLiteralExample() { | ||
const [count, setCount] = useState(0); | ||
#### JsxLiteral | ||
```javascript | ||
const htm = require('htm') | ||
const { createElement, useState, useMemo } = require('react') | ||
const ReactJSBox = require('react-jsbox') | ||
const jsx = htm.bind(createElement) | ||
function JsxLiteralExample({ width, height }) { | ||
const [count, setCount] = useState(0) | ||
const styles = useMemo( | ||
() => ({ | ||
container: $rect(0, 0, width, height), | ||
text: $rect(0, height * 0.25 - 15, width, 30), | ||
list: $rect(0, height * 0.5, width, 140) | ||
}), | ||
[width, height] | ||
) | ||
return jsx`<view frame=${styles.container}> | ||
@@ -434,17 +386,9 @@ <label | ||
/> | ||
<progress | ||
frame=${$rect(15, 150, width - 30, 30)} | ||
value=${0.5 + count * 0.01} | ||
}} | ||
/> | ||
<list | ||
frame=${styles.list} | ||
scrollEnabled=${false} | ||
radius=${5} | ||
bgcolor=${$color("#ededed")} | ||
data=${["INCREASE", "DECREASE", "RESET"]} | ||
template=${listTemplate} | ||
data=${['INCREASE', 'DECREASE', 'RESET']} | ||
events=${{ | ||
didSelect: (sender, { row }, data) => { | ||
setCount(count => count + [1, -1, -count][row]) | ||
didSelect: (sender, { row }) => { | ||
setCount(x => x + [1, -1, -x][row]) | ||
} | ||
@@ -456,9 +400,24 @@ }} | ||
const styles = { | ||
container: $rect(0, 0, width, height), | ||
text: $rect(0, 64, width, 30), | ||
list: $rect(0, width * 0.5, width, 132) | ||
} | ||
ReactJSBox.render(jsx`<${JsxLiteralExample} />`, $("root")) | ||
$ui.render({ | ||
props: { | ||
title: 'JsxLiteralExample' | ||
}, | ||
views: [ | ||
{ | ||
type: 'view', | ||
props: { | ||
id: 'root' | ||
}, | ||
layout(make, view) { | ||
make.edges.equalTo(view.super.safeArea) | ||
}, | ||
events: { | ||
layoutSubviews(view) { | ||
const { width, height } = view.frame | ||
ReactJSBox.render(jsx`<${JsxLiteralExample} width=${width} height=${height} />`, view) | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
``` | ||
@@ -470,3 +429,3 @@ | ||
- Github: [@Nicify](https://github.com/Nicify) | ||
- Github: [@Nicify](https://github.com/Nicify) | ||
@@ -473,0 +432,0 @@ ## Show your support |
@@ -10,1 +10,2 @@ export { default as useCache } from './useCache' | ||
export { default as useUpdateEffect } from './useUpdateEffect' | ||
export { default as useUpdateLayoutEffect } from './useUpdateLayoutEffect' |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
356679
21
1655
427