• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mac-s-g / react-json-view / #1374

28 Jul 2022 05:40AM UTC coverage: 75.419% (-7.9%) from 83.298%
#1374

push

SmitMaruti
update  styling

294 of 403 branches covered (72.95%)

Branch coverage included in aggregate %.

516 of 671 relevant lines covered (76.9%)

40.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.21
/src/js/components/DataTypes/Object.js
1
import React from 'react';
2
import { polyfill } from 'react-lifecycles-compat';
3
import { toType } from './../../helpers/util';
4

5
//data type components
6
import { JsonObject } from './DataTypes';
7

8
import VariableEditor from './../VariableEditor';
9
import VariableMeta from './../VariableMeta';
10
import ArrayGroup from './../ArrayGroup';
11
import ObjectName from './../ObjectName';
12

13
//attribute store
14
import AttributeStore from './../../stores/ObjectAttributes';
15

16
//icons
17
import { CollapsedIcon, ExpandedIcon } from './../ToggleIcons';
18

19
//theme
20
import Theme from './../../themes/getStyle';
21
import { Elipsis } from '../Elipsis/Elipsis.styled';
22

23
//increment 1 with each nested object & array
24
const DEPTH_INCREMENT = 1;
1✔
25
//single indent is 5px
26
const SINGLE_INDENT = 5;
1✔
27

28
class RjvObject extends React.PureComponent {
29
    constructor(props) {
30
        super(props);
46✔
31
        const state = RjvObject.getState(props);
46✔
32
        this.state = {
46✔
33
            ...state,
34
            prevProps: {}
35
        };
36
    }
37

38
    static getState = props => {
1✔
39
        const size = Object.keys(props.src).length;
100✔
40
        const expanded =
41
            (props.collapsed === false ||
100✔
42
                (props.collapsed !== true && props.collapsed > props.depth)) &&
43
            (!props.shouldCollapse ||
44
                props.shouldCollapse({
45
                    name: props.name,
46
                    src: props.src,
47
                    type: toType(props.src),
48
                    namespace: props.namespace
49
                }) === false) &&
50
            //initialize closed if object has no items
51
            size !== 0;
52
        const state = {
100✔
53
            expanded: AttributeStore.get(
54
                props.rjvId,
55
                props.namespace,
56
                'expanded',
57
                expanded
58
            ),
59
            object_type: props.type === 'array' ? 'array' : 'object',
100✔
60
            parent_type: props.type === 'array' ? 'array' : 'object',
100✔
61
            size,
62
            hovered: false
63
        };
64
        return state;
100✔
65
    };
66

67
    static getDerivedStateFromProps(nextProps, prevState) {
68
        const { prevProps } = prevState;
54✔
69
        if (
54!
70
            nextProps.src !== prevProps.src ||
75!
71
            nextProps.collapsed !== prevProps.collapsed ||
72
            nextProps.name !== prevProps.name ||
73
            nextProps.namespace !== prevProps.namespace ||
74
            nextProps.rjvId !== prevProps.rjvId
75
        ) {
76
            const newState = RjvObject.getState(nextProps);
54✔
77
            return {
54✔
78
                ...newState,
79
                prevProps: nextProps
80
            };
81
        }
82
        return null;
×
83
    }
84

85
    toggleCollapsed = () => {
46✔
86
        this.setState(
×
87
            {
88
                expanded: !this.state.expanded
89
            },
90
            () => {
91
                AttributeStore.set(
×
92
                    this.props.rjvId,
93
                    this.props.namespace,
94
                    'expanded',
95
                    this.state.expanded
96
                );
97
            }
98
        );
99
    };
100

101
    getObjectContent = (depth, src, props) => {
46✔
102
        return (
39✔
103
            <div class="pushed-content object-container">
104
                <div
105
                    class="object-content"
106
                    {...Theme(this.props.theme, 'pushed-content')}
107
                >
108
                    {this.renderObjectContents(src, props)}
109
                </div>
110
            </div>
111
        );
112
    };
113

114
    getEllipsis = () => {
46✔
115
        const { size } = this.state;
15✔
116

117
        if (size === 0) {
15✔
118
            //don't render an ellipsis when an object has no items
119
            return null;
7✔
120
        } else {
121
            return (
8✔
122
                <div
123
                    {...Theme(this.props.theme, 'ellipsis')}
124
                    class="node-ellipsis"
125
                    onClick={this.toggleCollapsed}
126
                >
127
                    <Elipsis />
128
                </div>
129
            );
130
        }
131
    };
132

133
    getObjectMetaData = src => {
46✔
134
        const { rjvId, theme } = this.props;
54✔
135
        const { size, hovered } = this.state;
54✔
136
        return (
54✔
137
            <VariableMeta rowHovered={hovered} size={size} {...this.props} />
138
        );
139
    };
140

141
    getBraceStart(object_type, expanded) {
142
        const { src, theme, iconStyle, parent_type } = this.props;
54✔
143

144
        if (parent_type === 'array_group') {
54✔
145
            return (
2✔
146
                <span>
147
                    <span {...Theme(theme, 'brace')}>
148
                        {object_type === 'array' ? '[' : '{'}
2!
149
                    </span>
150
                    {expanded ? this.getObjectMetaData(src) : null}
2!
151
                </span>
152
            );
153
        }
154

155
        const IconComponent = expanded ? ExpandedIcon : CollapsedIcon;
52✔
156

157
        return (
52✔
158
            <span>
159
                <span
160
                    onClick={e => {
161
                        this.toggleCollapsed();
×
162
                    }}
163
                    {...Theme(theme, 'brace-row')}
164
                >
165
                    <div
166
                        class="icon-container"
167
                        {...Theme(theme, 'icon-container')}
168
                    >
169
                        <IconComponent {...{ theme, iconStyle }} />
170
                    </div>
171
                    <ObjectName {...this.props} />
172
                    <span {...Theme(theme, 'brace')}>
173
                        {object_type === 'array' ? '[' : '{'}
52✔
174
                    </span>
175
                </span>
176
                {expanded ? this.getObjectMetaData(src) : null}
52✔
177
            </span>
178
        );
179
    }
180

181
    render() {
182
        // `indentWidth` and `collapsed` props will
183
        // perpetuate to children via `...rest`
184
        const {
185
            depth,
186
            src,
187
            namespace,
188
            namespaceVariable,
189
            name,
190
            type,
191
            parent_type,
192
            theme,
193
            jsvRoot,
194
            iconStyle,
195
            ...rest
196
        } = this.props;
54✔
197

198
        const { object_type, expanded } = this.state;
54✔
199

200
        let styles = {};
54✔
201
        if (!jsvRoot && parent_type !== 'array_group') {
54✔
202
            styles.paddingLeft = this.props.indentWidth * SINGLE_INDENT;
43✔
203
        } else if (parent_type === 'array_group') {
11✔
204
            styles.borderLeft = 0;
2✔
205
            styles.display = 'inline';
2✔
206
        }
207

208
        return (
54✔
209
            <div
210
                class="object-key-val"
211
                onMouseEnter={() =>
212
                    this.setState({ ...this.state, hovered: true })
×
213
                }
214
                onMouseLeave={() =>
215
                    this.setState({ ...this.state, hovered: false })
×
216
                }
217
                {...Theme(theme, jsvRoot ? 'jsv-root' : 'objectKeyVal', styles)}
54✔
218
            >
219
                {this.getBraceStart(object_type, expanded)}
220
                {expanded
54✔
221
                    ? this.getObjectContent(depth, src, {
222
                          theme,
223
                          iconStyle,
224
                          ...rest
225
                      })
226
                    : this.getEllipsis()}
227
                <span class="brace-row">
228
                    <span
229
                        style={{
230
                            ...Theme(theme, 'brace').style,
231
                            paddingLeft: expanded ? '3px' : '0px'
54✔
232
                        }}
233
                    >
234
                        {object_type === 'array' ? ']' : '}'}
54✔
235
                    </span>
236
                    {expanded ? null : this.getObjectMetaData(src)}
54✔
237
                </span>
238
            </div>
239
        );
240
    }
241

242
    renderObjectContents = (variables, props) => {
46✔
243
        // console.log({ variables, props, p: this.props });
244
        const {
245
            depth,
246
            parent_type,
247
            index_offset,
248
            groupArraysAfterLength,
249
            namespace,
250
            namespaceVariable
251
        } = this.props;
39✔
252
        // console.log({ namespace });
253
        const { object_type } = this.state;
39✔
254
        let elements = [],
39✔
255
            variable;
256
        let keys = Object.keys(variables || {});
39!
257
        if (this.props.sortKeys && object_type !== 'array') {
39✔
258
            keys = keys.sort();
1✔
259
        }
260

261
        keys.forEach(name => {
39✔
262
            variable = new JsonVariable(name, variables[name]);
118✔
263
            if (parent_type === 'array_group' && index_offset) {
118✔
264
                variable.name = parseInt(variable.name) + index_offset;
2✔
265
            }
266
            if (!variables.hasOwnProperty(name)) {
118!
267
                return;
×
268
            } else if (variable.type === 'object') {
118✔
269
                elements.push(
12✔
270
                    <JsonObject
271
                        key={variable.name}
272
                        depth={depth + DEPTH_INCREMENT}
273
                        name={variable.name}
274
                        src={variable.value}
275
                        namespace={namespace.concat(variable.name)}
276
                        //namespace={namespace}
277
                        namespaceVariable={namespaceVariable.concat([
278
                            {
279
                                name: variable.name,
280
                                type: variable.type
281
                            }
282
                        ])}
283
                        parent_type={object_type}
284
                        {...props}
285
                    />
286
                );
287
            } else if (variable.type === 'array') {
106✔
288
                let ObjectComponent = JsonObject;
13✔
289

290
                if (
13!
291
                    groupArraysAfterLength &&
23✔
292
                    variable.value.length > groupArraysAfterLength
293
                ) {
294
                    ObjectComponent = ArrayGroup;
×
295
                }
296

297
                elements.push(
13✔
298
                    <ObjectComponent
299
                        key={variable.name}
300
                        depth={depth + DEPTH_INCREMENT}
301
                        name={variable.name}
302
                        src={variable.value}
303
                        namespace={namespace.concat(variable.name)}
304
                        //namespace={namespace}
305
                        namespaceVariable={namespaceVariable.concat([
306
                            {
307
                                name: variable.name,
308
                                type: variable.type
309
                            }
310
                        ])}
311
                        type="array"
312
                        parent_type={object_type}
313
                        {...props}
314
                    />
315
                );
316
            } else {
317
                elements.push(
93✔
318
                    <VariableEditor
319
                        key={variable.name + '_' + namespace}
320
                        variable={variable}
321
                        singleIndent={SINGLE_INDENT}
322
                        //namespace={namespace}
323
                        namespace={namespace}
324
                        namespaceVariable={namespaceVariable}
325
                        type={this.props.type}
326
                        {...props}
327
                    />
328
                );
329
            }
330
        });
331

332
        return elements;
39✔
333
    };
334
}
335

336
//just store name, value and type with a variable
337
export class JsonVariable {
338
    constructor(name, value) {
339
        this.name = name;
128✔
340
        this.value = value;
128✔
341
        this.type = toType(value);
128✔
342
    }
343
}
344

345
polyfill(RjvObject);
1✔
346

347
//export component
348
export default RjvObject;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc