Skip to content

Commit 69bbe9d

Browse files
committed
fix: ConfigUtils: remove renderToStrting
1 parent 9d0d098 commit 69bbe9d

File tree

10 files changed

+187
-60
lines changed

10 files changed

+187
-60
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## [0.12.3] - 2020-04-29
2+
- fixed: use ReactDOM.render instead of renderToString
3+
14
## [0.12.1] - 2020-04-09
25

36
### Changed

TODO.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
React Tabulator
44

5+
<em>[TODO.md spec & Kanban Board](http://todomd.org)</em>
6+
57
### Todo
68

79
- [ ] example for Add Row

lib/ConfigUtils.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,4 @@ export interface IProps {
103103
downloadComplete?: any;
104104
options?: any;
105105
}
106-
export declare const propsToOptions: (props: any) => any;
106+
export declare const propsToOptions: (props: any) => Promise<any>;

lib/ConfigUtils.js

Lines changed: 86 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,92 @@
11
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
var __generator = (this && this.__generator) || function (thisArg, body) {
12+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14+
function verb(n) { return function (v) { return step([n, v]); }; }
15+
function step(op) {
16+
if (f) throw new TypeError("Generator is already executing.");
17+
while (_) try {
18+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19+
if (y = 0, t) op = [op[0] & 2, t.value];
20+
switch (op[0]) {
21+
case 0: case 1: t = op; break;
22+
case 4: _.label++; return { value: op[1], done: false };
23+
case 5: _.label++; y = op[1]; op = [0]; continue;
24+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
25+
default:
26+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30+
if (t[2]) _.ops.pop();
31+
_.trys.pop(); continue;
32+
}
33+
op = body.call(thisArg, _);
34+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36+
}
37+
};
238
exports.__esModule = true;
3-
var server_1 = require("react-dom/server");
39+
var Es6Promise = require("es6-promise");
40+
var react_dom_1 = require("react-dom");
441
// .prettierignore (to keep relevant props together)
542
var NOOPS = function () { };
43+
function syncRender(comp, el) {
44+
return new Es6Promise.Promise(function (resolve, reject) {
45+
react_dom_1.render(comp, el, function () {
46+
resolve(el);
47+
});
48+
});
49+
}
650
// get callbacks from props (default: NOOP) to set them to Tabulator options later.
7-
exports.propsToOptions = function (props) {
8-
var output = {};
9-
var defaultOptions = ['height', 'layout', 'layoutColumnsOnNewData', 'columnMinWidth', 'columnVertAlign',
10-
'resizableColumns', 'resizableRows', 'autoResize', 'tooltips', 'tooltipsHeader', 'tooltipGenerationMode',
11-
'initialSort', 'initialFilter', 'initialHeaderFilter', 'footerElement', 'index', 'keybindings', 'clipboard', 'clipboardCopyStyled',
12-
'clipboardCopySelector', 'clipboardCopyFormatter', 'clipboardCopyHeader', 'clipboardPasteParser',
13-
'clipboardPasteAction', 'rowFormatter', 'placeholder', 'selectable'];
14-
for (var _i = 0, defaultOptions_1 = defaultOptions; _i < defaultOptions_1.length; _i++) {
15-
var opt = defaultOptions_1[_i];
16-
if (typeof props[opt] !== 'undefined') {
17-
output[opt] = props[opt];
51+
exports.propsToOptions = function (props) { return __awaiter(void 0, void 0, void 0, function () {
52+
var output, defaultOptions, _i, defaultOptions_1, opt, callbackNames, _a, callbackNames_1, callbackName, el;
53+
return __generator(this, function (_b) {
54+
switch (_b.label) {
55+
case 0:
56+
output = {};
57+
defaultOptions = ['height', 'layout', 'layoutColumnsOnNewData', 'columnMinWidth', 'columnVertAlign',
58+
'resizableColumns', 'resizableRows', 'autoResize', 'tooltips', 'tooltipsHeader', 'tooltipGenerationMode',
59+
'initialSort', 'initialFilter', 'initialHeaderFilter', 'footerElement', 'index', 'keybindings', 'clipboard', 'clipboardCopyStyled',
60+
'clipboardCopySelector', 'clipboardCopyFormatter', 'clipboardCopyHeader', 'clipboardPasteParser',
61+
'clipboardPasteAction', 'rowFormatter', 'placeholder', 'selectable'];
62+
for (_i = 0, defaultOptions_1 = defaultOptions; _i < defaultOptions_1.length; _i++) {
63+
opt = defaultOptions_1[_i];
64+
if (typeof props[opt] !== 'undefined') {
65+
output[opt] = props[opt];
66+
}
67+
}
68+
callbackNames = ['tableBuilt', 'rowClick', 'rowDblClick', 'rowContext', 'rowTap', 'rowDblTap', 'rowTapHold',
69+
'rowAdded', 'rowDeleted', 'rowMoved', 'rowUpdated', 'rowSelectionChanged', 'rowSelected', 'rowDeselected', 'rowResized',
70+
'cellClick', 'cellDblClick', 'cellContext', 'cellTap', 'cellDblTap', 'cellTapHold', 'cellEditing', 'cellEdited', 'cellEditCancelled',
71+
'columnMoved', 'columnResized', 'columnTitleChanged', 'columnVisibilityChanged',
72+
'htmlImporting', 'htmlImported', 'dataLoading', 'dataLoaded', 'dataEdited',
73+
'ajaxRequesting', 'ajaxResponse', 'ajaxError', 'dataFiltering', 'dataFiltered', 'dataSorting', 'dataSorted',
74+
'renderStarted', 'renderComplete', 'pageLoaded', 'localized', 'dataGrouping', 'dataGrouped',
75+
'groupVisibilityChanged', 'groupClick', 'groupDblClick', 'groupContext', 'groupTap', 'groupDblTap', 'groupTapHold',
76+
'movableRowsSendingStart', 'movableRowsSent', 'movableRowsSentFailed', 'movableRowsSendingStop', 'movableRowsReceivingStart', 'movableRowsReceived', 'movableRowsReceivedFailed', 'movableRowsReceivingStop',
77+
'validationFailed', 'clipboardCopied', 'clipboardPasted', 'clipboardPasteError',
78+
'downloadDataFormatter', 'downloadReady', 'downloadComplete'];
79+
for (_a = 0, callbackNames_1 = callbackNames; _a < callbackNames_1.length; _a++) {
80+
callbackName = callbackNames_1[_a];
81+
output[callbackName] = props[callbackName] || NOOPS;
82+
}
83+
if (!(typeof props['footerElement'] === 'object')) return [3 /*break*/, 2];
84+
return [4 /*yield*/, syncRender(props['footerElement'], document.createElement('div'))];
85+
case 1:
86+
el = _b.sent();
87+
output['footerElement'] = el.innerHTML;
88+
_b.label = 2;
89+
case 2: return [2 /*return*/, output];
1890
}
19-
}
20-
var callbackNames = ['tableBuilt', 'rowClick', 'rowDblClick', 'rowContext', 'rowTap', 'rowDblTap', 'rowTapHold',
21-
'rowAdded', 'rowDeleted', 'rowMoved', 'rowUpdated', 'rowSelectionChanged', 'rowSelected', 'rowDeselected', 'rowResized',
22-
'cellClick', 'cellDblClick', 'cellContext', 'cellTap', 'cellDblTap', 'cellTapHold', 'cellEditing', 'cellEdited', 'cellEditCancelled',
23-
'columnMoved', 'columnResized', 'columnTitleChanged', 'columnVisibilityChanged',
24-
'htmlImporting', 'htmlImported', 'dataLoading', 'dataLoaded', 'dataEdited',
25-
'ajaxRequesting', 'ajaxResponse', 'ajaxError', 'dataFiltering', 'dataFiltered', 'dataSorting', 'dataSorted',
26-
'renderStarted', 'renderComplete', 'pageLoaded', 'localized', 'dataGrouping', 'dataGrouped',
27-
'groupVisibilityChanged', 'groupClick', 'groupDblClick', 'groupContext', 'groupTap', 'groupDblTap', 'groupTapHold',
28-
'movableRowsSendingStart', 'movableRowsSent', 'movableRowsSentFailed', 'movableRowsSendingStop', 'movableRowsReceivingStart', 'movableRowsReceived', 'movableRowsReceivedFailed', 'movableRowsReceivingStop',
29-
'validationFailed', 'clipboardCopied', 'clipboardPasted', 'clipboardPasteError',
30-
'downloadDataFormatter', 'downloadReady', 'downloadComplete'];
31-
for (var _a = 0, callbackNames_1 = callbackNames; _a < callbackNames_1.length; _a++) {
32-
var callbackName = callbackNames_1[_a];
33-
output[callbackName] = props[callbackName] || NOOPS;
34-
}
35-
if (typeof props['footerElement'] === 'object') {
36-
// convert from JSX to HTML string (tabulator's footerElement accepts string)
37-
output['footerElement'] = server_1.renderToString(props['footerElement']);
38-
}
39-
return output;
40-
};
91+
});
92+
}); };

lib/ReactTabulator.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default class extends React.Component<IProps, Partial<IState>> {
1010
htmlProps: any;
1111
mainId: string;
1212
table: any;
13-
componentDidMount(): void;
13+
componentDidMount(): Promise<void>;
1414
componentWillUnmount(): void;
1515
static getDerivedStateFromProps(props: any, state: any): any;
1616
componentDidUpdate(prevProps: IProps, prevState: IState): void;

lib/ReactTabulator.js

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,42 @@ var __assign = (this && this.__assign) || function () {
2323
};
2424
return __assign.apply(this, arguments);
2525
};
26+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
27+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
28+
return new (P || (P = Promise))(function (resolve, reject) {
29+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
30+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
31+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
32+
step((generator = generator.apply(thisArg, _arguments || [])).next());
33+
});
34+
};
35+
var __generator = (this && this.__generator) || function (thisArg, body) {
36+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
37+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
38+
function verb(n) { return function (v) { return step([n, v]); }; }
39+
function step(op) {
40+
if (f) throw new TypeError("Generator is already executing.");
41+
while (_) try {
42+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
43+
if (y = 0, t) op = [op[0] & 2, t.value];
44+
switch (op[0]) {
45+
case 0: case 1: t = op; break;
46+
case 4: _.label++; return { value: op[1], done: false };
47+
case 5: _.label++; y = op[1]; op = [0]; continue;
48+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
49+
default:
50+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
51+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
52+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
53+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
54+
if (t[2]) _.ops.pop();
55+
_.trys.pop(); continue;
56+
}
57+
op = body.call(thisArg, _);
58+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
59+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
60+
}
61+
};
2662
var __spreadArrays = (this && this.__spreadArrays) || function () {
2763
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
2864
for (var r = Array(s), k = 0, i = 0; i < il; i++)
@@ -61,24 +97,35 @@ var default_1 = /** @class */ (function (_super) {
6197
return _this;
6298
}
6399
default_1.prototype.componentDidMount = function () {
64-
var domEle = ReactDOM.findDOMNode(this.ref); // mounted DOM element
65-
var that = this;
66-
var _a = this.props, columns = _a.columns, data = _a.data, options = _a.options;
67-
var propOptions = ConfigUtils_1.propsToOptions(this.props);
68-
new Tabulator(domEle, __assign(__assign(__assign(__assign({ columns: columns }, propOptions), { layout: 'fitColumns', // fit columns to width of table (optional)
69-
tableBuilding: function () {
70-
that.table = this; // keep table instance
71-
that.props.tableBuilding ? that.props.tableBuilding() : '';
72-
},
73-
dataLoaded: function () {
74-
that.props.dataLoaded ? that.props.dataLoaded() : '';
75-
}, invalidOptionWarnings: false }), options), { // props.options are passed to Tabulator's options.
76-
data: data }));
77-
// await table.setData(data);
78-
// console.log('- componentDidMount');
79-
if (data && data.length > 0) {
80-
this.setState({ data: data });
81-
}
100+
return __awaiter(this, void 0, void 0, function () {
101+
var domEle, that, _a, columns, data, options, propOptions;
102+
return __generator(this, function (_b) {
103+
switch (_b.label) {
104+
case 0:
105+
domEle = ReactDOM.findDOMNode(this.ref);
106+
that = this;
107+
_a = this.props, columns = _a.columns, data = _a.data, options = _a.options;
108+
return [4 /*yield*/, ConfigUtils_1.propsToOptions(this.props)];
109+
case 1:
110+
propOptions = _b.sent();
111+
new Tabulator(domEle, __assign(__assign(__assign(__assign({ columns: columns }, propOptions), { layout: 'fitColumns', // fit columns to width of table (optional)
112+
tableBuilding: function () {
113+
that.table = this; // keep table instance
114+
that.props.tableBuilding ? that.props.tableBuilding() : '';
115+
},
116+
dataLoaded: function () {
117+
that.props.dataLoaded ? that.props.dataLoaded() : '';
118+
}, invalidOptionWarnings: false }), options), { // props.options are passed to Tabulator's options.
119+
data: data }));
120+
// await table.setData(data);
121+
// console.log('- componentDidMount');
122+
if (data && data.length > 0) {
123+
this.setState({ data: data });
124+
}
125+
return [2 /*return*/];
126+
}
127+
});
128+
});
82129
};
83130
default_1.prototype.componentWillUnmount = function () {
84131
this.table.destroy();

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-tabulator",
3-
"version": "0.12.2",
3+
"version": "0.12.3",
44
"description": "React Tabulator is based on tabulator - a JS table library with many advanced features.",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",
@@ -53,6 +53,7 @@
5353
"react-dom": ">=15.6.2 || ^16.0.0"
5454
},
5555
"devDependencies": {
56+
"@types/es6-promise": "^3.3.0",
5657
"@types/react": "^16.4.14",
5758
"@types/react-dom": "^16.0.9",
5859
"awesome-typescript-loader": "^5.2.1",

src/ConfigUtils.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { renderToString } from 'react-dom/server';
1+
import * as Es6Promise from 'es6-promise' // without this, 'yarn build' will complain about Promise.
2+
import { render } from 'react-dom';
23

34
// .prettierignore (to keep relevant props together)
45
const NOOPS = () => {};
@@ -112,8 +113,16 @@ export interface IProps {
112113
options?: any; // Tabulator options object
113114
}
114115

116+
function syncRender(comp: any, el: any): any {
117+
return new Es6Promise.Promise(function(resolve, reject) {
118+
render(comp, el, () => {
119+
resolve(el)
120+
})
121+
});
122+
}
123+
115124
// get callbacks from props (default: NOOP) to set them to Tabulator options later.
116-
export const propsToOptions = (props: any) => {
125+
export const propsToOptions = async (props: any) => {
117126
const output: any = {}
118127

119128
const defaultOptions = ['height', 'layout', 'layoutColumnsOnNewData', 'columnMinWidth', 'columnVertAlign',
@@ -145,7 +154,8 @@ export const propsToOptions = (props: any) => {
145154
}
146155
if (typeof props['footerElement'] === 'object') {
147156
// convert from JSX to HTML string (tabulator's footerElement accepts string)
148-
output['footerElement'] = renderToString(props['footerElement'])
157+
const el = await syncRender(props['footerElement'], document.createElement('div'))
158+
output['footerElement'] = el.innerHTML
149159
}
150160
return output
151161
}

src/ReactTabulator.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ export default class extends React.Component<IProps, Partial<IState>> {
2323
mainId = `tabulator-${+new Date()}-${Math.floor(Math.random() * 9999999)}`; // random id
2424
table: any = null; // will be set once Tabulator instantiated
2525

26-
componentDidMount() {
26+
async componentDidMount() {
2727
const domEle: any = ReactDOM.findDOMNode(this.ref); // mounted DOM element
2828
const that = this;
2929
const { columns, data, options } = this.props;
30-
const propOptions = propsToOptions(this.props);
30+
const propOptions = await propsToOptions(this.props);
3131

3232
new Tabulator(domEle, {
3333
columns,

yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@
8181
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
8282
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
8383

84+
"@types/es6-promise@^3.3.0":
85+
version "3.3.0"
86+
resolved "https://registry.yarnpkg.com/@types/es6-promise/-/es6-promise-3.3.0.tgz#61b55e554fd807b563f158a7986ee53d3a5a5a9d"
87+
integrity sha512-ixCIAEkLUKv9movnHKCzx2rzAJgEnSALDXPrOSSwOjWwXFs0ssSZKan+O2e3FExPPCbX+DfA9NcKsbvLuyUlNA==
88+
dependencies:
89+
es6-promise "*"
90+
8491
"@types/node@*":
8592
version "10.11.7"
8693
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.7.tgz#0e75ca9357d646ca754016ca1d68a127ad7e7300"
@@ -3009,6 +3016,11 @@ es6-iterator@~2.0.3:
30093016
es5-ext "^0.10.35"
30103017
es6-symbol "^3.1.1"
30113018

3019+
es6-promise@*:
3020+
version "4.2.8"
3021+
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
3022+
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
3023+
30123024
es6-promise@^4.0.3:
30133025
version "4.2.5"
30143026
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054"

0 commit comments

Comments
 (0)