Skip to content

Commit 322d607

Browse files
author
Vlad Balin
committed
Refactored Link core
1 parent 6c68054 commit 322d607

File tree

4 files changed

+116
-25
lines changed

4 files changed

+116
-25
lines changed

Linked.jsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
var React = require( 'react' );
2+
3+
exports.Input = ( { invalid = 'invalid', className = '', valueLink, checkedLink, ...props } ) =>{
4+
const type = props.type,
5+
link = valueLink || checkedLink;
6+
7+
switch( type ){
8+
case 'checkbox':
9+
return <input {...props}
10+
className={ className }
11+
checked={ link.value }
12+
onChange={ e => link.set( Boolean( e.target.checked ) ) }/>;
13+
14+
case 'radio' :
15+
return <input {...props}
16+
className={ className }
17+
checked={ link.value === props.value }
18+
onChange={ e => e.target.checked && link.set( props.value ) }/>;
19+
20+
default:
21+
return <input {...props}
22+
className={ valueLink.error ? invalid + ' ' + className : className }
23+
value={ valueLink.value }
24+
onChange={ e => valueLink.set( e.target.value ) }/>;
25+
}
26+
};
27+
28+
exports.TextArea = ( { invalid = 'invalid', className = '', valueLink, ...props } ) => (
29+
<textarea {...props}
30+
className={ valueLink.error ? invalid + ' ' + className : className }
31+
value={ valueLink.value }
32+
onChange={ e => valueLink.set( e.target.value ) }/>
33+
);
34+
35+
exports.Select = ( { valueLink, children, ...props } ) => (
36+
<select {...props}
37+
value={ valueLink.value }
38+
onChange={ e => valueLink.set( e.target.value ) }>
39+
{ children }
40+
</select>
41+
);
42+
43+
exports.Radio = ({ className = 'radio', checkedLink }) => (
44+
<div className={ className + ( checkedLink.value ? ' selected' : '' ) }
45+
onClick = { checkedLink.action( () => true ) }
46+
/>
47+
);
48+
49+
exports.Checkbox = ({ className = 'checkbox', checkedLink }) => (
50+
<div className={ className + ( checkedLink.value ? ' selected' : '' ) }
51+
onClick = { checkedLink.action( x => !x ) }
52+
/>
53+
);

example/index.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Test </title>
6+
</head>
7+
<body>
8+
9+
</body>
10+
</html>

index.js

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@
33
* (c) 2016 Vlad Balin & Volicon, MIT License
44
*/
55

6-
function Link( value, set, error ){
7-
this.value = value;
8-
this.requestChange = set || doNothing;
9-
this.validationError = error;
6+
function Link( value, set ){
7+
this.value = value;
8+
this.set = set || doNothing;
109
}
1110

1211
// create link to component's state attribute
1312
Link.state = function( component, attr ){
1413
return new Link( component.state[ attr ], function( x ){
15-
var nextState = {};
14+
var nextState = {};
1615
nextState[ attr ] = x;
1716
component.setState( nextState );
18-
});
17+
} );
1918
};
2019

2120
module.exports = Link;
@@ -25,30 +24,46 @@ function doNothing( x ){ }
2524
var defaultError = 'Invalid value';
2625

2726
Link.prototype = {
28-
value : null,
29-
validationError : null,
30-
requestChange : doNothing,
27+
// Core link API
28+
// ---------------------------------------------
29+
value : void 0,
30+
set : doNothing,
3131

32-
set : function( x ){ this.requestChange( x ); },
33-
toggle : function(){ this.requestChange( !this.value ); },
34-
35-
// create function which updates the link
32+
// Immediately update the link
3633
update : function( transform ){
34+
var nextValue = transform( link.value );
35+
nextValue === void 0 || link.set( nextValue );
36+
},
37+
38+
// Create action function which will updates the link
39+
action : function( transform ){
3740
var link = this;
38-
return function(){
39-
var nextValue = transform( link.value );
40-
nextValue === void 0 || link.requestChange( nextValue );
41-
}
41+
return function(){ link.update( transform ) };
4242
},
4343

44+
// React backward compatibility shim
45+
requestChange : function( x ){ this.set( x ); },
46+
47+
// DEPRECATED: Backward compatibility shim
48+
toggle : function(){ this.set( !this.value ); },
49+
50+
// Validation API
51+
// --------------------------------------------------
52+
error : void 0,
53+
54+
// DEPRECATED: backward compatibility shim
55+
get validationError(){ return this.error },
56+
4457
check : function( whenValid, error ){
45-
if( !this.validationError && !whenValid( this.value ) ){
46-
this.validationError = error || defaultError;
58+
if( !this.error && !whenValid( this.value ) ){
59+
this.error = error || defaultError;
4760
}
4861

4962
return this;
5063
},
5164

65+
// Link transformations
66+
// --------------------------------------------------
5267
// create boolean link to enclosed array element
5368
contains : function( element ){
5469
var link = this;
@@ -57,7 +72,7 @@ Link.prototype = {
5772
var next = Boolean( x );
5873
if( this.value !== next ){
5974
var arr = link.value;
60-
link.requestChange( x ? arr.concat( element ) : without( arr, element ) );
75+
link.set( x ? arr.concat( element ) : without( arr, element ) );
6176
}
6277
} );
6378
},
@@ -67,7 +82,7 @@ Link.prototype = {
6782
var link = this;
6883

6984
return new Link( this.value === asTrue, function( x ){
70-
link.requestChange( x ? asTrue : null );
85+
link.set( x ? asTrue : null );
7186
} );
7287
},
7388

@@ -80,7 +95,7 @@ Link.prototype = {
8095
var objOrArr = link.value;
8196
objOrArr = clone( objOrArr );
8297
objOrArr[ key ] = x;
83-
link.requestChange( objOrArr );
98+
link.set( objOrArr );
8499
}
85100
} );
86101
},
@@ -93,9 +108,12 @@ Link.prototype = {
93108

94109
// dummies for compatibility with nestedtypes object model...
95110
constructor : Link,
96-
initialize : function( value, set, error ){}
111+
initialize : function( value, set, error ){}
97112
};
98113

114+
// Tools
115+
// ============================================
116+
99117
function mapObject( link, object, fun ){
100118
var res = [];
101119

@@ -143,7 +161,11 @@ function clone( objOrArray ){
143161
var proto = objOrArray && Object.getPrototypeOf( objOrArray );
144162

145163
if( proto === Array.prototype ) return objOrArray.slice();
146-
if( proto === Object.prototype ) return Object.assign( {}, objOrArray );
164+
if( proto === Object.prototype ){
165+
var x = {};
166+
for( var i in objOrArray ) x[ i ] = objOrArray[ i ];
167+
return x;
168+
}
147169

148170
return objOrArray;
149171
}

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,11 @@
2626
"bugs": {
2727
"url": "https://github.com/Volicon/valuelink/issues"
2828
},
29-
"homepage": "https://github.com/Volicon/valuelink#readme"
29+
"homepage": "https://github.com/Volicon/valuelink#readme",
30+
"devDependencies": {
31+
"babel": "^6.5.2",
32+
"react": "^0.14.7",
33+
"react-dom": "^0.14.7",
34+
"webpack": "^1.12.14"
35+
}
3036
}

0 commit comments

Comments
 (0)