├── .gitignore
├── .jshintrc
├── .travis.yml
├── README.md
├── bower.json
├── dist
└── react-kendo.js
├── lib
├── KendoTemplate.js
├── KendoWidgetMixin.js
├── index.js
└── widgets
│ ├── Grid.js
│ └── index.js
├── package.json
└── test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw*
2 | node_modules
3 |
4 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "indent": 2,
3 | "maxdepth": 6,
4 | "maxlen": 120,
5 | "esnext": true,
6 | "expr": true,
7 | "trailing": true,
8 | "node": true,
9 | "esnext": true,
10 | "globals": {
11 | "describe": true,
12 | "it": true,
13 | "before": true,
14 | "after": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '4.2'
4 |
5 | sudo: false
6 |
7 | notifications:
8 | email: false
9 |
10 | before_script:
11 | - npm install react react-dom lodash
12 |
13 | deploy:
14 | provider: npm
15 | email: me@traviswebb.com
16 | api_key:
17 | secure: g8+dmH4cRtJCyHQbQteKTETRDfCUTZtD4o1QyyJNrpnj7CxqUKkgrnBCEOpFMnitXJ59WDv2/yCMhyLEFIdwhnYLFef2mILQwMRtuV0u5asPp5o6zjtdfl04ILPml5Fh4qb7JuUCGz7IT23NXlIjgOxqk+5c1ZGAF+duROTrU+0=
18 | on:
19 | tags: true
20 | repo: tjwebb/react-kendo
21 | all_branches: true
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-kendo
2 |
3 | [![npm version][npm-image]][npm-url]
4 | [![Build status][travis-image]][travis-url]
5 | [![Dependency Status][daviddm-image]][daviddm-url]
6 |
7 | React Component Library for Kendo UI Widgets. There exists a React Component
8 | named for every Kendo widget in the
9 | [kendo.ui](http://docs.telerik.com/kendo-ui/api/javascript/ui/ui) and [kendo.ui.mobile](http://docs.telerik.com/kendo-ui/api/javascript/mobile/application) namespaces.
10 | Tested on React 0.13 and KendoUI 2014.3.1411.
11 |
12 | ## Install
13 |
14 | ```sh
15 | $ npm install react-kendo --save
16 | ```
17 |
18 | ```html
19 |
20 |
21 |
22 | ```
23 |
24 | Please note: Kendo Professional Components require
25 | [a License](http://www.telerik.com/purchase/kendo-ui).
26 |
27 | ## Usage
28 | ```js
29 | var React = require('react');
30 | var k = React.Kendo = require('react-kendo');
31 |
32 | /**
33 | * Instead of, e.g.
34 | * $('#my-splitter').kendoSplitter(splitterOptions);
35 | */
36 | var splitterOptions = {
37 | orientation: 'horizontal',
38 | panes: [
39 | { collapsible: false, size: '300px' },
40 | { resizable: true }
41 | ]
42 | };
43 | var treeOptions = { /* ... */ };
44 | var gridOptions = { /* ... */ };
45 |
46 | var Workstation = React.createClass({
47 | render: function () {
48 | return (
49 |
50 |
51 |
52 |
53 | );
54 | }
55 | });
56 | ```
57 |
58 | ## Properties
59 |
60 | ### `options`
61 | The main Kendo options object that is sent into the constructor. e.g.
62 | `$('#my-splitter').kendoSplitter(options);`
63 |
64 | ### `tag`
65 | The `tag` property specifies the html tag that the Kendo widget will be bound
66 | to. This is `div` by default, but can be set to
67 | [any tag supported by React](http://facebook.github.io/react/docs/tags-and-attributes.html#html-elements).
68 |
69 | ### `reactive`
70 | Version 0.13 and later support automatically re-initializing the Kendo Widget
71 | when the `options` property is updated. This is useful for re-loading Grids
72 | with new data, among other things. This is `false` by default.
73 |
74 | ### `debug`
75 | Set `debug=true` to log detailed information on the lifecycle events of your
76 | react-kendo component.
77 |
78 | ## Additional Components
79 |
80 | ### `React.Kendo.Template`
81 |
82 | A React Component that represents a [Kendo Template](http://docs.telerik.com/kendo-ui/framework/templates/overview).
83 | Easily create a Kendo Template from a React Component. Additionally mixin
84 | `React.Kendo.TemplateMixin`.
85 |
86 | ```js
87 | var k = React.Kendo;
88 | var MyListItem = React.createClass({
89 | mixins: [
90 | k.TemplateMixin
91 | ],
92 | render: function () {
93 | var item = this.props.item;
94 | return (
95 | {item.title}
96 | );
97 | }
98 | });
99 | var KendoList = React.createClass({
100 | render: function () {
101 | return (
102 | );
105 | }
106 | } />
107 | );
108 | }
109 | });
110 | ```
111 |
112 |
113 | ## Supplemental Functions
114 |
115 | `react-kendo` also includes some extra functionality that isn't included in
116 | Kendo. These functions are added to the Kendo components via React mixins.
117 |
118 |
119 | ### `Grid.enableDraggableRows(group, options)`
120 |
121 | Invoke this function to make Grid rows draggable. This is not possible by
122 | default in the kendo-ui library.
123 |
124 | ```js
125 | var k = React.Kendo;
126 | var KendoList = React.createClass({
127 | componentDidMount: function () {
128 | this.refs.grid.enableDraggableRows('myGroup', {
129 | drag: function (e) {
130 | // some custom stuff
131 | }
132 | });
133 | },
134 | render: function () {
135 | return (
136 |
137 | );
138 | }
139 | });
140 | ```
141 |
142 | ## License
143 | MIT
144 |
145 | ## Maintained By
146 | [
](http://langa.io)
147 |
148 | [npm-image]: https://img.shields.io/npm/v/react-kendo.svg?style=flat-square
149 | [npm-url]: https://npmjs.org/package/react-kendo
150 | [travis-image]: https://img.shields.io/travis/tjwebb/react-kendo.svg?style=flat-square
151 | [travis-url]: https://travis-ci.org/tjwebb/react-kendo
152 | [daviddm-image]: http://img.shields.io/david/tjwebb/react-kendo.svg?style=flat-square
153 | [daviddm-url]: https://david-dm.org/tjwebb/react-kendo
154 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-kendo",
3 | "version": "0.13.1",
4 | "description": "React Component Library for Kendo UI Widgets. There exists a React Component named for every Kendo widget in the kendo.ui namespace. Tested on React 0.12 and KendoUI 2014.3.1411.",
5 | "homepage": "https://github.com/tjwebb/react-kendo",
6 | "main": "dist/react-kendo.js",
7 | "authors": [
8 | "Travis Webb "
9 | ],
10 | "moduleType": [
11 | "node"
12 | ],
13 | "keywords": [
14 | "react",
15 | "kendo",
16 | "react.js",
17 | "react-component",
18 | "kendo-ui",
19 | "telerik",
20 | "components",
21 | "widgets"
22 | ],
23 | "license": "MIT",
24 | "ignore": [
25 | "**/.*",
26 | "node_modules",
27 | "bower_components",
28 | "test",
29 | "tests"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/dist/react-kendo.js:
--------------------------------------------------------------------------------
1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ReactKendo = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o tr',
203 | group: group,
204 | cursorOffset: {
205 | top: 0,
206 | left: 0
207 | },
208 | hint: function (e) {
209 | // XXX clean up
210 | return $('');
211 | },
212 | dragend: function (e) {
213 | if (e.sender.dropped) {
214 | this.enableDraggableRows(group, options);
215 | }
216 | }.bind(this)
217 | }));
218 | }
219 | };
220 |
221 | module.exports = Grid;
222 |
223 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
224 | },{}],5:[function(require,module,exports){
225 | module.exports = {
226 | Grid: require('./Grid')
227 | };
228 |
229 | },{"./Grid":4}]},{},[3])(3)
230 | });
--------------------------------------------------------------------------------
/lib/KendoTemplate.js:
--------------------------------------------------------------------------------
1 | var ReactDOMServer = require('react-dom/server');
2 |
3 | var KendoTemplate = function (component) {
4 | return ReactDOMServer.renderToStaticMarkup(component);
5 | };
6 | KendoTemplate.wrap = function (component) {
7 | return function (props) {
8 | return KendoTemplate(component(props));
9 | };
10 | };
11 |
12 | module.exports = KendoTemplate;
13 |
--------------------------------------------------------------------------------
/lib/KendoWidgetMixin.js:
--------------------------------------------------------------------------------
1 | /* global kendo */
2 |
3 | var React = require('react');
4 | var ReactDOM = require('react-dom');
5 | var _ = require('lodash');
6 | var reactTags = _.keys(React.DOM);
7 |
8 | function mountKendoWidget (component, widget) {
9 | component.$elem[widget](component.props.options);
10 | return component.$elem.data(widget);
11 | }
12 |
13 | /**
14 | * Use for all Kendo objects that inherit from kendo.ui.Widget
15 | *
16 | * @param widget e.g. 'kendoGrid' for Grid
17 | */
18 | var KendoWidgetMixin = function (widget) {
19 | return {
20 |
21 | propTypes: {
22 | options: React.PropTypes.object,
23 | debug: React.PropTypes.bool,
24 | tag: React.PropTypes.oneOf(reactTags).isRequired
25 | },
26 |
27 | getDefaultProps: function () {
28 | return {
29 | options: { },
30 | debug: false,
31 | reactive: false,
32 | tag: 'div'
33 | };
34 | },
35 |
36 | componentWillMount: function () {
37 | if (this.props.debug) console.log('willMount kendo widget', widget, '...');
38 | },
39 |
40 | /**
41 | * Initialize Kendo component
42 | */
43 | componentDidMount: function () {
44 | if (this.props.debug) console.log('kendo widget mounting... ', widget);
45 |
46 | this.elem = this.refs.elem;
47 | this.$elem = $(this.elem);
48 | this.$widget = mountKendoWidget(this, widget);
49 |
50 | if (this.props.debug) console.log('kendo widget mounted:', widget, ', widget=', this.$widget);
51 | if (this.props.debug) console.log('elem=', this.elem);
52 | if (this.props.debug) console.log('$elem=', this.$elem);
53 | },
54 |
55 | componentWillUpdate: function () {
56 | if (this.props.debug) console.log('willUpdate kendo widget', widget, '...');
57 | },
58 |
59 | /**
60 | * Pass updated options into kendo widget
61 | */
62 | componentDidUpdate: function () {
63 | if (this.props.debug) console.log('didUpdate kendo widget', widget);
64 | if (this.props.debug) console.log('new options:', this.props.options);
65 |
66 | if (!this.props.reactive) return;
67 |
68 | if (this.props.debug) console.log('[', widget, '] refreshing "reactive" widget...');
69 |
70 | this.$widget.unbind();
71 | if (this.$widget.element) {
72 | kendo.destroy(this.$widget);
73 | }
74 | if (this.$widget.dataSource) {
75 | this.$widget.dataSource.unbind('change', this.$widget._refreshHandler);
76 | this.$widget.dataSource.unbind('error', this.$widget._errorHandler);
77 | }
78 |
79 | this.$elem.empty();
80 | this.$widget = mountKendoWidget(this, widget);
81 | },
82 |
83 | /**
84 | * Destroy kendo widget
85 | */
86 | componentWillUnmount: function () {
87 | if (this.props.debug) console.log('unmounting kendo widget', widget, '...');
88 |
89 | this.$widget.unbind();
90 | if (this.$widget.element) {
91 | kendo.destroy(this.$widget);
92 | }
93 |
94 | if (this.$widget.dataSource) {
95 | this.$widget.dataSource.unbind('change', this.$widget._refreshHandler);
96 | this.$widget.dataSource.unbind('error', this.$widget._errorHandler);
97 | }
98 |
99 | if (this.props.debug) console.log('kendo widget unmounted:', widget);
100 | },
101 |
102 | /**
103 | * Accessor function for the Kendo Widget object.
104 | */
105 | getWidget: function () {
106 | return this.$widget;
107 | },
108 |
109 | getElement: function () {
110 | return this.$elem;
111 | },
112 |
113 | /**
114 | * Default Kendo widget renderer
115 | */
116 | render: function () {
117 | var other = _.omit(this.props, [ 'options', 'children', 'tag' ]);
118 | other.ref = "elem";
119 | return React.DOM[this.props.tag](other, this.props.children);
120 | }
121 | };
122 | };
123 |
124 | module.exports = KendoWidgetMixin;
125 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | var _ = require('lodash');
2 | var React = require('react');
3 | var KendoWidgetMixin = require('./KendoWidgetMixin');
4 | var widgetMixins = require('./widgets');
5 | var kendo = global.kendo || require('kendo');
6 |
7 | if (!kendo || !kendo.ui) {
8 | throw new Error('kendo.ui not found');
9 | }
10 |
11 | function kendoWidgetName(prefix, name) {
12 | return 'kendo' + prefix + name;
13 | }
14 |
15 | function buildComponent (widget, name, prefix) {
16 | var mixins = [
17 | KendoWidgetMixin(kendoWidgetName(prefix, name))
18 | ];
19 | if (widgetMixins[name]) {
20 | mixins.push(widgetMixins[name]);
21 | }
22 | return React.createClass({
23 | mixins: mixins
24 | });
25 | }
26 |
27 | var KendoUi = _.mapValues(kendo.ui, function (widget, name) {
28 | return buildComponent(widget, name, '');
29 | });
30 |
31 | var KendoDataViz = _.mapValues(kendo.dataviz && kendo.dataviz.ui, function (widget, name) {
32 | return buildComponent(widget, name, '');
33 | });
34 |
35 | var KendoMobileUi = _.mapValues(kendo.mobile && kendo.mobile.ui, function (widget, name) {
36 | return buildComponent(widget, name, 'Mobile');
37 | });
38 |
39 | module.exports = _.extend({
40 | Template: require('./KendoTemplate'),
41 | mobile: KendoMobileUi,
42 | dataviz: KendoDataViz
43 | },
44 | KendoUi
45 | );
46 |
--------------------------------------------------------------------------------
/lib/widgets/Grid.js:
--------------------------------------------------------------------------------
1 | /* global kendo */
2 |
3 | var React = require('react');
4 | var _ = require('lodash');
5 |
6 | var Grid = {
7 | /**
8 | * @param group draggable group
9 | * @param options
10 | */
11 | enableDraggableRows: function (group, options) {
12 | this.getWidget().table.kendoDraggable(_.defaults(options || { }, {
13 | filter: 'tbody > tr',
14 | group: group,
15 | cursorOffset: {
16 | top: 0,
17 | left: 0
18 | },
19 | hint: function (e) {
20 | // XXX clean up
21 | return $('');
22 | },
23 | dragend: function (e) {
24 | if (e.sender.dropped) {
25 | this.enableDraggableRows(group, options);
26 | }
27 | }.bind(this)
28 | }));
29 | }
30 | };
31 |
32 | module.exports = Grid;
33 |
--------------------------------------------------------------------------------
/lib/widgets/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | Grid: require('./Grid')
3 | };
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-kendo",
3 | "version": "0.14.0",
4 | "description": "React Component Library for Kendo UI Widgets. There exists a React Component named for every Kendo widget in the kendo.ui namespace. Tested on React 0.12 and KendoUI 2014.3.1411.",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "dist": "browserify lib/index.js -o dist/react-kendo.js --standalone ReactKendo -t browserify-shim",
8 | "test": "mocha --reporter spec"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/tjwebb/react-kendo.git"
13 | },
14 | "keywords": [
15 | "react",
16 | "kendo",
17 | "react.js",
18 | "react-component",
19 | "kendo-ui",
20 | "telerik",
21 | "components",
22 | "widgets"
23 | ],
24 | "author": "Travis Webb ",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/tjwebb/react-kendo/issues"
28 | },
29 | "homepage": "https://github.com/tjwebb/react-kendo",
30 | "peerDependencies": {
31 | "react": ">=0.14.0",
32 | "react-dom": ">=0.14.0",
33 | "lodash": ">=3.0.0"
34 | },
35 | "devDependencies": {
36 | "browserify": "^11.2.0",
37 | "browserify-shim": "^3.8.10",
38 | "jsdom": "^7.0.1",
39 | "mocha": "^2.3.3"
40 | },
41 | "browserify-shim": {
42 | "react": "global:React",
43 | "react-dom/server": "global:React",
44 | "react-dom": "global:ReactDOM",
45 | "lodash": "global:_"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | var _ = require('lodash');
2 | var assert = require('assert');
3 | var jsdom = require('jsdom');
4 |
5 | describe('react-kendo', function () {
6 | var env;
7 |
8 | describe('pre-requisites', function () {
9 | it('should check prerequisite existence of kendo.ui', function () {
10 | assert.throws(function () {
11 | require('./');
12 | }, Error);
13 | });
14 | });
15 |
16 | describe('sanity', function () {
17 |
18 | before(function (done) {
19 | this.timeout(20000);
20 | env = jsdom.env({
21 | html: '',
22 | scripts: [
23 | 'https://code.jquery.com/jquery-2.1.3.min.js',
24 | 'http://cdn.kendostatic.com/2014.3.1411/js/kendo.all.min.js'
25 | ],
26 | done: function (err, window) {
27 | global.kendo = window.kendo;
28 | done(err);
29 | }
30 | });
31 | });
32 |
33 | describe('kendo.ui', function () {
34 | it('should load widgets', function () {
35 | var k = require('./');
36 | assert(_.isObject(k));
37 | assert(k.Grid);
38 | assert(k.Splitter);
39 | assert(k.TreeView);
40 | });
41 | });
42 |
43 | describe('kendo.mobile.ui', function () {
44 | it('should load widgets', function () {
45 | var k = require('./');
46 | assert(_.isObject(k.mobile));
47 | assert(k.mobile.Widget);
48 | });
49 | });
50 |
51 | describe('kendo.dataviz.ui', function () {
52 | it('should load widgets', function () {
53 | var k = require('./');
54 | assert(_.isObject(k.dataviz));
55 | assert(k.dataviz.Chart);
56 | });
57 | });
58 |
59 | });
60 | });
61 |
--------------------------------------------------------------------------------