react-json-tree
react-json-tree copied to clipboard
Object preview option?
Currently when a node is collapsed and contains an object or array, by default it will show something like 3 keys or 4 items. This is decent default and given that you can override getItemString users can do pretty much what ever they want.
That said I'm wondering if there is any interest in providing a "preview" mode as an option out fo the box. Obviously the below is just a sketch of what could be done, but I just wanted to prototype something to see if there was interest before investing more time.
Let me know.
const getItemString = (function() {
function dataType(data) {
return Object.prototype.toString.call(data).slice(8, -1);
}
function nodeValue(item) {
const type = dataType(item);
let color = themeJSONTree.extend.base0B;
if (type === 'Array' || type === 'Object') {
color = '#72b252'; // TODO: make a theme color
item = type;
}
else if (type === 'Number' || type === 'Boolean') {
item = String(item);
color = themeJSONTree.extend.base09;
}
else if (type === 'String') {
item = '\'' + item + '\'';
}
else {
if (item === null || item === undefined) {
color = themeJSONTree.extend.base08;
}
item = String(item);
}
return <span style={{color}}>{item}</span>;
}
function rootArray(data, itemString) {
const components = [ '[ ' ];
for (let i = 0; i < data.length; i++) {
if (i === 4) {
components.push(', ...');
break;
}
if (i > 0) {
components.push(', ');
}
components.push(nodeValue(data[i]));
};
components.push(' ] - ');
// add item string
components.push(<span style={{ color: themeJSONTree.extend.base08 }}>{itemString}</span>);
return components;
}
function rootObject(data, itemString) {
const components = [ '{ ' ];
let i = 0;
for (let key in data) {
if (key !== undefined) {
if (i++ === 4) {
components.push(', ...');
break;
}
if (i > 1) {
components.push(', ');
}
components.push(<span>{key}: {nodeValue(data[key])}</span>);
}
}
components.push(' } - ');
// add item string
components.push(<span style={{ color: themeJSONTree.extend.base08 }}>{itemString}</span>);
return components;
}
return function(type, data, itemType, itemString) {
let result = undefined;
if (type === 'Array') {
result = rootArray(data, itemString);
}
else if (type === 'Object') {
result = rootObject(data, itemString);
}
else {
result = <span>{itemType} {itemString}</span>;
}
return result;
};
})();
@avanderhoorn, could you please add it as a PR? I'd look into it.
It would be nice to have the number of object keys and arrays items customizable, and if the number is set to 0 to show {…}/[…].
Thanks for the response! What would you like the API look like (as in property names, etc)?
<JSONTree {...props} preview={{
limitObjectKeys: 3,
limitArrayItems: 4,
predefined: (val) => isIterable(val) || isImmutable(val) ? '(…)' : undefined,
prefix: (data) => data['@@__IS_IMMUTABLE__@@'] ? 'Immutable' : ''
}} />
Not sure you want to move that part from predefined and prefix inside the lib. Also don't forget about functions. Symbols I guess could be stringified.