Skip to content

Commit 34c221a

Browse files
committed
feat: refactor to typescript using vite.js
0 parents  commit 34c221a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+9268
-0
lines changed

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
7+
[*.{js,json,yml}]
8+
charset = utf-8
9+
indent_style = space
10+
indent_size = 2

.eslintrc.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module.exports = {
2+
root: true,
3+
extends: './node_modules/@textea/dev-kit/config/eslint',
4+
settings: {
5+
react: {
6+
version: 'detect'
7+
}
8+
},
9+
env: {
10+
browser: true, es6: true
11+
}
12+
}

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.yarn/*
2+
!.yarn/patches
3+
!.yarn/plugins
4+
!.yarn/releases
5+
!.yarn/sdks
6+
!.yarn/versions
7+
8+
# Swap the comments on the following lines if you don't wish to use zero-installs
9+
# Documentation here: https://yarnpkg.com/features/zero-installs
10+
#!.yarn/cache
11+
.pnp.*
12+
13+
dist
14+
tsconfig.tsbuildinfo
15+
.eslintcache
16+
node_modules

.yarn/releases/yarn-3.2.2.cjs

Lines changed: 783 additions & 0 deletions
Large diffs are not rendered by default.

.yarnrc.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
nmMode: hardlinks-local
2+
3+
nodeLinker: node-modules
4+
5+
yarnPath: .yarn/releases/yarn-3.2.2.cjs

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# json-viewer

package.json

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"name": "@textea/json-viewer",
3+
"packageManager": "yarn@3.2.2",
4+
"description": "Interactive react component for displaying javascript arrays and JSON objects.",
5+
"version": "1.21.3",
6+
"types": "src/type.d.ts",
7+
"main": "dist/index.js",
8+
"module": "dist/index.mjs",
9+
"exports": {
10+
".": {
11+
"types": "./src/type.d.ts",
12+
"import": "./dist/index.mjs",
13+
"require": "./dist/index.js",
14+
"default": "./dist/index.umd.js"
15+
}
16+
},
17+
"files": [
18+
"src/**.d.ts",
19+
"dist",
20+
"yarn.lock"
21+
],
22+
"scripts": {
23+
"build": "run tsc && run vite build"
24+
},
25+
"dependencies": {
26+
"events": "^3.3.0",
27+
"flux": "^4.0.3",
28+
"react-base16-styling": "^0.9.1",
29+
"react-lifecycles-compat": "^3.0.4",
30+
"react-textarea-autosize": "^8.3.4"
31+
},
32+
"peerDependencies": {
33+
"react": "^18.2.0",
34+
"react-dom": "^18.2.0"
35+
},
36+
"devDependencies": {
37+
"@textea/dev-kit": "^0.11.2",
38+
"@types/events": "^3.0.0",
39+
"@types/node": "^18.6.5",
40+
"@types/react": "^18.0.15",
41+
"@types/react-dom": "^18.0.6",
42+
"@types/react-lifecycles-compat": "^3.0.1",
43+
"@types/web": "^0.0.71",
44+
"@typescript-eslint/eslint-plugin": "^5.32.0",
45+
"@typescript-eslint/parser": "^5.32.0",
46+
"@vitejs/plugin-react": "^2.0.0",
47+
"eslint": "^8.21.0",
48+
"eslint-config-standard": "^17.0.0",
49+
"eslint-plugin-cypress": "^2.12.1",
50+
"eslint-plugin-import": "^2.26.0",
51+
"eslint-plugin-n": "^15.2.4",
52+
"eslint-plugin-promise": "^6.0.0",
53+
"eslint-plugin-react": "^7.30.1",
54+
"eslint-plugin-react-hooks": "^4.6.0",
55+
"eslint-plugin-simple-import-sort": "^7.0.0",
56+
"eslint-plugin-unused-imports": "^2.0.0",
57+
"prettier": "^2.7.1",
58+
"react": "^18.2.0",
59+
"react-dom": "^18.2.0",
60+
"ts-node": "^10.9.1",
61+
"typescript": "^4.7.4",
62+
"vite": "^3.0.5",
63+
"vite-plugin-dts": "^1.4.1",
64+
"vitest": "^0.21.1"
65+
}
66+
}

src/components/ArrayGroup.jsx

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import React from 'react';
2+
import Theme from './../themes/getStyle';
3+
4+
import VariableMeta from './VariableMeta';
5+
import ObjectName from './ObjectName';
6+
import ObjectComponent from './DataTypes/Object';
7+
8+
//icons
9+
import { CollapsedIcon, ExpandedIcon } from './ToggleIcons';
10+
11+
//single indent is 5px
12+
const SINGLE_INDENT = 5;
13+
14+
export default class extends React.PureComponent {
15+
constructor(props) {
16+
super(props);
17+
this.state = {
18+
expanded: []
19+
};
20+
}
21+
22+
toggleCollapsed = i => {
23+
const newExpanded = [];
24+
for (const j in this.state.expanded) {
25+
newExpanded.push(this.state.expanded[j]);
26+
}
27+
newExpanded[i] = !newExpanded[i];
28+
this.setState({
29+
expanded: newExpanded
30+
});
31+
};
32+
33+
getExpandedIcon(i) {
34+
const { theme, iconStyle } = this.props;
35+
36+
if (this.state.expanded[i]) {
37+
return <ExpandedIcon {...{ theme, iconStyle }} />;
38+
}
39+
40+
return <CollapsedIcon {...{ theme, iconStyle }} />;
41+
}
42+
43+
render() {
44+
const {
45+
src,
46+
groupArraysAfterLength,
47+
depth,
48+
name,
49+
theme,
50+
jsvRoot,
51+
namespace,
52+
parent_type,
53+
...rest
54+
} = this.props;
55+
56+
let object_padding_left = 0;
57+
58+
const array_group_padding_left = this.props.indentWidth * SINGLE_INDENT;
59+
60+
if (!jsvRoot) {
61+
object_padding_left = this.props.indentWidth * SINGLE_INDENT;
62+
}
63+
64+
const size = groupArraysAfterLength;
65+
const groups = Math.ceil(src.length / size);
66+
67+
return (
68+
<div
69+
class="object-key-val"
70+
{...Theme(theme, jsvRoot ? 'jsv-root' : 'objectKeyVal', {
71+
paddingLeft: object_padding_left
72+
})}
73+
>
74+
<ObjectName {...this.props} />
75+
76+
<span>
77+
<VariableMeta size={src.length} {...this.props} />
78+
</span>
79+
{[...Array(groups)].map((_, i) => (
80+
<div
81+
key={i}
82+
class="object-key-val array-group"
83+
{...Theme(theme, 'objectKeyVal', {
84+
marginLeft: 6,
85+
paddingLeft: array_group_padding_left
86+
})}
87+
>
88+
<span {...Theme(theme, 'brace-row')}>
89+
<div
90+
class="icon-container"
91+
{...Theme(theme, 'icon-container')}
92+
onClick={e => {
93+
this.toggleCollapsed(i);
94+
}}
95+
>
96+
{this.getExpandedIcon(i)}
97+
</div>
98+
{this.state.expanded[i] ? (
99+
<ObjectComponent
100+
key={name + i}
101+
depth={0}
102+
name={false}
103+
collapsed={false}
104+
groupArraysAfterLength={size}
105+
index_offset={i * size}
106+
src={src.slice(i * size, i * size + size)}
107+
namespace={namespace}
108+
type="array"
109+
parent_type="array_group"
110+
theme={theme}
111+
{...rest}
112+
/>
113+
) : (
114+
<span
115+
{...Theme(theme, 'brace')}
116+
onClick={e => {
117+
this.toggleCollapsed(i);
118+
}}
119+
class="array-group-brace"
120+
>
121+
[
122+
<div
123+
{...Theme(
124+
theme,
125+
'array-group-meta-data'
126+
)}
127+
class="array-group-meta-data"
128+
>
129+
<span
130+
class="object-size"
131+
{...Theme(theme, 'object-size')}
132+
>
133+
{i * size}
134+
{' - '}
135+
{i * size + size > src.length
136+
? src.length
137+
: i * size + size}
138+
</span>
139+
</div>
140+
]
141+
</span>
142+
)}
143+
</span>
144+
</div>
145+
))}
146+
</div>
147+
);
148+
}
149+
}

src/components/CopyToClipboard.jsx

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import React from 'react';
2+
3+
import { toType } from './../helpers/util';
4+
5+
//clibboard icon
6+
import { Clippy } from './icons';
7+
8+
//theme
9+
import Theme from './../themes/getStyle';
10+
11+
export default class extends React.PureComponent {
12+
constructor(props) {
13+
super(props);
14+
this.state = {
15+
copied: false
16+
};
17+
}
18+
19+
copiedTimer = null;
20+
21+
componentWillUnmount() {
22+
if (this.copiedTimer) {
23+
clearTimeout(this.copiedTimer);
24+
this.copiedTimer = null;
25+
}
26+
}
27+
28+
handleCopy = () => {
29+
const container = document.createElement('textarea');
30+
const { clickCallback, src, namespace } = this.props;
31+
32+
container.innerHTML = JSON.stringify(
33+
this.clipboardValue(src),
34+
null,
35+
' '
36+
);
37+
38+
document.body.appendChild(container);
39+
container.select();
40+
document.execCommand('copy');
41+
42+
document.body.removeChild(container);
43+
44+
this.copiedTimer = setTimeout(() => {
45+
this.setState({
46+
copied: false
47+
});
48+
}, 5500);
49+
50+
this.setState({ copied: true }, () => {
51+
if (typeof clickCallback !== 'function') {
52+
return;
53+
}
54+
55+
clickCallback({
56+
src: src,
57+
namespace: namespace,
58+
name: namespace[namespace.length - 1]
59+
});
60+
});
61+
};
62+
63+
getClippyIcon = () => {
64+
const { theme } = this.props;
65+
66+
if (this.state.copied) {
67+
return (
68+
<span>
69+
<Clippy class="copy-icon" {...Theme(theme, 'copy-icon')} />
70+
<span {...Theme(theme, 'copy-icon-copied')}></span>
71+
</span>
72+
);
73+
}
74+
75+
return <Clippy class="copy-icon" {...Theme(theme, 'copy-icon')} />;
76+
};
77+
78+
clipboardValue = value => {
79+
const type = toType(value);
80+
switch (type) {
81+
case 'function':
82+
case 'regexp':
83+
return value.toString();
84+
default:
85+
return value;
86+
}
87+
};
88+
89+
render() {
90+
const { src, theme, hidden, rowHovered } = this.props;
91+
let style = Theme(theme, 'copy-to-clipboard').style;
92+
let display = 'inline';
93+
94+
if (hidden) {
95+
display = 'none';
96+
}
97+
98+
return (
99+
<span
100+
className="copy-to-clipboard-container"
101+
title="Copy to clipboard"
102+
style={{
103+
verticalAlign: 'top',
104+
display: rowHovered ? 'inline-block' : 'none'
105+
}}
106+
>
107+
<span
108+
style={{
109+
...style,
110+
display: display
111+
}}
112+
onClick={this.handleCopy}
113+
>
114+
{this.getClippyIcon()}
115+
</span>
116+
</span>
117+
);
118+
}
119+
}

0 commit comments

Comments
 (0)