import {Box, BoxProps, Card, Code, Label, Stack} from '@sanity/ui'
import React, {useCallback, useEffect, useRef, useState} from 'react'
import styled, {DefaultTheme, StyledComponent} from 'styled-components'
import {pathToString} from '../../paths'
import {FieldChangeNode} from '../../types'
import {FromToArrow} from './FromToArrow'
interface Props extends BoxProps {
children: React.ReactNode
change: FieldChangeNode
as?: StyledComponent<'div', DefaultTheme>
}
const CodeWrapper = styled.pre`
overflow-x: auto;
position: relative;
`
const Meta = styled.div`
position: absolute;
top: 0;
right: 0;
`
export function DiffInspectWrapper({
children,
as,
change,
...restProps
}: Props): React.ReactElement {
const isHovering = useRef(false)
const [isInspecting, setIsInspecting] = useState(false)
const toggleInspect = useCallback(() => setIsInspecting((state) => !state), [setIsInspecting])
const handleMouseEnter = useCallback(() => (isHovering.current = true), [])
const handleMouseLeave = useCallback(() => (isHovering.current = false), [isHovering])
useEffect(() => {
function onKeyDown(evt: KeyboardEvent) {
const {metaKey, key} = evt
if (metaKey && key === 'i' && isHovering.current) {
toggleInspect()
}
}
window.addEventListener('keydown', onKeyDown, false)
return () => window.removeEventListener('keydown', onKeyDown, false)
}, [toggleInspect])
return (
{isInspecting ? : children}
)
}
const MetaLabel = ({title}: {title: string}) => (
)
function DiffInspector({change}: {change: FieldChangeNode}): React.ReactElement | null {
return (
{printMeta({
path: pathToString(change.path),
fromIndex: change.itemDiff?.fromIndex,
toIndex: change.itemDiff?.toIndex,
hasMoved: change.itemDiff?.hasMoved,
action: change.diff.action,
isChanged: change.diff.isChanged,
})}
{jsonify(change.diff.fromValue)}
{jsonify(change.diff.toValue)}
)
}
function jsonify(value: unknown) {
if (typeof value === 'undefined') {
return 'undefined'
}
return JSON.stringify(value, null, 2)
}
function printMeta(keys: Record) {
const lines: string[] = []
Object.entries(keys).forEach(([key, value]) => {
if (typeof value !== 'undefined' && value !== null) {
lines.push(`${key}: ${value}`)
}
})
return lines.join('\n')
}