@cocreate/render 1.9.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/demo/render.html +42 -0
- package/package.json +1 -1
- package/src/index.js +210 -51
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
# [1.11.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.10.0...v1.11.0) (2022-07-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* if templateId setAttribute ([41e30b3](https://github.com/CoCreate-app/CoCreate-render/commit/41e30b3a748aa8900d9f9397584f14052d637197))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* getValueFromObject supports deeply nested array and objects ([db7fefd](https://github.com/CoCreate-app/CoCreate-render/commit/db7fefd81a908ba6f68dbf4c43d62639aa73e3f8))
|
|
12
|
+
* observe new elements with atrribute render, if elements detected replace placholders with values ([90d7d98](https://github.com/CoCreate-app/CoCreate-render/commit/90d7d982eedf83b194cfae0704d06e110914ca52))
|
|
13
|
+
|
|
14
|
+
# [1.10.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.2...v1.10.0) (2022-07-14)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* renderMap function to apply map containing placeholder to node object in order to render new values ([7afffa0](https://github.com/CoCreate-app/CoCreate-render/commit/7afffa07b2cc1dd562e96d1ee558433d3f6d043a))
|
|
20
|
+
|
|
21
|
+
## [1.9.2](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.1...v1.9.2) (2022-07-10)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* use dataOriginal if path includes collection ([e6b9288](https://github.com/CoCreate-app/CoCreate-render/commit/e6b92886bad560fa64e487609c69f37268d87587))
|
|
27
|
+
|
|
1
28
|
## [1.9.1](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.0...v1.9.1) (2022-07-08)
|
|
2
29
|
|
|
3
30
|
|
package/demo/render.html
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Render | CoCreateJS</title>
|
|
4
|
+
|
|
5
|
+
<!-- CoCreate Favicon -->
|
|
6
|
+
<link rel="icon" href="https://cdn.cocreate.app/favicon.ico" type="image/ico" sizes="16x16">
|
|
7
|
+
</head>
|
|
8
|
+
<style>
|
|
9
|
+
.template{display:none}
|
|
10
|
+
</style>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<body>
|
|
14
|
+
|
|
15
|
+
<div class="template" template_id="abc1">
|
|
16
|
+
<h3>{{collection}}</h3>
|
|
17
|
+
<h3>{{data._id}}</h3>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<pre>
|
|
21
|
+
<h1>Paste in your browser console</h1>
|
|
22
|
+
|
|
23
|
+
/** Example **/
|
|
24
|
+
CoCreate.render.data({
|
|
25
|
+
selector: '[template_id=abc1]',
|
|
26
|
+
data: {
|
|
27
|
+
collection: 'dededede',
|
|
28
|
+
data: {
|
|
29
|
+
_id : '123kijfhgfkel45',
|
|
30
|
+
current_org: ['test1', 'test2', 'test31', 'test3'],
|
|
31
|
+
current: [{name: 'test1w'}, {name: 'test2'}, {name: 'test31'}, {name: 'test3'}]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
</pre>
|
|
38
|
+
|
|
39
|
+
<!-- CoCreate JS CDN -->
|
|
40
|
+
<script src="../../../CoCreateJS/dist/CoCreate.js" ></script>
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
/*globals CustomEvent*/
|
|
2
2
|
import action from '@cocreate/actions';
|
|
3
|
+
import observer from '@cocreate/observer';
|
|
4
|
+
import uuid from '@cocreate/uuid';
|
|
3
5
|
import { queryDocumentSelector } from '@cocreate/utils';
|
|
4
6
|
// import { getValue } from '../../CoCreate-elements/src/getValue';
|
|
5
7
|
// import api from '@cocreate/api';
|
|
6
8
|
|
|
7
9
|
const CoCreateRender = {
|
|
8
|
-
|
|
10
|
+
// Can be called from crud getObjectValueByPath
|
|
9
11
|
__getValueFromObject : function(json, path) {
|
|
10
12
|
try {
|
|
11
13
|
if(typeof json == 'undefined' || !path)
|
|
12
14
|
return false;
|
|
13
|
-
if (path.indexOf('.') == -1)
|
|
15
|
+
if (path.indexOf('.') == -1 && path.includes('collection'))
|
|
14
16
|
json = this.dataOriginal
|
|
17
|
+
if (/\[([0-9]*)\]/g.test(path)) {
|
|
18
|
+
path = path.replace(/\[/g, '.');
|
|
19
|
+
if (path.endsWith(']'))
|
|
20
|
+
path = path.slice(0, -1)
|
|
21
|
+
path = path.replace(/\]./g, '.');
|
|
22
|
+
path = path.replace(/\]/g, '.');
|
|
23
|
+
}
|
|
15
24
|
let jsonData = json, subpath = path.split('.');
|
|
16
25
|
|
|
17
26
|
for (let i = 0; i < subpath.length; i++) {
|
|
@@ -52,7 +61,7 @@ const CoCreateRender = {
|
|
|
52
61
|
}
|
|
53
62
|
},
|
|
54
63
|
|
|
55
|
-
__replaceValue: function(data, inputValue, renderKey) {
|
|
64
|
+
__replaceValue: function(data, inputValue, renderKey, valueType) {
|
|
56
65
|
let isPass = false;
|
|
57
66
|
let self = this;
|
|
58
67
|
let resultValue = null;
|
|
@@ -64,18 +73,8 @@ const CoCreateRender = {
|
|
|
64
73
|
data[renderKey]['collection'] = this.dataOriginal[renderKey]['collection']
|
|
65
74
|
|
|
66
75
|
let value = self.__getValue(data, attr);
|
|
67
|
-
// if (value) {
|
|
68
|
-
// if (value && typeof(value) !== "object") {
|
|
69
|
-
// if (value && !Array.isArray(value)) {
|
|
70
76
|
if (value) {
|
|
71
|
-
// converts object to string
|
|
72
|
-
// if (!Array.isArray(value) && typeof(value) == "object") {
|
|
73
77
|
if (typeof(value) == "object") {
|
|
74
|
-
// let str = '';
|
|
75
|
-
// for (const [key, val] of Object.entries(value)) {
|
|
76
|
-
// str += `${key}: ${val}\n`;
|
|
77
|
-
// }
|
|
78
|
-
|
|
79
78
|
value = this.generateString(value)
|
|
80
79
|
}
|
|
81
80
|
isPass = true;
|
|
@@ -113,33 +112,33 @@ const CoCreateRender = {
|
|
|
113
112
|
},
|
|
114
113
|
|
|
115
114
|
render: function(template, data) {
|
|
116
|
-
let type = template.getAttribute('render-array') || "data";
|
|
117
|
-
const renderKey = template.getAttribute('render-key') || type;
|
|
118
115
|
const self = this;
|
|
119
|
-
|
|
120
|
-
// const arrayData = this.__getValueFromObject(data, type);
|
|
116
|
+
let type = '';
|
|
121
117
|
let arrayData = data;
|
|
122
118
|
|
|
123
119
|
const isRenderObject = template.hasAttribute('render-object');
|
|
124
120
|
if (isRenderObject){
|
|
125
|
-
const renderObject = template.getAttribute('render-object');
|
|
126
|
-
type = renderObject || '
|
|
121
|
+
const renderObject = template.getAttribute('render-object');
|
|
122
|
+
type = renderObject || ''
|
|
127
123
|
}
|
|
128
124
|
|
|
129
125
|
const isRenderArray = template.hasAttribute('render-array');
|
|
130
126
|
if (isRenderArray){
|
|
131
|
-
|
|
127
|
+
var renderArray = template.getAttribute('render-array');
|
|
132
128
|
if (renderArray)
|
|
133
129
|
arrayData = data[renderArray];
|
|
134
|
-
type = renderArray || '
|
|
130
|
+
type = renderArray || '';
|
|
135
131
|
}
|
|
132
|
+
|
|
133
|
+
let renderKey = template.getAttribute('render-key') || type;
|
|
134
|
+
|
|
136
135
|
if (isRenderObject && type) {
|
|
137
|
-
let
|
|
138
|
-
|
|
136
|
+
let Data = self.__getValueFromObject(arrayData, type);
|
|
137
|
+
let array = self.isRenderObject(Data, renderKey)
|
|
138
|
+
for (let item of array) {
|
|
139
139
|
let cloneEl = this.cloneEl(template);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
|
|
140
|
+
self.setValue([cloneEl], item, renderArray, renderKey);
|
|
141
|
+
template.insertAdjacentElement('beforebegin', cloneEl);
|
|
143
142
|
}
|
|
144
143
|
} else {
|
|
145
144
|
|
|
@@ -148,18 +147,16 @@ const CoCreateRender = {
|
|
|
148
147
|
|
|
149
148
|
if (!arrayData) {
|
|
150
149
|
let cloneEl = this.cloneEl(template);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
|
|
150
|
+
self.setValue([cloneEl], data, renderArray, renderKey);
|
|
151
|
+
template.insertAdjacentElement('beforebegin', cloneEl);
|
|
154
152
|
}
|
|
155
153
|
|
|
156
154
|
if(type && Array.isArray(arrayData)) {
|
|
157
155
|
arrayData.forEach((item) => {
|
|
158
156
|
let cloneEl = this.cloneEl(template);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
|
|
157
|
+
let object = self.__createObject(item, renderKey);
|
|
158
|
+
self.setValue([cloneEl], object, renderArray, renderKey);
|
|
159
|
+
template.insertAdjacentElement('beforebegin', cloneEl);
|
|
163
160
|
});
|
|
164
161
|
}
|
|
165
162
|
}
|
|
@@ -167,6 +164,8 @@ const CoCreateRender = {
|
|
|
167
164
|
|
|
168
165
|
isRenderObject: function(data, renderKey) {
|
|
169
166
|
let array = []
|
|
167
|
+
if (!data)
|
|
168
|
+
return array
|
|
170
169
|
for (const [key, value] of Object.entries(data)) {
|
|
171
170
|
let type = 'string';
|
|
172
171
|
if (typeof(value) == "object")
|
|
@@ -181,76 +180,161 @@ const CoCreateRender = {
|
|
|
181
180
|
|
|
182
181
|
cloneEl: function(template) {
|
|
183
182
|
let cloneEl = template.cloneNode(true);
|
|
184
|
-
|
|
183
|
+
|
|
185
184
|
let templateId = cloneEl.getAttribute('template_id');
|
|
185
|
+
if (templateId)
|
|
186
|
+
cloneEl.setAttribute('templateId', templateId);
|
|
187
|
+
|
|
186
188
|
cloneEl.removeAttribute('template_id');
|
|
187
|
-
cloneEl.setAttribute('
|
|
189
|
+
cloneEl.setAttribute('render-clone', '');
|
|
190
|
+
cloneEl.classList.remove('template');
|
|
191
|
+
|
|
192
|
+
if (template.dataOriginal)
|
|
193
|
+
cloneEl.dataOriginal = template.dataOriginal
|
|
194
|
+
|
|
188
195
|
return cloneEl;
|
|
189
196
|
},
|
|
190
197
|
|
|
191
|
-
setValue: function(els, data, renderKey){
|
|
198
|
+
setValue: function(els, data, renderArray, renderKey){
|
|
192
199
|
if (!data) return;
|
|
193
200
|
const that = this;
|
|
194
201
|
Array.from(els).forEach(el => {
|
|
202
|
+
let updateData;
|
|
203
|
+
|
|
195
204
|
if (el.nodeType == 1) {
|
|
205
|
+
if (el.hasAttribute('render-clone')) {
|
|
206
|
+
el.renderData = {...data}
|
|
207
|
+
}
|
|
208
|
+
if (el.renderMap) {
|
|
209
|
+
let placeholder = el.renderMap.get(el)
|
|
210
|
+
if (placeholder){
|
|
211
|
+
renderKey = placeholder.renderKey
|
|
212
|
+
renderArray = placeholder.renderArray
|
|
213
|
+
if (renderArray)
|
|
214
|
+
updateData = data[renderArray][0]
|
|
215
|
+
if (renderKey)
|
|
216
|
+
updateData = {[renderKey]: updateData}
|
|
217
|
+
let textContent = placeholder.placeholder
|
|
218
|
+
let text = that.__replaceValue(updateData, textContent, renderKey, valueType);
|
|
219
|
+
if (text)
|
|
220
|
+
el.innerHTML = placeholder.placeholder
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
196
224
|
Array.from(el.attributes).forEach(attr=>{
|
|
197
225
|
let attr_name = attr.name.toLowerCase();
|
|
198
226
|
let attrValue = attr.value;
|
|
199
|
-
|
|
227
|
+
|
|
228
|
+
let placeholder
|
|
229
|
+
if (attr.renderMap)
|
|
230
|
+
placeholder = attr.renderMap.get(attr)
|
|
231
|
+
else
|
|
232
|
+
that.renderMap(attr, attr.value, renderArray, renderKey)
|
|
233
|
+
|
|
234
|
+
if(placeholder){
|
|
235
|
+
let updateData = data;
|
|
236
|
+
attrValue = placeholder.placeholder;
|
|
237
|
+
renderKey = placeholder.renderKey
|
|
238
|
+
renderArray = placeholder.renderArray
|
|
239
|
+
if (renderArray)
|
|
240
|
+
updateData = data[renderArray][0]
|
|
241
|
+
if (renderKey)
|
|
242
|
+
updateData = {[renderKey]: updateData}
|
|
243
|
+
|
|
244
|
+
attrValue = that.__replaceValue(updateData, attrValue, renderKey);
|
|
245
|
+
}
|
|
246
|
+
else
|
|
247
|
+
attrValue = that.__replaceValue(data, attrValue, renderKey);
|
|
200
248
|
|
|
249
|
+
// ToDo support attibute name replace if has {{}}
|
|
250
|
+
// attr_name = that.__replaceValue(data, attr_name, renderKey);
|
|
251
|
+
|
|
201
252
|
if (attrValue || attrValue == "") {
|
|
202
253
|
el.setAttribute(attr_name, attrValue);
|
|
203
254
|
}
|
|
204
255
|
});
|
|
205
256
|
|
|
206
|
-
if(el.childNodes.length > 0) {
|
|
207
|
-
that.setValue(el.childNodes, data, renderKey);
|
|
257
|
+
if(el.childNodes.length > 0) {
|
|
258
|
+
that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
|
|
208
259
|
}
|
|
209
260
|
if (el.classList.contains('template') && !el.hasAttribute('template_id')) {
|
|
210
261
|
that.render(el, data);
|
|
211
262
|
}
|
|
212
263
|
}
|
|
213
|
-
|
|
264
|
+
|
|
214
265
|
if (el.nodeType == 3) {
|
|
215
266
|
let valueType = el.parentElement.getAttribute('value-type')
|
|
216
|
-
|
|
217
|
-
let
|
|
267
|
+
|
|
268
|
+
let textContent, placeholder, text;
|
|
269
|
+
if (el.renderMap)
|
|
270
|
+
placeholder = el.renderMap.get(el)
|
|
271
|
+
if (placeholder) {
|
|
272
|
+
let updateData = data;
|
|
273
|
+
textContent = placeholder.placeholder
|
|
274
|
+
renderKey = placeholder.renderKey
|
|
275
|
+
renderArray = placeholder.renderArray
|
|
276
|
+
if (renderArray)
|
|
277
|
+
updateData = data[renderArray][0]
|
|
278
|
+
if (renderKey)
|
|
279
|
+
updateData = {[renderKey]: updateData}
|
|
280
|
+
text = that.__replaceValue(updateData, textContent, renderKey, valueType);
|
|
281
|
+
}
|
|
282
|
+
if (!text) {
|
|
283
|
+
textContent = el.textContent;
|
|
284
|
+
that.renderMap(el, textContent, renderArray, renderKey)
|
|
285
|
+
text = that.__replaceValue(data, textContent, renderKey, valueType);
|
|
286
|
+
}
|
|
287
|
+
|
|
218
288
|
if (text || text == "") {
|
|
219
289
|
if (valueType == 'text' || valueType == 'string'){
|
|
220
290
|
el.textContent = text;
|
|
221
291
|
} else {
|
|
222
292
|
const newNode = document.createElement('div');
|
|
223
293
|
newNode.innerHTML = text;
|
|
294
|
+
let parentElement = el.parentElement
|
|
295
|
+
if (!parentElement.renderMap) {
|
|
296
|
+
that.renderMap(parentElement, textContent, renderArray, renderKey)
|
|
297
|
+
} else if (!parentElement['renderMap'].has(parentElement))
|
|
298
|
+
that.renderMap(parentElement, textContent, renderArray, renderKey)
|
|
224
299
|
el.replaceWith(...newNode.childNodes)
|
|
225
300
|
}
|
|
226
301
|
}
|
|
227
302
|
}
|
|
228
|
-
|
|
229
303
|
});
|
|
230
304
|
},
|
|
305
|
+
|
|
306
|
+
renderMap: function(node, placeholder, renderArray, renderKey) {
|
|
307
|
+
if (!node.renderMap) {
|
|
308
|
+
node['renderMap'] = new Map();
|
|
309
|
+
}
|
|
310
|
+
if (placeholder && renderKey)
|
|
311
|
+
node['renderMap'].set(node, {placeholder, renderArray, renderKey})
|
|
312
|
+
},
|
|
231
313
|
|
|
232
314
|
dataOriginal: {},
|
|
233
315
|
data: function({selector, data, elements}) {
|
|
234
|
-
this.dataOriginal = data;
|
|
316
|
+
this.dataOriginal = {...data};
|
|
317
|
+
this.dataString = {...data};
|
|
318
|
+
delete this.dataOriginal.data
|
|
319
|
+
|
|
320
|
+
for (let element of elements)
|
|
321
|
+
element.dataOriginal = {...this.dataOriginal};
|
|
322
|
+
|
|
235
323
|
if (selector) {
|
|
236
324
|
let template = queryDocumentSelector(selector);
|
|
237
325
|
if (!template) return;
|
|
326
|
+
template.dataOriginal = {...data}
|
|
238
327
|
if (template.classList.contains('template')) {
|
|
239
328
|
this.render(template, data);
|
|
240
329
|
}
|
|
241
330
|
else
|
|
242
331
|
this.setValue([template], data);
|
|
243
332
|
} else if (elements) {
|
|
244
|
-
if (elements.length == 1 && elements[0].classList.contains('template'))
|
|
333
|
+
if (elements.length == 1 && elements[0].classList.contains('template')){
|
|
245
334
|
this.render(elements[0], data);
|
|
335
|
+
}
|
|
246
336
|
else
|
|
247
337
|
this.setValue(elements, data);
|
|
248
|
-
// for (let element of elements) {
|
|
249
|
-
// if (element.classList.contains('template'))
|
|
250
|
-
// this.render(element, data);
|
|
251
|
-
// else
|
|
252
|
-
// this.setValue([element], data);
|
|
253
|
-
// }
|
|
254
338
|
}
|
|
255
339
|
|
|
256
340
|
}
|
|
@@ -279,4 +363,79 @@ action.init({
|
|
|
279
363
|
}
|
|
280
364
|
});
|
|
281
365
|
|
|
366
|
+
observer.init({
|
|
367
|
+
name: 'render',
|
|
368
|
+
observe: ['addedNodes'],
|
|
369
|
+
target: '[render]',
|
|
370
|
+
callback: function(mutation) {
|
|
371
|
+
let element = mutation.target
|
|
372
|
+
element.removeAttribute('render')
|
|
373
|
+
|
|
374
|
+
let parentElement = element.parentElement
|
|
375
|
+
if (parentElement) {
|
|
376
|
+
let el = element
|
|
377
|
+
let parentKeys = [];
|
|
378
|
+
let renderData = new Map();
|
|
379
|
+
do {
|
|
380
|
+
let data;
|
|
381
|
+
el = el.parentElement
|
|
382
|
+
if (el) {
|
|
383
|
+
if (el.dataOriginal)
|
|
384
|
+
renderData.set(el.dataOriginal, '')
|
|
385
|
+
if (el.hasAttribute('render-clone'))
|
|
386
|
+
data = el.renderData
|
|
387
|
+
if (data)
|
|
388
|
+
renderData.set(data, '')
|
|
389
|
+
|
|
390
|
+
let parentKey = el.getAttribute('parentKey')
|
|
391
|
+
if(parentKey && parentKey != null) {
|
|
392
|
+
if (/^\d+$/.test(parentKey))
|
|
393
|
+
parentKey = `[${parentKey}]`
|
|
394
|
+
parentKeys.push(parentKey)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
} while (el)
|
|
398
|
+
|
|
399
|
+
let renderKey = element.getAttribute('render-key')
|
|
400
|
+
|
|
401
|
+
let parentKey;
|
|
402
|
+
parentKey = parentElement.getAttribute('parentKey')
|
|
403
|
+
if(renderKey == '$auto' || parentKey || parentKeys) {
|
|
404
|
+
let template = element.outerHTML
|
|
405
|
+
if (renderKey) {
|
|
406
|
+
template = template.replace(/\$auto/g, uuid.generate(6));
|
|
407
|
+
}
|
|
408
|
+
if (parentKeys.length > 0) {
|
|
409
|
+
let string = ''
|
|
410
|
+
if (parentKeys.length == 1){
|
|
411
|
+
string = parentKeys[0]
|
|
412
|
+
}
|
|
413
|
+
else
|
|
414
|
+
string = parentKeys.reverse().join('.')
|
|
415
|
+
string = string.replace(/.\[/g, '[');
|
|
416
|
+
template = template.replace(/\$parents/g, string);
|
|
417
|
+
}
|
|
418
|
+
if (parentKey) {
|
|
419
|
+
template = template.replace(/\$parent/g, parentKey);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
parentElement.innerHTML = template
|
|
423
|
+
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
element = parentElement.firstElementChild
|
|
427
|
+
let obj = {}
|
|
428
|
+
let array = Array.from(renderData.keys())
|
|
429
|
+
for (let data of array.reverse()){
|
|
430
|
+
obj = {...obj, ...data}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
CoCreateRender.data({
|
|
434
|
+
elements: [element],
|
|
435
|
+
data: obj
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
|
|
282
441
|
export default CoCreateRender;
|