├── .gitignore ├── index.js ├── index-dev.js ├── README.md ├── gulpfile.js ├── assets └── style.css ├── examples ├── index.html └── app.jsx ├── package.json ├── lib └── EditableTextField.jsx └── dist └── EditableTextField.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var EditableTextField = require('./dist/EditableTextField.js'); 4 | 5 | 6 | module.exports = { 7 | EditableTextField : EditableTextField 8 | }; -------------------------------------------------------------------------------- /index-dev.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var EditableTextField = require('./lib/EditableTextField.jsx'); 4 | 5 | 6 | module.exports = { 7 | EditableTextField : EditableTextField 8 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-xeditable 2 | It's [X-editable](http://vitalets.github.io/x-editable) for React. Built using [React-Bootstrap](http://react-bootstrap.github.io/). 3 | This is work in progress. 4 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var browserify = require('browserify'); 2 | var gulp = require('gulp'); 3 | var source = require("vinyl-source-stream"); 4 | var reactify = require('reactify'); 5 | 6 | gulp.task('browserify', function(){ 7 | var b = browserify(); 8 | b.transform(reactify); // use the reactify transform 9 | b.add('./index.js'); 10 | return b.bundle() 11 | .pipe(source('react-x-editable.js')) 12 | .pipe(gulp.dest('./dist')); 13 | }); 14 | -------------------------------------------------------------------------------- /assets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .editable-buttons { 3 | display: inline-block; 4 | vertical-align: top; 5 | margin-left: 7px !important; 6 | zoom: 1; 7 | } 8 | 9 | .editable-click, a.editable-click, a.editable-click:hover { 10 | text-decoration: none; 11 | border-bottom: dashed 1px #0088cc; 12 | } 13 | 14 | .editable-empty, .editable-empty:hover, .editable-empty:focus{ 15 | font-style: italic; 16 | color: #DD1144; 17 | text-decoration: none; 18 | } -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React X-editable Examples 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

React X-editable Examples

15 |

This is how React X-editable looks like.

16 |
17 |
18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/app.jsx: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react'); 4 | 5 | document.addEventListener('DOMContentLoaded', function () { 6 | var XEditable = require('../index.js'); 7 | 8 | var App = React.createClass({ 9 | getInitialState : function () { 10 | return { 11 | project : { 12 | name : 'React X-editable', 13 | description : 'X-editable for React' 14 | } 15 | } 16 | }, 17 | valueUpdated : function (name, value) { 18 | var state = this.state; 19 | state.project[name] = value; 20 | this.setState(state); 21 | }, 22 | render : function () { 23 | return ( 24 |
25 |

Project name:

26 |

Project description:

27 |
28 | ); 29 | } 30 | }) 31 | 32 | React.render(, document.getElementById('content')); 33 | }); 34 | 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-xeditable", 3 | "version": "0.1.3", 4 | "description": "X-Editable for React", 5 | "main": "index.js", 6 | "directories": { 7 | "doc": "docs" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "examples": "./node_modules/beefy/bin/beefy examples/app.jsx --index=examples/index.html -- -t reactify", 12 | "build": "babel lib/ --out-dir dist/." 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/kodbiro/react-xeditable.git" 17 | }, 18 | "keywords" : [ 19 | "react-component", 20 | "react", 21 | "x-editable", 22 | "xeditable", 23 | "react-bootstrap", 24 | "inline editing" 25 | ], 26 | "author": "Luka Mijatović (http://www.kodbiro.com/)", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/kodbiro/react-xeditable/issues" 30 | }, 31 | "browserify": {"transform": ["reactify"]}, 32 | "homepage": "https://github.com/kodbiro/react-xeditable", 33 | "devDependencies": { 34 | "beefy": "^2.1.5", 35 | "browserify": "^10.2.4", 36 | "gulp": "^3.9.0", 37 | "reactify": "^1.0.0", 38 | "vinyl-source-stream": "^1.1.0" 39 | }, 40 | "peerDependencies": { 41 | "react": ">0.13.3", 42 | "react-bootstrap": ">0.23.4" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/EditableTextField.jsx: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react'); 4 | 5 | var Button = require('react-bootstrap').Button; 6 | var OverlayTrigger = require('react-bootstrap').OverlayTrigger; 7 | var Popover = require('react-bootstrap').Popover; 8 | var Input = require('react-bootstrap').Input; 9 | var ButtonToolbar = require('react-bootstrap').ButtonToolbar; 10 | 11 | 12 | var EditableTextField = React.createClass({ 13 | save: function() { 14 | this.props.onUpdate(this.props.name, this.refs.input.getValue()); 15 | this.refs.overlay.hide(); 16 | }, 17 | 18 | cancel: function() { 19 | this.refs.overlay.hide(); 20 | }, 21 | 22 | submit: function(event) { 23 | event.preventDefault(); 24 | this.save(); 25 | }, 26 | 27 | render: function() { 28 | var empty = this.props.value === ""; 29 | var linkText = empty ? 'Empty' : this.props.value; 30 | var linkClass = empty ? 'editable-click editable-empty' : 'editable-click'; 31 | var popover = 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 |
; 42 | 43 | return ( 44 | 45 | {linkText} 46 | 47 | ); 48 | } 49 | }); 50 | 51 | module.exports = EditableTextField; 52 | -------------------------------------------------------------------------------- /dist/EditableTextField.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react'); 4 | 5 | var Button = require('react-bootstrap').Button; 6 | var OverlayTrigger = require('react-bootstrap').OverlayTrigger; 7 | var Popover = require('react-bootstrap').Popover; 8 | var Input = require('react-bootstrap').Input; 9 | var ButtonToolbar = require('react-bootstrap').ButtonToolbar; 10 | 11 | var EditableTextField = React.createClass({ 12 | displayName: 'EditableTextField', 13 | 14 | save: function save() { 15 | this.props.onUpdate(this.props.name, this.refs.input.getValue()); 16 | this.refs.overlay.hide(); 17 | }, 18 | 19 | cancel: function cancel() { 20 | this.refs.overlay.hide(); 21 | }, 22 | 23 | submit: function submit(event) { 24 | event.preventDefault(); 25 | this.save(); 26 | }, 27 | 28 | render: function render() { 29 | var empty = this.props.value === ""; 30 | var linkText = empty ? 'Empty' : this.props.value; 31 | var linkClass = empty ? 'editable-click editable-empty' : 'editable-click'; 32 | var popover = React.createElement( 33 | Popover, 34 | null, 35 | React.createElement( 36 | 'form', 37 | { className: 'form-inline', onSubmit: this.submit }, 38 | React.createElement( 39 | Input, 40 | { type: 'text', ref: 'input', placeholder: 'Empty', className: 'input-sm', defaultValue: this.props.value }, 41 | React.createElement( 42 | ButtonToolbar, 43 | { className: 'editable-buttons' }, 44 | React.createElement( 45 | Button, 46 | { bsStyle: 'primary', className: 'btn-sm', onClick: this.save }, 47 | React.createElement('i', { className: 'glyphicon glyphicon-ok' }) 48 | ), 49 | React.createElement( 50 | Button, 51 | { bsStyle: 'default', className: 'btn-sm', onClick: this.cancel }, 52 | React.createElement('i', { className: 'glyphicon glyphicon-remove' }) 53 | ) 54 | ) 55 | ) 56 | ) 57 | ); 58 | 59 | return React.createElement( 60 | OverlayTrigger, 61 | { ref: 'overlay', trigger: 'click', rootClose: true, placement: 'bottom', overlay: popover }, 62 | React.createElement( 63 | 'a', 64 | { href: 'javascript:;', className: linkClass }, 65 | linkText 66 | ) 67 | ); 68 | } 69 | }); 70 | 71 | module.exports = EditableTextField; --------------------------------------------------------------------------------