-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: hide json view under a button (#93)
* feat: view json in a button * feat: add syntax highlights --------- Co-authored-by: Neil Campbell <[email protected]>
- Loading branch information
1 parent
420772f
commit a17192e
Showing
25 changed files
with
245 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
src/features/common/components/json-view-dialog-button.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { JsonView as ReactJsonView } from 'react-json-view-lite' | ||
import 'react-json-view-lite/dist/index.css' | ||
import styles from './json-view-dialog.module.css' | ||
import { cn } from '../utils' | ||
import { Button } from './button' | ||
import { useCallback, useState } from 'react' | ||
import { asJson } from '@/utils/as-json' | ||
import { toast } from 'react-toastify' | ||
import { Dialog, DialogContent, DialogHeader } from '@/features/common/components/dialog' | ||
import { useResolvedTheme } from '@/features/settings/data/theme' | ||
|
||
type Props = { | ||
json: object | ||
expandJsonLevel?: (level: number) => boolean | ||
} | ||
|
||
export function OpenJsonViewDialogButton({ json, expandJsonLevel: exapandJsonLevel = defaultExpandLevel }: Props) { | ||
const [dialogOpen, setDialogOpen] = useState(false) | ||
|
||
const openJsonViewDialog = useCallback(() => { | ||
setDialogOpen(true) | ||
}, [setDialogOpen]) | ||
|
||
const styleDark: StyleProps = { | ||
container: styles['key-dark'], | ||
basicChildStyle: styles['basic-element-style'], | ||
collapseIcon: styles['collapse-icon'], | ||
expandIcon: styles['expand-icon'], | ||
collapsedContent: styles['collapsed-content'], | ||
label: styles['label'], | ||
clickableLabel: styles['clickable-label'], | ||
nullValue: '', | ||
undefinedValue: '', | ||
stringValue: styles['value-string-dark'], | ||
booleanValue: styles['value-boolean-dark'], | ||
numberValue: styles['value-number-dark'], | ||
otherValue: '', | ||
punctuation: styles['punctuation-dark'], | ||
noQuotesForStringValues: false, | ||
} | ||
const styleLight: StyleProps = { | ||
container: styles['key-light'], | ||
basicChildStyle: styles['basic-element-style'], | ||
collapseIcon: styles['collapse-icon'], | ||
expandIcon: styles['expand-icon'], | ||
collapsedContent: styles['collapsed-content'], | ||
label: styles['label'], | ||
clickableLabel: styles['clickable-label'], | ||
nullValue: '', | ||
undefinedValue: '', | ||
stringValue: styles['value-string-light'], | ||
booleanValue: styles['value-boolean-light'], | ||
numberValue: styles['value-number-light'], | ||
otherValue: '', | ||
punctuation: styles['punctuation-light'], | ||
noQuotesForStringValues: false, | ||
} | ||
|
||
const theme = useResolvedTheme() | ||
const currentStyle = theme === 'dark' ? styleDark : styleLight | ||
|
||
const copyJsonToClipboard = useCallback(() => { | ||
const jsonString = asJson(json) | ||
navigator.clipboard.writeText(jsonString) | ||
|
||
toast.success('JSON copied to clipboard') | ||
}, [json]) | ||
|
||
return ( | ||
<> | ||
<Button variant="outline" onClick={openJsonViewDialog}> | ||
View JSON | ||
</Button> | ||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen} modal={true}> | ||
<DialogContent className="bg-card"> | ||
<DialogHeader> | ||
<h4 className={cn('text-xl text-primary font-bold')}>JSON</h4> | ||
</DialogHeader> | ||
<div className={cn('border-solid border-2 border-border grid w-[900px] min-h-[200px] max-h-[500px] overflow-auto relative')}> | ||
<Button variant="default" className={cn('absolute top-2 right-2')} onClick={copyJsonToClipboard}> | ||
Copy | ||
</Button> | ||
<ReactJsonView data={json} shouldExpandNode={exapandJsonLevel} style={currentStyle} /> | ||
</div> | ||
</DialogContent> | ||
</Dialog> | ||
</> | ||
) | ||
} | ||
// By default only render the top level because sometimes the object has too many children, which result in the UI thread being blocked on mount. | ||
const defaultExpandLevel = (level: number) => { | ||
return level < 1 | ||
} | ||
|
||
export interface StyleProps { | ||
container: string | ||
basicChildStyle: string | ||
label: string | ||
clickableLabel: string | ||
nullValue: string | ||
undefinedValue: string | ||
numberValue: string | ||
stringValue: string | ||
booleanValue: string | ||
otherValue: string | ||
punctuation: string | ||
expandIcon: string | ||
collapseIcon: string | ||
collapsedContent: string | ||
noQuotesForStringValues: boolean | ||
} |
81 changes: 81 additions & 0 deletions
81
src/features/common/components/json-view-dialog.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
.collapse-icon::after { | ||
cursor: pointer; | ||
margin-right: 5px; | ||
content: '\25BE'; | ||
} | ||
|
||
.expand-icon::after { | ||
cursor: pointer; | ||
margin-right: 5px; | ||
content: '\25B8'; | ||
} | ||
|
||
.basic-element-style { | ||
margin: 0 10px; | ||
padding: 0; | ||
} | ||
|
||
.label { | ||
margin-right: 5px; | ||
} | ||
|
||
.clickable-label { | ||
cursor: pointer; | ||
} | ||
|
||
.collapsed-content { | ||
cursor: pointer; | ||
margin-right: 5px; | ||
} | ||
|
||
.collapsed-content::after { | ||
content: '...'; | ||
font-size: 0.8em; | ||
} | ||
|
||
.punctuation-base { | ||
margin-right: 5px; | ||
font-weight: normal; | ||
} | ||
|
||
.punctuation-light { | ||
composes: punctuation-base; | ||
color: rgb(15 23 42); | ||
} | ||
|
||
.key-light { | ||
color: rgb(27 108 135); | ||
padding: 10px 0; | ||
} | ||
.value-string-light { | ||
color: rgb(169 48 59); | ||
} | ||
|
||
.value-number-light { | ||
color: rgb(25 109 11); | ||
} | ||
|
||
.value-boolean-light { | ||
color: rgb(67 100 99); | ||
} | ||
|
||
.punctuation-dark { | ||
composes: punctuation-base; | ||
color: rgb(255 255 255); | ||
} | ||
|
||
.key-dark { | ||
color: rgb(43 157 195); | ||
padding: 10px 0; | ||
} | ||
.value-string-dark { | ||
color: rgb(234 100 104); | ||
} | ||
|
||
.value-number-dark { | ||
color: rgb(43 167 22); | ||
} | ||
|
||
.value-boolean-dark { | ||
color: rgb(105 154 152); | ||
} |
Oops, something went wrong.