Skip to content

Commit 20229ae

Browse files
committed
Finish website
1 parent 38d6367 commit 20229ae

14 files changed

Lines changed: 362 additions & 37 deletions

File tree

README.md

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,6 @@ React function component for displaying javascript arrays and JSON objects. Supp
2323
## Installation
2424
```bash
2525
npm i react18-json-view
26-
# or pnpm i react18-json-view
27-
# or yarn i react18-json-view
28-
29-
# canary
30-
# or npm i react18-json-view@canary
31-
# or pnpm i react18-json-view@canary
32-
# or yarn i react18-json-view@canary
3326
```
3427

3528
## Usage
@@ -42,7 +35,7 @@ import 'react18-json-view/src/style.css'
4235
<JsonView src={my_json_object} />
4336

4437
// If needed, you can use the internal stringify function.
45-
import { stringify } from 'react18-json-view'
38+
// import { stringify } from 'react18-json-view'
4639

4740
```
4841

@@ -60,7 +53,7 @@ import { stringify } from 'react18-json-view'
6053
| `onAdd` | `function` | - | `(params: { indexOrName: string\| number, depth: number, src: any; parentType: 'object' \| 'array' }) => void` |
6154
| `onDelete` | `function` | - | `(params:{ value: any,indexOrName: string \| number,depth: number,src: any,parentType: 'object' \| 'array'}) => void` |
6255
| `onEdit` | `function` | - | `(params: { newValue: any, oldValue: any, depth: number, src: any, indexOrName: string \| number, parentType: 'object' \| 'array'}) => void` |
63-
| `customizeNode`(@canary) | `ReactElement`\|`ReactComponent`\|`Options` | - | Highly customize every node. |
56+
| `customizeNode` | `ReactElement`\|`ReactComponent`\|`Options` | - | Highly customize every node. |
6457

6558
### Collapsed function
6659
```ts
@@ -105,10 +98,6 @@ The editor uses `eval(<input-value>)`. While in edit mode, you can enter `({})`
10598

10699
This component does not perform any cloning operations, so every step of the operation is carried out on the original object. If cloning is required, please handle it yourself.
107100

108-
## Figma [link](https://www.figma.com/file/1XAkndYOprEcUZQU2KFFoT/Json-View?type=design&node-id=9%3A1570&mode=design&t=SQHDsbrSYStNeEOD-1)
109-
110-
* Includes the design of *Json View Online*
111-
112101
## Theme
113102
Every theme has a dark mode. [preview](https://react18-json-view.vercel.app/?path=/docs/themes--docs)
114103

@@ -156,11 +145,11 @@ react-json-view does not support React 18.
156145
- [x] more color themes(dark)
157146
- [x] collapse objects callback
158147
- [x] editable option
159-
- [x] advance customization **<=**
148+
- [x] advance customization
160149
- [ ] map/set viewer
161150
- [ ] display data type
162151
- [ ] display object size
163152
- [ ] handle circle loop
164-
- [ ] redesign docs ★
153+
- [x] redesign docs ★
165154

166155
* tree?

src/utils.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ export function isCollapsed(
4545
if (typeof collapsed === 'function') {
4646
const result = safeCall(collapsed, [{ node, depth, indexOrName, size }])
4747
if (typeof result === 'boolean') return result
48-
else {
49-
console.warn('[react18-json-view collapsed]', 'The collapsed function does not return boolean correctly')
50-
return false
51-
}
5248
}
5349
if (Array.isArray(node) && size > collapseObjectsAfterLength) return true
5450
if (isObject(node) && size > collapseObjectsAfterLength) return true

website/src/app/footer.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default function Footer() {
2+
return (
3+
<footer className=' bg-gray-100'>
4+
<div className='py-8 container flex items-center'>
5+
<img src='https://avatars.githubusercontent.com/u/53907086?v=4' className='w-6 h-6 rounded-full mr-2' />
6+
Made by
7+
<a className='ml-1 font-bold' target='_blank' href='https://github.com/YYsuni'>
8+
Suni
9+
</a>
10+
</div>
11+
</footer>
12+
)
13+
}

website/src/app/layout.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Footer from './footer'
12
import './globals.css'
23
import Head from './head'
34

@@ -8,6 +9,8 @@ export default function RootLayout({ children }: { children: React.ReactNode })
89
<body>
910
{children}
1011

12+
<Footer />
13+
1114
<link
1215
href='https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600&display=swap'
1316
rel='stylesheet'

website/src/app/page.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,26 @@ import Installation from '@/contents/installation'
77
import Hero from '@/contents/hero'
88
import Usage from '@/contents/usage'
99
import Themes from '@/contents/themes'
10+
import Collapsed from '@/contents/collapsed'
11+
import Editable from '@/contents/editable'
12+
import Customization from '@/contents/customization'
1013

1114
export default function Home() {
1215
return (
13-
<main className='container pt-12 max-sm:pt-4 pb-8'>
16+
<main className='container pt-12 max-sm:pt-4 pb-20'>
1417
<Hero />
1518

1619
<Installation />
1720

1821
<Usage />
1922

2023
<Themes />
24+
25+
<Collapsed />
26+
27+
<Editable />
28+
29+
<Customization />
2130
</main>
2231
)
2332
}

website/src/components/theme.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default function Theme() {
7070
)
7171
return (
7272
<button className='border border-slate-300 h-8 w-8 flex justify-center items-center rounded-lg'>
73-
<SingleLoading />
73+
<SystemSVG className='w-4 h-4' />
7474
</button>
7575
)
7676
}

website/src/contents/collapsed.tsx

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { writeText } from '@/lib/clipboard'
2+
import clsx from 'clsx'
3+
import hljs from 'highlight.js/lib/core'
4+
import { useState } from 'react'
5+
import JsonView from 'react18-json-view'
6+
import CopySVG from '@/svgs/copy.svg'
7+
import CopiedSVG from '@/svgs/copied.svg'
8+
9+
type Option = '0' | '1' | '2' | '3' | 'true' | 'false' | 'function'
10+
const options: Option[] = ['0', '1', '2', '3', 'true', 'false', 'function']
11+
12+
const valueMap: Record<Option, any> = {
13+
'0': 0,
14+
'1': 1,
15+
'2': 2,
16+
'3': 3,
17+
true: true,
18+
false: false,
19+
function: (params: any) => {
20+
if (params.indexOrName === 'arr') return true
21+
if (params.depth > 3) return true
22+
if (params.depth > 2 && params.size > 3) return true
23+
if (params.node && typeof params.node === 'object' && params.node.nest === 'over') return true
24+
}
25+
}
26+
27+
const funcString = `(params) => {
28+
if (params.indexOrName === 'arr') return true
29+
if (params.depth > 3) return true
30+
if (params.depth > 2 && params.size > 3) return true
31+
if (params.node && typeof params.node === 'object' && params.node.nest === 'over') return true
32+
}`
33+
34+
export default function Collapsed() {
35+
const [selected, setSelected] = useState(options[1])
36+
37+
const code = `<JsonView src={json_object} collapsed={${selected === 'function' ? funcString : selected}} />`
38+
39+
const [copied, setCopied] = useState(false)
40+
41+
const copy = () => {
42+
writeText(code)
43+
setCopied(true)
44+
setTimeout(() => setCopied(false), 2000)
45+
}
46+
47+
const highlightedCode = hljs.highlight(code, { language: 'js' }).value
48+
49+
return (
50+
<>
51+
<h2 className='mt-12 text-lg font-medium'>Collapsed</h2>
52+
<ul className='flex flex-wrap gap-1 mt-3 select-none'>
53+
{options.map(item => (
54+
<li
55+
key={item}
56+
className={clsx(
57+
'border rounded-lg cursor-pointer px-2 py-1',
58+
selected === item && 'bg-slate-200 dark:bg-slate-700'
59+
)}
60+
onClick={() => setSelected(item)}>
61+
{item}
62+
</li>
63+
))}
64+
</ul>
65+
66+
<div className='relative'>
67+
<code className='my-3 flex items-center text-sm justify-between rounded-lg border bg-slate-50 p-4 dark:bg-slate-700 overflow-auto'>
68+
<pre
69+
dangerouslySetInnerHTML={{
70+
__html: highlightedCode
71+
}}
72+
/>
73+
</code>
74+
<button onClick={copy} className='rounded-lg p-1 absolute top-4 right-4'>
75+
{copied ? <CopiedSVG className='h-5 w-5' /> : <CopySVG className='h-5 w-5' />}
76+
</button>
77+
</div>
78+
79+
<div className='rounded-lg border p-4 text-sm mt-2 bg-white dark:bg-[#0E0832]'>
80+
<JsonView
81+
collapsed={valueMap[selected]}
82+
src={{
83+
string: 'string',
84+
number: 123456,
85+
boolean: false,
86+
null: null,
87+
func: function () {},
88+
Symbol: Symbol('JSON View'),
89+
obj: {
90+
k1: 123,
91+
k2: '123',
92+
k3: false
93+
},
94+
arr: ['string', 123456, false, null],
95+
nest: {
96+
nest: {
97+
nest: {
98+
nest: {
99+
nest: 'over'
100+
}
101+
}
102+
}
103+
}
104+
}}
105+
/>
106+
</div>
107+
</>
108+
)
109+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { writeText } from '@/lib/clipboard'
2+
import hljs from 'highlight.js/lib/core'
3+
import { useState } from 'react'
4+
import JsonView from 'react18-json-view'
5+
import CopySVG from '@/svgs/copy.svg'
6+
import CopiedSVG from '@/svgs/copied.svg'
7+
8+
const CODE = `<JsonView
9+
editable
10+
customizeNode={params => {
11+
if (params.indexOrName === 'obj') return { add: false, delete: false, enableClipboard: false }
12+
if (params.node === 'no-clipboard') return { enableClipboard: false }
13+
if (params.node === 'non-delete') return { delete: false }
14+
if (params.node === 'non-editable') return { add: false, delete: false, edit: false }
15+
if (params.indexOrName === 'arr') return { collapsed: false }
16+
if (params.depth > 2) return { collapsed: true }
17+
if (params.indexOrName === 'className') return { className: 'underline' }
18+
if (params.indexOrName === 'collapsed') return { collapsed: true }
19+
if (params.node === 'count')
20+
return () => {
21+
const [count, setCount] = useState(0)
22+
23+
return (
24+
<span>
25+
{count}
26+
<button onClick={() => setCount(count + 1)} className='border ml-1 px-1 py-0.5'>
27+
add
28+
</button>
29+
</span>
30+
)
31+
}
32+
if (typeof params.node === 'string' && params.node.startsWith('https://'))
33+
return (
34+
<a href={params.node} target='_blank' className='text-sky-500 hover:underline'>
35+
{params.node}
36+
</a>
37+
)
38+
}}
39+
src={{json_object}}
40+
/>`
41+
42+
export default function Customization() {
43+
const [copied, setCopied] = useState(false)
44+
45+
const copy = () => {
46+
writeText(CODE)
47+
setCopied(true)
48+
setTimeout(() => setCopied(false), 2000)
49+
}
50+
51+
const highlightedCode = hljs.highlight(CODE, { language: 'js' }).value
52+
53+
return (
54+
<>
55+
<h2 className='mt-12 text-lg font-medium'>Advanced customization</h2>
56+
57+
<div className='relative'>
58+
<code className='my-3 flex items-center text-sm justify-between rounded-lg border bg-slate-50 p-4 dark:bg-slate-700 overflow-auto'>
59+
<pre
60+
dangerouslySetInnerHTML={{
61+
__html: highlightedCode
62+
}}
63+
/>
64+
</code>
65+
<button onClick={copy} className='rounded-lg p-1 absolute top-4 right-4'>
66+
{copied ? <CopiedSVG className='h-5 w-5' /> : <CopySVG className='h-5 w-5' />}
67+
</button>
68+
</div>
69+
70+
<div className='rounded-lg border p-4 text-sm mt-2 bg-white dark:bg-[#0E0832]'>
71+
<JsonView
72+
editable
73+
customizeNode={params => {
74+
if (params.node === 'count')
75+
return () => {
76+
const [count, setCount] = useState(0)
77+
78+
return (
79+
<span>
80+
{count}
81+
<button onClick={() => setCount(count + 1)} className='border ml-1 px-1 py-0.5'>
82+
add
83+
</button>
84+
</span>
85+
)
86+
}
87+
if (typeof params.node === 'string' && params.node.startsWith('https://'))
88+
return (
89+
<a href={params.node} target='_blank' className='text-sky-500 hover:underline'>
90+
{params.node}
91+
</a>
92+
)
93+
if (params.indexOrName === 'obj') return { add: false, delete: false, enableClipboard: false }
94+
if (params.node === 'no-clipboard') return { enableClipboard: false }
95+
if (params.node === 'non-delete') return { delete: false }
96+
if (params.node === 'non-editable') return { add: false, delete: false, edit: false }
97+
if (params.indexOrName === 'arr') return { collapsed: false }
98+
if (params.depth > 2) return { collapsed: true }
99+
if (params.indexOrName === 'className') return { className: 'underline' }
100+
if (params.indexOrName === 'collapsed') return { collapsed: true }
101+
}}
102+
src={{
103+
count: 'count',
104+
link: 'https://github.com/YYsuni/react18-json-view',
105+
number: 123456,
106+
'no-clipboard': 'no-clipboard',
107+
'non-delete': 'non-delete',
108+
'non-editable': 'non-editable',
109+
className: 'className',
110+
collapsed: {
111+
k1: 123,
112+
k2: '123',
113+
k3: false
114+
},
115+
arr: ['string', 123456, false, null, [1, 2, 3]]
116+
}}
117+
/>
118+
</div>
119+
</>
120+
)
121+
}

0 commit comments

Comments
 (0)