Commit 5f60949c by Иван Кубота

working Slider example. Start test coverage. Subproperties deep setting…

working Slider example. Start test coverage. Subproperties deep setting implementation and customization possibility
parent d220008f
......@@ -16,12 +16,21 @@
"pragma": "h"
}
],
["@babel/typescript", { "jsxPragma": "h" }]
[
"@babel/typescript",
{
"jsxPragma": "h"
}
]
],
"plugins": [
"@babel/plugin-proposal-class-properties",
["transform-react-jsx", { "pragma": "h" }]
[
"transform-react-jsx",
{
"pragma": "h"
}
]
]
},
"keywords": [],
......@@ -38,12 +47,19 @@
"babel-preset-env": "^1.7.0",
"babel-preset-preact": "^1.1.0",
"babel-preset-react": "^6.24.1",
"mocha": "^6.1.4",
"mocha-webpack": "^2.0.0-beta.0",
"source-map-loader": "^0.2.4",
"typescript": "^3.3.3333",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.2.1"
"webpack-dev-server": "^3.2.1",
"@babel/register": "^7.4.4",
"chai": "^4.2.0"
},
"types": "src/Rjsx.d.ts",
"typings": "./src/Rjsx.d.ts"
"typings": "./src/Rjsx.d.ts",
"dependencies": {
"simplest-dom": "0.0.19"
}
}
......@@ -11,22 +11,21 @@ class Item extends Component {
return <div>
{this.checkbox = <input disabled={false} type="checkbox"/>}<br/>
Title: <input value={R(()=>checkbox3.on('checked'))}/><br/>
Title: <input value={R(()=>checkbox3.sub('checked'))}/><br/>
{this.checkbox2 = <input type="checkbox"/>}<br/>
{checkbox3 = <input type="checkbox" checked={R(
this.checkbox2.on('checked'),
this.checkbox.on('checked'),
this.checkbox2.sub('checked'),
this.checkbox.sub('checked'),
(v1,v2)=>!!(v1^v2)
)}/>}<br/>
{<input type="checkbox" id="c4" checked={R(checkbox3.on('checked'))}/>}<br/><br/><br/><br/>
{<input type="checkbox" id="c4" checked={R(checkbox3.sub('checked'))}/>}<br/><br/><br/><br/>
</div>;
}
}
let but = <i text={2}>1</i>;
class UIComponent extends Component {
def = {
const UIComponent = Component.extend('UIComponent', {
def: {
disabled: false,
hidden: false,
label: {
......@@ -41,54 +40,109 @@ class UIComponent extends Component {
size: 'normal',
margin: {top: '16px'}
}
};
setters = {
hidden: (_, val) => _.el.style.display = val ? 'block' : 'none',
},
setters: {
hidden: (_, val) => _.el.style.display = val === false ? 'block' : 'none',
style: (_, val)=>{
}
}
}
});
class Check extends UIComponent {
setters = {
const Check = UIComponent.extend('Check', {
setters: {
value: (_, val)=>{
_.check.el.checked = val
},
label: {
text: (_, val)=>_.label.el.innerText = val
}
};
getters = {
},
getters: {
value: (_, val)=>_.check.el.checked
};
},
render(){
this.check = <input type="checkbox"/>;
this.set({value: R(this.check.on('checked'))})
this.set({value: R(this.check.sub('checked'))})
this.check.on('click', ()=>{console.log('lalka')} );
this.label = <span>456</span>;
return <label>{this.check}{this.label}</label>
}
}
});
const Slider = UIComponent.extend('Slider', {
def: {
from: 0,
to: 100,
step: 1,
value: 0,
sliderWidth: 10,
background: 'red'
},
recalc: function() {
if(this.state.value<this.state.from){
return this.set({value: this.state.from});
}
if(this.state.value>this.state.to){
return this.set({value: this.state.to});
}
class Slider extends UIComponent {
var delta = this.state.to - this.state.from;
this.mover.set({
style: {
left: (this.state.value-this.state.from)/delta*(this.state.width-this.state.sliderWidth)
}
});
},
setters: {
'from,to,step,value,width': (_)=>{
_.later('recalc', _.recalc);
}
},
render(){
return <div class="slider" style={{background: 'red'}}>
let sliderRect;
const moveFn = (e)=>{
const newRawVal = Math.max(0, Math.min(1,(e.clientX-sliderRect.left)/(sliderRect.width))),
delta = this.state.to - this.state.from,
newRangedVal = newRawVal*delta+this.state.from,
step = this.state.step,
newRoundedVal = Math.round(newRangedVal/step)*step;
this.set({value: newRoundedVal});
};
this.mover = <div
style={{cursor: 'pointer', width: 10, height: 10, border: '3px solid #fff', position: 'absolute', boxSizing: 'border-box'}}
onMouseDown={(e)=>{
console.log('down');
sliderRect = this.getBoundingClientRect();
this.doc.on('mousemove', moveFn);
this.doc.once('mouseup', ()=>{
this.doc.un('mousemove', moveFn);
});
this.set({width: sliderRect.width});
e.preventDefault();
}}
/>;
//console.log()
return <div class="slider" style={{background: R(this.sub('background')), position: 'relative', height: 10}}>
{this.mover}
</div>;
}
}
});
//
let chhh = <Check value={false} label={{text: R(()=>i.on('text'))}}/>;
let chhh = <Check value={false} label={{text: R(()=>i.sub('text'))}}/>;
console.log(chhh);
let slider1 = <Slider from={-10} to={100} step={1}/>;
let RS, GS, BS;
<div className='wrapper'>
<Check value={true} label={{text: 'Ti pidor'}} hidden={R(()=>chhh.on('value'))}/>
<Check value={true} label={{text: 'Ti pidor'}} hidden={R(()=>chhh.sub('value'))}/>
{chhh}
<Check value={R(()=>chhh.on('value'))}/>
<Check value={R(()=>chhh.sub('value'))}/>
{item = <Item/>}
{btn = <Button onClick={function(e,b,c){
item.checkbox.set({checked: !item.checkbox.state.checked})
......@@ -96,8 +150,57 @@ console.log(chhh);
<Item/>
<Item />
{but}
<Slider/>
</div>.renderTo(document.body);
{slider1}
<div>
<div>from: <b text={R(()=>slider1.sub('from'))}/></div>
<div>to: <b text={R(()=>slider1.sub('to'))}/></div>
<div>value: <b text={R(()=>slider1.sub('value'))}/></div>
<div>step: <b text={R(()=>slider1.sub('step'))}/></div>
</div>
{RS = <Slider from={0} to={255} step={1} value={123} background={R(
()=>RS.sub('value'),
(r)=>'rgba('+[r,0,0,1]+')'
)}/>}
{GS = <Slider from={0} to={255} step={1} value={123} background={R(
()=>GS.sub('value'),
(g)=>'rgba('+[0,g,0,1]+')'
)}/>}
{BS = <Slider from={0} to={255} step={1} value={123} background={R(
()=>BS.sub('value'),
(b)=>'rgba('+[0,0,b,1]+')'
)}/>}
<div style={{
width: 300,
height: 300,
padding: '30px',
position: 'absolute',
background: R(
()=>RS.sub('value'),
()=>GS.sub('value'),
()=>BS.sub('value'),
(r,g,b)=>'rgba('+[r,g,b,1]+')'
),
color: R(
()=>RS.sub('value'),
()=>GS.sub('value'),
()=>BS.sub('value'),
(r,g,b)=>'rgba('+[256-r,(256-r+g)%256,b,1]+')'
)
}}
text={R(
()=>RS.sub('value'),
()=>GS.sub('value'),
()=>BS.sub('value'),
(r,g,b)=>
`R: ${r}
G: ${g}
B: ${b}`
)}
/>
</div>.mount(document.body);
let counter = 0;
setInterval(()=>{
......@@ -110,7 +213,7 @@ setInterval(()=>{
setTimeout(()=>{
//debugger;
but.set({
text: R(but.on('text'), (v1)=>{
text: R(but.sub('text'), (v1)=>{
return (v1-0)+148
})
});
......
var x;
for(var i = 0; i < 0x13322; i++){
x+=i;
}
void 0;
\ No newline at end of file
import {assert} from 'chai';
//import {describe, it} from 'mocha';
import dom from 'simplest-dom';
global.document = new dom();
let animationFnList = [];
global.requestAnimationFrame = function(fn) {
animationFnList.push(fn);
};
const animate = function() {
const list = animationFnList;
animationFnList = [];
list.forEach(function(fn) {
fn();
});
};
import {h, R, Component} from '../src/F';
describe('creating element', function() {
it('should create element', function() {
let div = <div/>;
assert.equal(div.el.nodeName, 'div', 'create correct element');
});
it('should create nested elements', function() {
let div = <div><b/></div>;
assert.equal(div.el.nodeName, 'div', 'create correct element');
assert.equal(div.el.childNodes[0].nodeName, 'b', 'create correct child element');
});
it('should create and compose element with cls and content', function() {
let div = <div class="cls1">abc</div>;
assert.equal(div.el.outerHTML, '<div class="cls1">abc</div>', 'create correct element');
});
});
describe('reactive', function() {
it('should update dependency', function() {
let div1 = <div n="1" a={3} b={4}/>
let div = <div
n={R(div1.sub('n'))}
m={R(div1.sub('a'),div1.sub('b'), (a,b)=>a*b)}
/>;
assert.equal(div1.state.n, '1', 'setted correctly');
assert.equal(div.state.n, void 0, 'before property update');
assert.equal(div.state.m, void 0, 'before property update');
animate();
assert.equal(div.state.n, '1', 'setted correctly through dependency');
assert.equal(div.state.m, 3*4, 'setted correctly through dependency of two props');
const newVal = 22;
div1.set({n: newVal, a: div1.get('a')+1});
assert.equal(div1.get('a'), 4, 'setted correctly through dependency');
assert.equal(div.state.n, '1', 'setted correctly through dependency');
assert.equal(div.state.m, 3*4, 'setted correctly through dependency of two props');
animate();
assert.equal(div.state.n, newVal, 'setted correctly through dependency');
assert.equal(div.state.m, 4*4, 'setted correctly through dependency of two props');
})
});
describe('components', function() {
let MyCmp;
let nest1, nest2, nest3;
it('should extend Component', function(){
MyCmp = Component.extend( 'MyCmp', {
def: {
prop1: true,
prop2: false,
nest: nest1 = {
num: 1,
str: 'str'
},
prop3: void 0,
prop4: null,
nest2: nest2 = {
subNest2: nest3 = {
a: 42,
b: 33
}
}
},
setters: {
nest2: ( _, val, lastVal, theKey, state ) => {
if(!state.nest2){
state.nest2 = {};
}
Object.assign(state.nest2, val);
return false;
//Object.assign( _.state.nest, val )
},
style: ( _, val ) => {
}
},
render: () => {
return <div/>;
}
} );
var cm = <MyCmp/>;
assert.equal( cm.get( 'prop1' ), true, 'default bool prop' );
assert.equal( cm.get( 'prop2' ), false, 'default bool prop' );
assert.equal( cm.get( 'nest' ), nest1, 'nested prop' );
assert.equal( cm.get( 'nest.num' ), nest1.num, 'nested number prop' );
assert.equal( cm.get( 'nest.str' ), nest1.str, 'nested string prop' );
assert.equal( cm.get( 'prop3' ), void 0, 'undefined prop' );
assert.equal( cm.get( 'prop4' ), null, 'null prop' );
assert.deepEqual( cm.get( 'nest2' ), nest2, 'nested2 prop' );
assert.deepEqual( cm.get( 'nest2.subNest2' ), nest3, 'nested2 nested prop' );
assert.equal( cm.get( 'nest2.subNest2.a' ), nest3.a, 'nested2 nested number prop' );
assert.equal( cm.get( 'nest2.subNest2.b' ), nest3.b, 'nested2 nested number prop' );
});
it('should correctly overwrite props', function() {
let newNest1 = {num:3};
let cmp = <MyCmp prop2={false} nest={newNest1} nest2={
{x: 666}
}/>;
assert.equal(cmp.get('prop1'), true, 'default bool prop');
assert.equal(cmp.get('prop2'), false, 'default bool prop');
assert.deepEqual(cmp.get('nest'), newNest1, 'nested prop');
assert.equal(cmp.get('prop3'), void 0, 'undefined prop');
assert.equal(cmp.get('prop4'), null, 'null prop');
assert.deepEqual(cmp.get('nest2'), { subNest2: { a: 42, b: 33 }, x: 666 }, 'nested2 prop');
});
});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
module.exports = {
entry: './src/index.jsx',
devtool: 'source-map',
devtool: '#inline-cheap-module-source-map',
module: {
rules: [
{
......@@ -21,7 +21,9 @@ module.exports = {
output: {
path: __dirname + '/dist',
publicPath: '/',
filename: 'bundle.js'
filename: 'bundle.js',
devtoolModuleFilenameTemplate : '[absolute-resource-path]',
devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
},
devServer: {
contentBase: './dist'
......
// webpack.test.config.js
const config = require('./webpack.config.js');
config.target = 'node';
config.mode = 'development';
module.exports = config;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment