11/* eslint-disable linebreak-style */
22import React , { useContext } from 'react' ;
33import { BaseEditor , createEditor , Descendant , Text } from 'slate' ;
4- import { Editable , ReactEditor , Slate , withReact } from 'slate-react' ;
4+ import {
5+ Editable ,
6+ ReactEditor ,
7+ Slate ,
8+ withReact ,
9+ RenderLeafProps ,
10+ RenderElementProps ,
11+ } from 'slate-react' ;
512import { cn } from '@/lib/utils' ;
613import getPartsOfJson , { SyntaxPart } from '~/lib/getPartsOfJson' ;
714import jsonSchemaReferences from './jsonSchemaLinks' ;
@@ -21,7 +28,7 @@ import { atomOneDark } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
2128
2229type CustomElement = CustomNode | CustomText ;
2330type CustomNode = { type : 'paragraph' ; children : CustomText [ ] } ;
24- type CustomText = { text : string } ;
31+ type CustomText = { text : string ; syntaxPart ?: SyntaxPart } ;
2532
2633declare module 'slate' {
2734 interface CustomTypes {
@@ -215,7 +222,7 @@ const calculateNewDecorationsMap = (
215222 textPathIndexes ,
216223 ) ;
217224 const highlightingDecorations = multipathDecorations . reduce (
218- ( acc , multipathDecoration : MultipathDecoration ) => {
225+ ( acc : RangeWithSyntaxPart [ ] , multipathDecoration : MultipathDecoration ) => {
219226 const decorationsOfNodes = multipathDecoration . nodes . reduce (
220227 ( acc : RangeWithSyntaxPart [ ] , node : NodeRange ) => {
221228 const decorationOfNode = {
@@ -231,11 +238,11 @@ const calculateNewDecorationsMap = (
231238 } ;
232239 return [ ...acc , decorationOfNode ] ;
233240 } ,
234- [ ] ,
241+ [ ] as RangeWithSyntaxPart [ ] ,
235242 ) ;
236243 return [ ...acc , ...decorationsOfNodes ] ;
237244 } ,
238- [ ] ,
245+ [ ] as RangeWithSyntaxPart [ ] ,
239246 ) ;
240247
241248 const decorationMap = makeDecorationsToMap ( highlightingDecorations ) ;
@@ -359,7 +366,7 @@ export default function JsonEditor({
359366 }
360367 } , [ codeContent , isJsonMode ] ) ;
361368
362- const parsedCode : null | any = React . useMemo ( ( ) => {
369+ const parsedCode : Record < string , unknown > | null = React . useMemo ( ( ) => {
363370 try {
364371 return JSON . parse ( serializedCode ) ;
365372 } catch ( e ) {
@@ -404,8 +411,15 @@ export default function JsonEditor({
404411 let text = '' ;
405412 /* istanbul ignore else : there is no else block to test here */
406413 if ( value ) {
407- value . forEach ( ( e : any ) => {
408- text += e . children [ 0 ] . text + '\n' ;
414+ value . forEach ( ( e : Descendant ) => {
415+ if (
416+ 'children' in e &&
417+ Array . isArray ( e . children ) &&
418+ e . children [ 0 ] &&
419+ 'text' in e . children [ 0 ]
420+ ) {
421+ text += ( e . children [ 0 ] as Text ) . text + '\n' ;
422+ }
409423 } ) ;
410424 }
411425 return text ;
@@ -414,10 +428,11 @@ export default function JsonEditor({
414428 // copy status react state
415429 const [ copied , setCopied ] = React . useState ( false ) ;
416430
417- const allPathDecorationsMap : Record < string , any > = React . useMemo (
418- ( ) => calculateNewDecorationsMap ( value , isPartialSchema ) ,
419- [ value , isPartialSchema ] ,
420- ) ;
431+ const allPathDecorationsMap : Record < string , RangeWithSyntaxPart [ ] > =
432+ React . useMemo (
433+ ( ) => calculateNewDecorationsMap ( value , isPartialSchema ) ,
434+ [ value , isPartialSchema ] ,
435+ ) ;
421436
422437 // Badge text logic for regular code blocks
423438 const getBadgeText = ( ) => {
@@ -609,17 +624,19 @@ export default function JsonEditor({
609624 /* istanbul ignore next: allPathDecorationsMap[stringPath] cannot be null */
610625 return allPathDecorationsMap [ stringPath ] || [ ] ;
611626 } }
612- renderLeaf = { ( props : any ) => {
627+ renderLeaf = { ( props : RenderLeafProps ) => {
613628 const { leaf, children, attributes } = props ;
629+ const syntaxType = leaf . syntaxPart ?. type ?? '' ;
614630 const textStyles : undefined | string = ( ( ) => {
631+ const parentJsonPath = leaf . syntaxPart ?. parentJsonPath ?? '' ;
615632 if (
616633 [
617634 'objectPropertyStartQuotes' ,
618635 'objectPropertyEndQuotes' ,
619- ] . includes ( leaf . syntaxPart ?. type )
636+ ] . includes ( syntaxType )
620637 )
621638 return 'text-blue-200' ;
622- if ( [ 'objectProperty' ] . includes ( leaf . syntaxPart ?. type ) ) {
639+ if ( [ 'objectProperty' ] . includes ( syntaxType ) ) {
623640 const isJsonScope = jsonPathsWithJsonScope
624641 . filter (
625642 ( jsonPathWithScope ) =>
@@ -630,7 +647,7 @@ export default function JsonEditor({
630647 ( jsonPathsWithJsonScope ) =>
631648 jsonPathsWithJsonScope . jsonPath ,
632649 )
633- . includes ( leaf . syntaxPart ?. parentJsonPath ) ;
650+ . includes ( parentJsonPath ) ;
634651 if (
635652 isJsonScope &&
636653 jsonSchemaReferences . objectProperty [ leaf . text ]
@@ -652,7 +669,7 @@ export default function JsonEditor({
652669 'arrayComma' ,
653670 'arrayStartBracket' ,
654671 'arrayEndBracket' ,
655- ] . includes ( leaf . syntaxPart ?. type )
672+ ] . includes ( syntaxType )
656673 )
657674 return 'text-slate-400' ;
658675 if (
@@ -661,19 +678,20 @@ export default function JsonEditor({
661678 'stringValue' ,
662679 'booleanValue' ,
663680 'nullValue' ,
664- ] . includes ( leaf . syntaxPart ?. type )
681+ ] . includes ( syntaxType )
665682 )
666683 return 'text-lime-200' ;
667684
668685 // Handle partial schema specific highlighting that might not match exactly
669- if ( ! leaf . syntaxPart ?. type ) {
686+ if ( ! syntaxType ) {
670687 // If no syntax part type, apply default white color for partial schemas
671688 return isPartialSchema ? 'text-white' : undefined ;
672689 }
673690 } ) ( ) ;
674691
675692 const link : null | string = ( ( ) =>
676- jsonSchemaReferences ?. [ leaf . syntaxPart ?. type ] ?. [ leaf . text ] ||
693+ ( syntaxType &&
694+ jsonSchemaReferences ?. [ syntaxType ] ?. [ leaf . text ] ) ||
677695 null ) ( ) ;
678696
679697 return (
@@ -691,7 +709,7 @@ export default function JsonEditor({
691709 </ span >
692710 ) ;
693711 } }
694- renderElement = { ( props : any ) => {
712+ renderElement = { ( props : RenderElementProps ) => {
695713 // This will be the path to the image element.
696714 const { element, children, attributes } = props ;
697715 const path = ReactEditor . findPath ( editor , element ) ;
@@ -783,29 +801,31 @@ export type PathIndex = [number, number[]];
783801const getMultipathDecorationsByMatchesAndTextPathIndexes = (
784802 syntaxParts : SyntaxPart [ ] ,
785803 textPathIndexes : PathIndex [ ] ,
786- ) : any [ ] => {
787- const multipathDecorations : any [ ] = syntaxParts . map ( ( syntaxPart ) => {
788- const nodes = getNodesFromIndexAndLength (
789- syntaxPart . index ,
790- syntaxPart . length ,
791- textPathIndexes ,
792- ) ;
793- return {
794- nodes : nodes ,
795- syntaxPart,
796- } ;
797- } ) ;
804+ ) : MultipathDecoration [ ] => {
805+ const multipathDecorations : MultipathDecoration [ ] = syntaxParts . map (
806+ ( syntaxPart ) => {
807+ const nodes = getNodesFromIndexAndLength (
808+ syntaxPart . index ,
809+ syntaxPart . length ,
810+ textPathIndexes ,
811+ ) ;
812+ return {
813+ nodes : nodes ,
814+ syntaxPart,
815+ } ;
816+ } ,
817+ ) ;
798818 return multipathDecorations ;
799819} ;
800820
801821export const getNodesFromIndexAndLength = (
802822 index : number ,
803823 length : number ,
804824 textPathIndexes : PathIndex [ ] ,
805- ) : any [ ] => {
825+ ) : NodeRange [ ] => {
806826 const { nodes } = textPathIndexes . reduce (
807827 (
808- acc : { nodes : any [ ] ; index : number ; length : number } ,
828+ acc : { nodes : NodeRange [ ] ; index : number ; length : number } ,
809829 textPathIndex : PathIndex ,
810830 ) => {
811831 if ( acc . length <= 0 ) return acc ;
@@ -816,7 +836,7 @@ export const getNodesFromIndexAndLength = (
816836 const anchor = acc . index ;
817837 const focus = Math . min ( anchor + acc . length , textPathLength ) ;
818838 const lengthInNode = focus - anchor ;
819- const node : any = { anchor, focus, path : nodePath } ;
839+ const node : NodeRange = { anchor, focus, path : nodePath } ;
820840 return {
821841 nodes : [ ...acc . nodes , node ] ,
822842 index : 0 ,
@@ -828,9 +848,14 @@ export const getNodesFromIndexAndLength = (
828848 return nodes ;
829849} ;
830850
831- const makeDecorationsToMap = ( decorations : any [ ] ) : Record < string , any [ ] > => {
832- return decorations . reduce ( ( acc , decoration ) => {
833- const stringPath = decoration . anchor . path . join ( ',' ) ;
834- return { ...acc , [ stringPath ] : [ ...( acc [ stringPath ] || [ ] ) , decoration ] } ;
835- } , { } ) ;
851+ const makeDecorationsToMap = (
852+ decorations : RangeWithSyntaxPart [ ] ,
853+ ) : Record < string , RangeWithSyntaxPart [ ] > => {
854+ return decorations . reduce (
855+ ( acc , decoration ) => {
856+ const stringPath = decoration . anchor . path . join ( ',' ) ;
857+ return { ...acc , [ stringPath ] : [ ...( acc [ stringPath ] || [ ] ) , decoration ] } ;
858+ } ,
859+ { } as Record < string , RangeWithSyntaxPart [ ] > ,
860+ ) ;
836861} ;
0 commit comments