import type { SvgIconProps } from '@mui/material' import { AppBar, Box, FormControl, FormControlLabel, InputLabel, MenuItem, Select, SvgIcon, Switch, TextField, Toolbar, Typography } from '@mui/material' import type { DataType, JsonViewerKeyRenderer, JsonViewerOnAdd, JsonViewerOnChange, JsonViewerOnDelete, JsonViewerTheme } from '@textea/json-viewer' import { applyValue, defineDataType, deleteValue, JsonViewer, stringType } from '@textea/json-viewer' import Image from 'next/image' import Link from 'next/link' import type { FC } from 'react' import { useCallback, useEffect, useState } from 'react' import { ocean } from '../../lib/shared' const allowedDomains = ['i.imgur.com'] // this url is copied from: https://beta.reactjs.org/learn/passing-props-to-a-component const avatar = 'https://i.imgur.com/1bX5QH6.jpg' function aPlusB (a: number, b: number) { return a + b } const aPlusBConst = function (a: number, b: number) { return a + b } const loopObject = { foo: 42, goo: 'Lorem Ipsum' } as Record loopObject.self = loopObject const loopArray = [ loopObject ] loopArray[1] = loopArray const longArray = Array.from({ length: 1000 }).map((_, i) => i) const map = new Map() map.set('foo', 1) map.set('goo', 'hello') map.set({}, 'world') const set = new Set([1, 2, 3]) const superLongString = '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111' const example = { avatar, string: 'Lorem ipsum dolor sit amet', integer: 42, url: new URL('https://example.com'), float: 114.514, bigint: 123456789087654321n, undefined, timer: 0, date: new Date('Tue Sep 13 2022 14:07:44 GMT-0500 (Central Daylight Time)'), link: 'http://example.com', emptyArray: [], array: [19, 19, 810, 'test', NaN], emptyObject: {}, object: { foo: true, bar: false, last: null }, emptyMap: new Map(), map, emptySet: new Set(), set, loopObject, loopArray, longArray, nestedArray: [ [1, 2], [3, 4] ], superLongString, function: aPlusB, constFunction: aPlusBConst, anonymousFunction: function (a: number, b: number) { return a + b }, shortFunction: (arg1: any, arg2: any) => console.log(arg1, arg2), shortLongFunction: (arg1: any, arg2: any) => { console.log(arg1, arg2) return '123' }, string_number: '1234' } const KeyRenderer: JsonViewerKeyRenderer = ({ path }) => { return ( "{path.slice(-1)}" ) } KeyRenderer.when = (props) => props.value === 114.514 const imageDataType = defineDataType({ is: (value) => { if (typeof value === 'string') { try { const url = new URL(value) return allowedDomains.includes(url.host) && url.pathname.endsWith('.jpg') } catch { return false } } return false }, Component: (props) => { return ( {props.value} ) } }) const LinkIcon = (props: SvgIconProps) => ( // ) const linkType: DataType = { ...stringType, is (value) { return typeof value === 'string' && value.startsWith('http') }, PostComponent: (props) => ( Open ) } const urlType = defineDataType({ is: (data) => data instanceof URL, Component: (props) => { const url = props.value.toString() return ( {url} ) } }) const IndexPage: FC = () => { const [indent, setIndent] = useState(3) const [groupArraysAfterLength, setGroupArraysAfterLength] = useState(100) const [themeKey, setThemeKey] = useState('light') const [theme, setTheme] = useState('light') const [src, setSrc] = useState(() => example) const [displayDataTypes, setDisplayDataTypes] = useState(true) const [displaySize, setDisplaySize] = useState(true) const [displayComma, setDisplayComma] = useState(false) const [editable, setEditable] = useState(true) const [highlightUpdates, setHighlightUpdates] = useState(true) useEffect(() => { const loop = () => { setSrc(src => ({ ...src, timer: src.timer + 1 })) } const id = setInterval(loop, 1000) return () => clearInterval(id) }, []) return (
JSON viewer setEditable(event.target.checked)} /> )} label='Editable' /> setHighlightUpdates(event.target.checked)} /> )} label='Highlight Updates' /> setDisplayDataTypes(event.target.checked)} /> )} label='DisplayDataTypes' /> setDisplaySize(event.target.checked)} /> )} label='DisplayObjectSize' /> setDisplayComma(event.target.checked)} /> )} label='DisplayComma' /> { const indent = parseInt(event.target.value) if (indent > -1 && indent < 10) { setIndent(indent) } } } /> { const groupArraysAfterLength = parseInt(event.target.value) if (groupArraysAfterLength > -1 && groupArraysAfterLength < 500) { setGroupArraysAfterLength(groupArraysAfterLength) } } } /> Theme ( (path) => { const key = prompt('Key:') if (key === null) return const value = prompt('Value:') if (value === null) return setSrc(src => applyValue(src, [...path, key], value)) }, [] ) } onChange={ useCallback( (path, oldValue, newValue) => { setSrc(src => applyValue(src, path, newValue)) }, [] ) } onDelete={ useCallback( (path, value) => { setSrc(src => deleteValue(src, path, value)) }, [] ) } sx={{ paddingX: 2 }} />
) } export default IndexPage