@xyo-network/react-typedoc 2.26.37 → 2.26.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/docs.json +1 -1
  2. package/package.json +1 -1
  3. package/src/CommentViewer.tsx +15 -0
  4. package/src/JsonViewerButton.tsx +33 -0
  5. package/src/ProjectTwoPanelReflectionViewer.stories.tsx +37 -0
  6. package/src/ProjectTwoPanelReflectionViewer.tsx +14 -0
  7. package/src/ReflectionLookup.ts +3 -0
  8. package/src/ReflectionViewer/Container.tsx +35 -0
  9. package/src/ReflectionViewer/Declaration.tsx +30 -0
  10. package/src/ReflectionViewer/DeclarationContainer.tsx +32 -0
  11. package/src/ReflectionViewer/NameViewer.tsx +39 -0
  12. package/src/ReflectionViewer/Project.tsx +32 -0
  13. package/src/ReflectionViewer/ReflectionGroupViewer.tsx +70 -0
  14. package/src/ReflectionViewer/ReflectionViewer.tsx +40 -0
  15. package/src/ReflectionViewer/ReflectionViewerProps.tsx +17 -0
  16. package/src/ReflectionViewer/SomeTypeViewer/SomeTypeViewer.tsx +23 -0
  17. package/src/ReflectionViewer/SomeTypeViewer/TypeBuilder.ts +6 -0
  18. package/src/ReflectionViewer/SomeTypeViewer/buildArrayString.tsx +14 -0
  19. package/src/ReflectionViewer/SomeTypeViewer/buildIntersectionString.tsx +18 -0
  20. package/src/ReflectionViewer/SomeTypeViewer/buildReferenceString.ts +21 -0
  21. package/src/ReflectionViewer/SomeTypeViewer/buildReflectionString.tsx +9 -0
  22. package/src/ReflectionViewer/SomeTypeViewer/buildTypeString.tsx +49 -0
  23. package/src/ReflectionViewer/SomeTypeViewer/buildUnionString.tsx +18 -0
  24. package/src/ReflectionViewer/SomeTypeViewer/index.ts +1 -0
  25. package/src/ReflectionViewer/index.ts +8 -0
  26. package/src/SomeReflection.ts +7 -0
  27. package/src/SourceViewer.tsx +17 -0
  28. package/src/TreeViewer/Reflection.tsx +62 -0
  29. package/src/TreeViewer/ReflectionGroup.tsx +24 -0
  30. package/src/TreeViewer/index.ts +2 -0
  31. package/src/TwoPanelReflectionViewer.tsx +99 -0
  32. package/src/createLookup.ts +7 -0
  33. package/src/index.ts +9 -0
  34. package/src/resolveChildren.ts +24 -0
  35. package/src/trimFlagLabel.ts +6 -0
package/dist/docs.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "fileName": "index.ts",
11
11
  "line": 1,
12
12
  "character": 0,
13
- "url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/blob/eeec410/packages/typedoc/src/index.ts#L1"
13
+ "url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/blob/c31a96d/packages/typedoc/src/index.ts#L1"
14
14
  }
15
15
  ]
16
16
  }
package/package.json CHANGED
@@ -83,5 +83,5 @@
83
83
  },
84
84
  "sideEffects": false,
85
85
  "types": "dist/esm/index.d.ts",
86
- "version": "2.26.37"
86
+ "version": "2.26.38"
87
87
  }
@@ -0,0 +1,15 @@
1
+ import { Typography } from '@mui/material'
2
+ import { FlexBoxProps, FlexCol } from '@xylabs/react-flexbox'
3
+ import { Comment } from 'typedoc'
4
+
5
+ export interface CommentViewerProps extends FlexBoxProps {
6
+ comment: Comment
7
+ }
8
+
9
+ export const CommentViewer: React.FC<CommentViewerProps> = ({ comment, ...props }) => {
10
+ return (
11
+ <FlexCol alignItems="stretch" {...props}>
12
+ <Typography variant="body2">{comment.summary[0]?.text}</Typography>
13
+ </FlexCol>
14
+ )
15
+ }
@@ -0,0 +1,33 @@
1
+ import { Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'
2
+ import { ButtonEx, ButtonExProps } from '@xylabs/react-button'
3
+ import { lazy, Suspense, useState } from 'react'
4
+ import { ReactJsonViewProps } from 'react-json-view'
5
+
6
+ const JsonView = lazy(() => import(/* webpackChunkName: "jsonView" */ 'react-json-view'))
7
+
8
+ export interface JsonViewerButtonProps extends ButtonExProps {
9
+ src: object
10
+ jsonViewProps?: Partial<ReactJsonViewProps>
11
+ }
12
+
13
+ export const JsonViewerButton: React.FC<JsonViewerButtonProps> = ({ title, src, jsonViewProps, ...props }) => {
14
+ const [open, setOpen] = useState(false)
15
+ return (
16
+ <>
17
+ <ButtonEx onClick={() => setOpen(!open)} {...props}>
18
+ JSON
19
+ </ButtonEx>
20
+ <Dialog open={open} onClose={() => setOpen(false)}>
21
+ {title ? <DialogTitle>{title}</DialogTitle> : null}
22
+ <DialogContent>
23
+ <Suspense fallback={<div />}>
24
+ <JsonView src={src} {...jsonViewProps} />
25
+ </Suspense>
26
+ </DialogContent>
27
+ <DialogActions>
28
+ <ButtonEx onClick={() => setOpen(false)}>Close</ButtonEx>
29
+ </DialogActions>
30
+ </Dialog>
31
+ </>
32
+ )
33
+ }
@@ -0,0 +1,37 @@
1
+ import { ComponentMeta, ComponentStory } from '@storybook/react'
2
+ // eslint-disable-next-line import/no-internal-modules
3
+ import clientDocs from '@xyo-network/core/dist/docs.json'
4
+ import { BrowserRouter } from 'react-router-dom'
5
+ import { ProjectReflection } from 'typedoc'
6
+
7
+ import { ProjectTwoPanelReflectionViewer } from './ProjectTwoPanelReflectionViewer'
8
+
9
+ const StorybookEntry = {
10
+ argTypes: {},
11
+ component: ProjectTwoPanelReflectionViewer,
12
+ parameters: {
13
+ docs: {
14
+ page: null,
15
+ },
16
+ },
17
+ title: 'typedoc/TypeDocViewer/ProjectTwoPanelReflectionViewer',
18
+ } as ComponentMeta<typeof ProjectTwoPanelReflectionViewer>
19
+
20
+ const Template: ComponentStory<typeof ProjectTwoPanelReflectionViewer> = ({ reflection, ...props }) => {
21
+ return (
22
+ <BrowserRouter>
23
+ <ProjectTwoPanelReflectionViewer height="90vh" reflection={reflection} {...props} />
24
+ </BrowserRouter>
25
+ )
26
+ }
27
+
28
+ const Client = Template.bind({})
29
+ const clientDocsWithProject = { ...clientDocs }
30
+ Client.args = {
31
+ reflection: clientDocsWithProject as unknown as ProjectReflection,
32
+ }
33
+
34
+ export { Client }
35
+
36
+ // eslint-disable-next-line import/no-default-export
37
+ export default StorybookEntry
@@ -0,0 +1,14 @@
1
+ import { assertEx } from '@xylabs/sdk-js'
2
+ import { ProjectReflection } from 'typedoc'
3
+
4
+ import { ContainerReflectionViewerProps, DeclarationContainerReflectionViewer } from './ReflectionViewer'
5
+ import { TwoPanelReflectionViewer } from './TwoPanelReflectionViewer'
6
+
7
+ export const ProjectTwoPanelReflectionViewer: React.FC<ContainerReflectionViewerProps<ProjectReflection>> = ({
8
+ reflection,
9
+ itemRenderer = DeclarationContainerReflectionViewer,
10
+ ...props
11
+ }) => {
12
+ assertEx(reflection.kindString === 'Project', `Project !== ${reflection.kindString}`)
13
+ return <TwoPanelReflectionViewer itemRenderer={itemRenderer} reflection={reflection} {...props} />
14
+ }
@@ -0,0 +1,3 @@
1
+ import { DeclarationReflection } from 'typedoc'
2
+
3
+ export type ReflectionLookup<T extends DeclarationReflection = DeclarationReflection> = Record<string, T>
@@ -0,0 +1,35 @@
1
+ import { ContainerReflection, ReflectionGroup } from 'typedoc'
2
+
3
+ import { createLookup } from '../createLookup'
4
+ import { ReflectionGroupViewer } from './ReflectionGroupViewer'
5
+ import { ReflectionViewer } from './ReflectionViewer'
6
+ import { ReflectionViewerProps } from './ReflectionViewerProps'
7
+
8
+ export interface ContainerReflectionViewerProps<T extends ContainerReflection = ContainerReflection> extends ReflectionViewerProps<T> {
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ itemRenderer?: React.FC<ReflectionViewerProps<any>>
11
+ }
12
+
13
+ export const ContainerReflectionViewer: React.FC<ContainerReflectionViewerProps> = ({ children, reflection, hiddenFlags, itemRenderer = ReflectionViewer, ...props }) => {
14
+ const lookup = createLookup(reflection)
15
+
16
+ return (
17
+ <ReflectionViewer title="ContainerReflectionViewer" sources reflection={reflection} lookup={lookup} {...props}>
18
+ {reflection.groups?.map((group: ReflectionGroup) => {
19
+ return (
20
+ <ReflectionGroupViewer
21
+ margin={1}
22
+ lookup={lookup}
23
+ renderer={itemRenderer}
24
+ key={group.title}
25
+ group={group}
26
+ reflection={reflection}
27
+ hiddenFlags={hiddenFlags}
28
+ alignItems="stretch"
29
+ />
30
+ )
31
+ })}
32
+ {children}
33
+ </ReflectionViewer>
34
+ )
35
+ }
@@ -0,0 +1,30 @@
1
+ import { DeclarationReflection, SignatureReflection } from 'typedoc'
2
+
3
+ import { ReflectionViewer } from './ReflectionViewer'
4
+ import { ReflectionViewerProps } from './ReflectionViewerProps'
5
+
6
+ export const DeclarationReflectionViewer: React.FC<ReflectionViewerProps<DeclarationReflection>> = ({ reflection, hiddenFlags, ...props }) => {
7
+ const safeSignatures = (signatures?: SignatureReflection[] | SignatureReflection) => {
8
+ return Array.isArray(signatures) ? signatures : signatures ? [signatures] : undefined
9
+ }
10
+
11
+ return (
12
+ <ReflectionViewer
13
+ nameViewer={reflection.signatures || reflection.getSignature || reflection.setSignature ? null : undefined}
14
+ title="DeclarationReflectionViewer"
15
+ hiddenFlags={hiddenFlags}
16
+ reflection={reflection}
17
+ {...props}
18
+ >
19
+ {reflection.signatures?.map((signature) => {
20
+ return <ReflectionViewer key={signature.id} hiddenFlags={hiddenFlags} reflection={signature} />
21
+ })}
22
+ {safeSignatures(reflection.getSignature)?.map((signature) => {
23
+ return <ReflectionViewer marginX={1} key={signature.id} hiddenFlags={hiddenFlags} reflection={signature} />
24
+ })}
25
+ {safeSignatures(reflection.setSignature)?.map((signature) => {
26
+ return <ReflectionViewer marginX={1} key={signature.id} hiddenFlags={hiddenFlags} reflection={signature} />
27
+ })}
28
+ </ReflectionViewer>
29
+ )
30
+ }
@@ -0,0 +1,32 @@
1
+ import { useTheme } from '@mui/material'
2
+ import { useLocation } from 'react-router-dom'
3
+ import { DeclarationReflection } from 'typedoc'
4
+
5
+ import { ContainerReflectionViewer, ContainerReflectionViewerProps } from './Container'
6
+ import { DeclarationReflectionViewer } from './Declaration'
7
+
8
+ export interface DeclarationContainerReflectionViewerProps extends ContainerReflectionViewerProps {
9
+ reflection: DeclarationReflection
10
+ }
11
+
12
+ export const DeclarationContainerReflectionViewer: React.FC<DeclarationContainerReflectionViewerProps> = ({
13
+ reflection,
14
+ lookup,
15
+ itemRenderer = DeclarationReflectionViewer,
16
+ ...props
17
+ }) => {
18
+ const { hash } = useLocation()
19
+ const theme = useTheme()
20
+
21
+ return (
22
+ <ContainerReflectionViewer
23
+ title="DeclarationContainerReflectionViewer"
24
+ paper={hash.substring(1) === reflection.name}
25
+ bgcolor={hash.substring(1) === reflection.name ? theme.palette.background.default : undefined}
26
+ lookup={lookup}
27
+ itemRenderer={itemRenderer}
28
+ reflection={reflection}
29
+ {...props}
30
+ />
31
+ )
32
+ }
@@ -0,0 +1,39 @@
1
+ import { Chip, Stack, Typography, TypographyVariant } from '@mui/material'
2
+ import { FlexBoxProps, FlexRow } from '@xylabs/react-flexbox'
3
+
4
+ import { JsonViewerButton } from '../JsonViewerButton'
5
+ import { SomeReflection } from '../SomeReflection'
6
+ import { trimFlagLabel } from '../trimFlagLabel'
7
+ import { ReflectionViewerProps } from './ReflectionViewerProps'
8
+ import { SomeTypeViewer } from './SomeTypeViewer'
9
+
10
+ export interface NameViewerProps extends FlexBoxProps {
11
+ reflection: SomeReflection
12
+ variant?: TypographyVariant
13
+ reflectionViewer: React.FC<ReflectionViewerProps>
14
+ }
15
+
16
+ export const NameViewer: React.FC<NameViewerProps> = ({ reflectionViewer, variant, reflection, ...props }) => {
17
+ return (
18
+ <FlexRow justifyContent="flex-start" {...props}>
19
+ <FlexRow marginRight={1}>
20
+ <Typography variant={variant} noWrap>
21
+ {reflection.name}
22
+ {reflection.type ? <>:&nbsp;</> : null}
23
+ </Typography>
24
+ <SomeTypeViewer reflection={reflection} reflectionViewer={reflectionViewer} />
25
+ </FlexRow>
26
+ <Stack direction="row" spacing={1}>
27
+ <Chip size="small" label={reflection.kindString} />
28
+ {reflection.flags
29
+ ? Object.entries(reflection.flags).map(([flag, value]) => {
30
+ return value ? <Chip size="small" key={flag} label={trimFlagLabel(flag)} variant="outlined" /> : null
31
+ })
32
+ : null}
33
+ </Stack>
34
+ {document && document?.location.hostname === 'localhost' && (
35
+ <JsonViewerButton jsonViewProps={{ collapsed: 1 }} size="small" variant="contained" padding={0} marginX={1} src={reflection} />
36
+ )}
37
+ </FlexRow>
38
+ )
39
+ }
@@ -0,0 +1,32 @@
1
+ import { useMemo } from 'react'
2
+ import { ProjectReflection, ReflectionGroup } from 'typedoc'
3
+
4
+ import { createLookup } from '../createLookup'
5
+ import { ContainerReflectionViewerProps } from './Container'
6
+ import { ReflectionGroupViewer } from './ReflectionGroupViewer'
7
+ import { ReflectionViewer } from './ReflectionViewer'
8
+
9
+ export const ProjectReflectionViewer: React.FC<ContainerReflectionViewerProps<ProjectReflection>> = ({ reflection, hiddenFlags, itemRenderer = ReflectionViewer, ...props }) => {
10
+ const lookup = useMemo(() => createLookup(reflection), [reflection])
11
+ return (
12
+ <ReflectionViewer title="ProjectReflectionViewer" hiddenFlags={hiddenFlags} reflection={reflection} {...props}>
13
+ {useMemo(() => {
14
+ return reflection.groups?.map((group: ReflectionGroup) => {
15
+ return (
16
+ <ReflectionGroupViewer
17
+ autoscroll
18
+ variant="h6"
19
+ lookup={lookup}
20
+ key={group.title}
21
+ renderer={itemRenderer}
22
+ group={group}
23
+ reflection={reflection}
24
+ alignItems="stretch"
25
+ hiddenFlags={hiddenFlags}
26
+ />
27
+ )
28
+ })
29
+ }, [lookup, reflection, hiddenFlags, itemRenderer])}
30
+ </ReflectionViewer>
31
+ )
32
+ }
@@ -0,0 +1,70 @@
1
+ import { Typography } from '@mui/material'
2
+ import { FlexCol, FlexRow } from '@xylabs/react-flexbox'
3
+ import { useEffect } from 'react'
4
+ import { useLocation } from 'react-router-dom'
5
+ import { ContainerReflection, ReflectionFlags, ReflectionGroup } from 'typedoc'
6
+
7
+ import { JsonViewerButton } from '../JsonViewerButton'
8
+ import { resolveChildren } from '../resolveChildren'
9
+ import { ReflectionViewer } from './ReflectionViewer'
10
+ import { FlagFilter, ReflectionViewerProps } from './ReflectionViewerProps'
11
+
12
+ export interface ReflectionGroupViewerProps extends ReflectionViewerProps<ContainerReflection> {
13
+ reflection: ContainerReflection
14
+ renderer?: React.FC<ReflectionViewerProps>
15
+ group: ReflectionGroup
16
+ autoscroll?: boolean
17
+ }
18
+
19
+ export const ReflectionGroupViewer: React.FC<ReflectionGroupViewerProps> = ({
20
+ variant,
21
+ group,
22
+ children,
23
+ lookup,
24
+ autoscroll = false,
25
+ renderer = ReflectionViewer,
26
+ hiddenFlags,
27
+ ...props
28
+ }) => {
29
+ const hide = (flags?: ReflectionFlags, hiddenFlags: FlagFilter[] = []) => {
30
+ let hide = false
31
+ hiddenFlags.map((hiddenFlag) => {
32
+ if (flags?.[hiddenFlag]) {
33
+ hide = true
34
+ }
35
+ })
36
+ return hide
37
+ }
38
+
39
+ const resolvedChildern = resolveChildren(group, lookup) ?? []
40
+
41
+ const visibleChildren = hiddenFlags
42
+ ? resolvedChildern.reduce((acc, item) => {
43
+ return acc + (hide(item.flags, hiddenFlags) ? 0 : 1)
44
+ }, 0)
45
+ : 1
46
+
47
+ const { hash } = useLocation()
48
+ useEffect(() => {
49
+ if (hash && autoscroll) {
50
+ document.querySelector(hash)?.scrollIntoView({ behavior: 'smooth' })
51
+ }
52
+ }, [hash, autoscroll])
53
+ return visibleChildren > 0 ? (
54
+ <FlexCol title="ReflectionGroupViewer" {...props}>
55
+ <FlexRow marginY={1} justifyContent="flex-start">
56
+ <Typography variant={variant}>{group.title}</Typography>
57
+ <JsonViewerButton jsonViewProps={{ collapsed: 1 }} size="small" variant="contained" padding={0} marginX={1} src={resolveChildren(group, lookup)} />
58
+ </FlexRow>
59
+ {resolveChildren(group, lookup).map((reflection) => {
60
+ return reflection ? (
61
+ // I wrap this in a div since React does not understand that they have keys using the Renderer
62
+ <div id={reflection.name} key={reflection.id}>
63
+ {renderer({ hiddenFlags, lookup, margin: 1, padding: 1, reflection })}
64
+ </div>
65
+ ) : null
66
+ })}
67
+ {children}
68
+ </FlexCol>
69
+ ) : null
70
+ }
@@ -0,0 +1,40 @@
1
+ import { FlexCol } from '@xylabs/react-flexbox'
2
+ import { ReflectionFlags } from 'typedoc'
3
+
4
+ import { CommentViewer } from '../CommentViewer'
5
+ import { SomeReflection } from '../SomeReflection'
6
+ import { SourceViewer } from '../SourceViewer'
7
+ import { NameViewer } from './NameViewer'
8
+ import { FlagFilter, ReflectionViewerProps } from './ReflectionViewerProps'
9
+
10
+ const hide = (flags?: ReflectionFlags, hiddenFlags: FlagFilter[] = []) => {
11
+ let hide = false
12
+ hiddenFlags.map((hiddenFlag) => {
13
+ if (flags?.[hiddenFlag]) {
14
+ hide = true
15
+ }
16
+ })
17
+ return hide
18
+ }
19
+
20
+ export const ReflectionViewer: React.FC<ReflectionViewerProps> = ({ variant, nameViewer, children, reflection, hiddenFlags, sources = false, ...props }) => {
21
+ const someReflection = reflection as SomeReflection
22
+
23
+ return hide(reflection?.flags, hiddenFlags) ? null : (
24
+ <FlexCol title="ReflectionViewer" alignItems="stretch" {...props}>
25
+ {nameViewer === undefined ? <NameViewer marginY={0.25} variant={variant} reflection={someReflection} reflectionViewer={ReflectionViewer} /> : nameViewer}
26
+ {reflection.comment ? <CommentViewer comment={reflection.comment} /> : null}
27
+ {sources && reflection.sources && children ? (
28
+ <>
29
+ {reflection.sources.map((source, index) => {
30
+ return <SourceViewer key={index} source={source} />
31
+ })}
32
+ </>
33
+ ) : null}
34
+ {someReflection.parameters?.map((parameter) => {
35
+ return <ReflectionViewer hiddenFlags={hiddenFlags} marginY={0.25} marginX={1} key={parameter.id} reflection={parameter} />
36
+ }) ?? null}
37
+ {children}
38
+ </FlexCol>
39
+ )
40
+ }
@@ -0,0 +1,17 @@
1
+ import { TypographyVariant } from '@mui/material'
2
+ import { FlexBoxProps } from '@xylabs/react-flexbox'
3
+ import { ReactElement } from 'react'
4
+ import { Reflection } from 'typedoc'
5
+
6
+ import { ReflectionLookup } from '../ReflectionLookup'
7
+
8
+ export type FlagFilter = 'isPublic' | 'isPrivate' | 'isProtected'
9
+
10
+ export interface ReflectionViewerProps<T extends Reflection = Reflection> extends FlexBoxProps {
11
+ reflection: T
12
+ nameViewer?: ReactElement | null
13
+ lookup?: ReflectionLookup
14
+ hiddenFlags?: FlagFilter[]
15
+ sources?: boolean
16
+ variant?: TypographyVariant
17
+ }
@@ -0,0 +1,23 @@
1
+ import { Typography, TypographyProps } from '@mui/material'
2
+
3
+ import { SomeReflection } from '../../SomeReflection'
4
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
5
+ import { buildTypeString } from './buildTypeString'
6
+
7
+ export interface SomeTypeViewerProps extends TypographyProps {
8
+ reflection: SomeReflection
9
+ opacity?: number
10
+ reflectionViewer: React.FC<ReflectionViewerProps>
11
+ }
12
+
13
+ export const SomeTypeViewer: React.FC<SomeTypeViewerProps> = ({ reflectionViewer, opacity = 0.5, reflection, ...props }) => {
14
+ const typeReactNode = reflection.type ? buildTypeString(reflection.type, reflectionViewer) : ''
15
+ if (typeof typeReactNode === 'string') {
16
+ return (
17
+ <Typography title="SomeTypeViewer" style={{ opacity }} {...props}>
18
+ {typeReactNode}
19
+ </Typography>
20
+ )
21
+ }
22
+ return <>{typeReactNode}</>
23
+ }
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from 'react'
2
+ import { SomeType, Type } from 'typedoc'
3
+
4
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
5
+
6
+ export type TypeBuilder = (type: SomeType | Type, reflectionViewer: React.FC<ReflectionViewerProps>, typeBuilder?: TypeBuilder) => ReactNode
@@ -0,0 +1,14 @@
1
+ import { ArrayType } from 'typedoc'
2
+
3
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
4
+ import { TypeBuilder } from './TypeBuilder'
5
+
6
+ export const buildArrayString = (typeObj: ArrayType, reflectionViewer: React.FC<ReflectionViewerProps>, typeBuilder: TypeBuilder) => {
7
+ const parts: string[] = []
8
+ const typeString = typeBuilder(typeObj.elementType, reflectionViewer)
9
+ if (typeof typeString === 'string') {
10
+ parts.push(typeString)
11
+ }
12
+ parts.push('[]')
13
+ return parts
14
+ }
@@ -0,0 +1,18 @@
1
+ import { IntersectionType } from 'typedoc'
2
+
3
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
4
+ import { TypeBuilder } from './TypeBuilder'
5
+
6
+ export const buildIntersectionString = (typeObj: IntersectionType, reflectionViewer: React.FC<ReflectionViewerProps>, typeBuilder: TypeBuilder) => {
7
+ const parts: string[] = []
8
+ if (typeObj.types) {
9
+ parts.push(
10
+ typeObj.types
11
+ .map((arg) => {
12
+ return typeBuilder(arg, reflectionViewer)
13
+ })
14
+ .join(' & ')
15
+ )
16
+ }
17
+ return parts
18
+ }
@@ -0,0 +1,21 @@
1
+ import { ReferenceType } from 'typedoc'
2
+
3
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
4
+ import { TypeBuilder } from './TypeBuilder'
5
+
6
+ export const buildReferenceString = (typeObj: ReferenceType, reflectionViewer: React.FC<ReflectionViewerProps>, typeBuilder: TypeBuilder) => {
7
+ const parts: string[] = []
8
+ parts.push(typeObj.name)
9
+ if (typeObj.typeArguments) {
10
+ parts.push('<')
11
+ parts.push(
12
+ typeObj.typeArguments
13
+ .map((arg) => {
14
+ return typeBuilder(arg, reflectionViewer)
15
+ })
16
+ .join(', ')
17
+ )
18
+ parts.push('>')
19
+ }
20
+ return parts
21
+ }
@@ -0,0 +1,9 @@
1
+ import { ReflectionType } from 'typedoc'
2
+
3
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
4
+
5
+ export const buildRelfectionString = (typeObj: ReflectionType, reflectionViewer: React.FC<ReflectionViewerProps>) => {
6
+ if (typeObj.declaration) {
7
+ return <>{reflectionViewer({ reflection: typeObj.declaration })}</>
8
+ }
9
+ }
@@ -0,0 +1,49 @@
1
+ import { ReactNode } from 'react'
2
+ import { SomeType, Type } from 'typedoc'
3
+
4
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
5
+ import { buildArrayString } from './buildArrayString'
6
+ import { buildIntersectionString } from './buildIntersectionString'
7
+ import { buildReferenceString } from './buildReferenceString'
8
+ import { buildRelfectionString } from './buildReflectionString'
9
+ import { buildUnionString } from './buildUnionString'
10
+ import { TypeBuilder } from './TypeBuilder'
11
+
12
+ export const buildTypeString: TypeBuilder = (type: SomeType | Type, reflectionViewer: React.FC<ReflectionViewerProps>): ReactNode => {
13
+ const someType = type as SomeType
14
+ const parts: string[] = []
15
+
16
+ switch (someType.type) {
17
+ case 'intrinsic':
18
+ parts.push(someType.name)
19
+ break
20
+ case 'intersection': {
21
+ parts.push(...buildIntersectionString(someType, reflectionViewer, buildTypeString))
22
+ break
23
+ }
24
+ case 'literal':
25
+ parts.push(JSON.stringify(someType.value))
26
+ break
27
+ case 'array': {
28
+ parts.push(...buildArrayString(someType, reflectionViewer, buildTypeString))
29
+ break
30
+ }
31
+ case 'reference': {
32
+ parts.push(...buildReferenceString(someType, reflectionViewer, buildTypeString))
33
+ break
34
+ }
35
+ case 'union': {
36
+ parts.push(...buildUnionString(someType, reflectionViewer, buildTypeString))
37
+ break
38
+ }
39
+ case 'reflection': {
40
+ return buildRelfectionString(someType, reflectionViewer)
41
+ }
42
+ default:
43
+ parts.push('#')
44
+ parts.push(someType.type)
45
+ parts.push('#')
46
+ break
47
+ }
48
+ return parts.join('')
49
+ }
@@ -0,0 +1,18 @@
1
+ import { UnionType } from 'typedoc'
2
+
3
+ import { ReflectionViewerProps } from '../ReflectionViewerProps'
4
+ import { TypeBuilder } from './TypeBuilder'
5
+
6
+ export const buildUnionString = (typeObj: UnionType, reflectionViewer: React.FC<ReflectionViewerProps>, typeBuilder: TypeBuilder) => {
7
+ const parts: string[] = []
8
+ if (typeObj.types) {
9
+ parts.push(
10
+ typeObj.types
11
+ .map((arg) => {
12
+ return typeBuilder(arg, reflectionViewer)
13
+ })
14
+ .join(' | ')
15
+ )
16
+ }
17
+ return parts
18
+ }
@@ -0,0 +1 @@
1
+ export * from './SomeTypeViewer'
@@ -0,0 +1,8 @@
1
+ export * from './Container'
2
+ export * from './Declaration'
3
+ export * from './DeclarationContainer'
4
+ export * from './Project'
5
+ export * from './ReflectionGroupViewer'
6
+ export * from './ReflectionViewer'
7
+ export * from './ReflectionViewerProps'
8
+ export * from './SomeTypeViewer'
@@ -0,0 +1,7 @@
1
+ import { ParameterReflection, Reflection, SomeType } from 'typedoc'
2
+
3
+ export type WithSomeType<T> = T & { type?: SomeType }
4
+
5
+ export type WithSomeParameters<T> = T & { parameters?: ParameterReflection[] }
6
+
7
+ export type SomeReflection = WithSomeParameters<WithSomeType<Reflection>>
@@ -0,0 +1,17 @@
1
+ import { Typography } from '@mui/material'
2
+ import { FlexBoxProps, FlexCol } from '@xylabs/react-flexbox'
3
+ import { SourceReference } from 'typedoc'
4
+
5
+ export interface SourceViewerProps extends FlexBoxProps {
6
+ source: SourceReference
7
+ }
8
+
9
+ export const SourceViewer: React.FC<SourceViewerProps> = ({ source, ...props }) => {
10
+ return (
11
+ <FlexCol alignItems="stretch" {...props}>
12
+ <Typography style={{ opacity: 0.5 }} variant="body2">
13
+ <i>{source.fileName}</i>
14
+ </Typography>
15
+ </FlexCol>
16
+ )
17
+ }
@@ -0,0 +1,62 @@
1
+ import { Add, Remove } from '@mui/icons-material'
2
+ import { TreeItem, TreeView } from '@mui/lab'
3
+ import { Typography } from '@mui/material'
4
+ import { FlexBoxProps, FlexCol } from '@xylabs/react-flexbox'
5
+ import { useNavigate } from 'react-router-dom'
6
+ import { ContainerReflection, Reflection } from 'typedoc'
7
+
8
+ import { ReflectionLookup } from '../ReflectionLookup'
9
+ import { FlagFilter } from '../ReflectionViewer'
10
+
11
+ export interface ReflectionTreeViewerProps<T extends Reflection = ContainerReflection> extends FlexBoxProps {
12
+ reflection: T
13
+ lookup?: ReflectionLookup
14
+ hiddenFlags?: FlagFilter[]
15
+ searchTerm?: string
16
+ }
17
+
18
+ export const ReflectionTreeViewer: React.FC<ReflectionTreeViewerProps> = ({ lookup, reflection, searchTerm, ...props }) => {
19
+ const navigate = useNavigate()
20
+ return (
21
+ <FlexCol alignItems="stretch" {...props}>
22
+ {/* TODO - move this into a title component */}
23
+ {/*{nameViewer === undefined ? <NameViewer variant={variant} reflection={reflection} /> : nameViewer}*/}
24
+ {/*{reflection.comment ? <CommentViewer comment={reflection.comment} /> : null}*/}
25
+ {/*{reflection.sources ? (*/}
26
+ {/* <>*/}
27
+ {/* {reflection.sources.map((source, index) => {*/}
28
+ {/* return <SourceViewer key={index} source={source} />*/}
29
+ {/* })}*/}
30
+ {/* </>*/}
31
+ {/*) : null}*/}
32
+ {/* TODO - when searching do not include categories that dont have children, pull maps out of view */}
33
+ <TreeView
34
+ aria-label="XYO SDK Documentation"
35
+ defaultExpandIcon={<Add />}
36
+ defaultCollapseIcon={<Remove />}
37
+ defaultExpanded={reflection.groups ? [reflection.groups[0].title] : []}
38
+ >
39
+ {reflection.groups?.map((group, index) => (
40
+ <TreeItem key={`primary-${index}`} nodeId={group.title} label={<Typography variant="h6">{group.title}</Typography>}>
41
+ {group.children.map((child, jndex) => {
42
+ const searchTermTrimmed = searchTerm?.trim().toLowerCase()
43
+ const childReflection = typeof child === 'number' ? lookup?.[child as number] : child
44
+ return childReflection && (!searchTermTrimmed || childReflection.name.toLowerCase().indexOf(searchTermTrimmed) !== -1) ? (
45
+ <TreeItem
46
+ key={`secondary-${index}- ${jndex}`}
47
+ nodeId={`declaration-${childReflection?.id}`}
48
+ label={childReflection.name}
49
+ onClick={() => {
50
+ const hash = `#${childReflection.name}`
51
+ navigate({ hash })
52
+ document.querySelector(hash)?.scrollIntoView({ behavior: 'smooth' })
53
+ }}
54
+ />
55
+ ) : null
56
+ })}
57
+ </TreeItem>
58
+ ))}
59
+ </TreeView>
60
+ </FlexCol>
61
+ )
62
+ }
@@ -0,0 +1,24 @@
1
+ import { Typography } from '@mui/material'
2
+ import { FlexCol, FlexRow } from '@xylabs/react-flexbox'
3
+
4
+ import { JsonViewerButton } from '../JsonViewerButton'
5
+ import { ReflectionGroupViewerProps, ReflectionViewer } from '../ReflectionViewer'
6
+ import { resolveChildren } from '../resolveChildren'
7
+
8
+ export const ReflectionGroupTreeViewer: React.FC<ReflectionGroupViewerProps> = ({ variant, group, children, lookup, renderer = ReflectionViewer, ...props }) => {
9
+ return (
10
+ <FlexCol {...props}>
11
+ <FlexRow marginY={1} justifyContent="flex-start">
12
+ <Typography variant={variant}>{group.title}</Typography>
13
+ <JsonViewerButton jsonViewProps={{ collapsed: 1 }} size="small" variant="contained" padding={0} marginX={1} src={resolveChildren(group, lookup)} />
14
+ </FlexRow>
15
+ {resolveChildren(group, lookup).map((reflection) => {
16
+ return reflection ? (
17
+ // I wrap this in a div since React does not understand that they have keys using the Renderer
18
+ <div key={reflection.id}>{renderer({ lookup, margin: 1, reflection })}</div>
19
+ ) : null
20
+ })}
21
+ {children}
22
+ </FlexCol>
23
+ )
24
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Reflection'
2
+ export * from './ReflectionGroup'
@@ -0,0 +1,99 @@
1
+ import { Search } from '@mui/icons-material'
2
+ import { TextField, useTheme } from '@mui/material'
3
+ import { FlexBoxProps, FlexCol, FlexGrowCol, FlexRow } from '@xylabs/react-flexbox'
4
+ import { useMemo, useState } from 'react'
5
+ import { ReflectionGroup } from 'typedoc'
6
+
7
+ import { createLookup } from './createLookup'
8
+ import { ContainerReflectionViewerProps, ReflectionGroupViewer, ReflectionViewer } from './ReflectionViewer'
9
+ import { ReflectionTreeViewer } from './TreeViewer'
10
+
11
+ export const TwoPanelReflectionViewer: React.FC<ContainerReflectionViewerProps> = ({ reflection, itemRenderer = ReflectionViewer, hiddenFlags, ...props }) => {
12
+ const lookup = useMemo(() => createLookup(reflection), [reflection])
13
+ const theme = useTheme()
14
+ const [searchTerm, setSearchTerm] = useState<string>()
15
+ const onSearchTermChange = (e: React.ChangeEvent<HTMLInputElement>) => {
16
+ setSearchTerm(e.target.value)
17
+ }
18
+
19
+ const reflectionGroups = useMemo(() => {
20
+ return reflection.groups?.map((group: ReflectionGroup) => {
21
+ return (
22
+ <ReflectionGroupViewer
23
+ autoscroll
24
+ variant="h6"
25
+ lookup={lookup}
26
+ renderer={itemRenderer}
27
+ key={group.title}
28
+ group={group}
29
+ reflection={reflection}
30
+ alignItems="stretch"
31
+ hiddenFlags={hiddenFlags}
32
+ />
33
+ )
34
+ })
35
+ }, [itemRenderer, lookup, reflection, hiddenFlags])
36
+
37
+ const NavigationCol: React.FC<FlexBoxProps> = (props) => {
38
+ return (
39
+ <FlexCol {...props}>
40
+ <TextField
41
+ fullWidth
42
+ InputProps={{
43
+ startAdornment: <Search />,
44
+ }}
45
+ onChange={onSearchTermChange}
46
+ />
47
+ <FlexGrowCol marginTop={1} alignItems="stretch">
48
+ <ReflectionTreeViewer
49
+ justifyContent="flex-start"
50
+ position="absolute"
51
+ top={0}
52
+ left={0}
53
+ right={0}
54
+ bottom={0}
55
+ overflow="scroll"
56
+ searchTerm={searchTerm}
57
+ hiddenFlags={hiddenFlags}
58
+ reflection={reflection}
59
+ lookup={lookup}
60
+ border={`1px solid ${theme.palette.grey['300']}`}
61
+ borderRadius={1}
62
+ paddingY={1}
63
+ />
64
+ </FlexGrowCol>
65
+ </FlexCol>
66
+ )
67
+ }
68
+
69
+ const DetailsCol: React.FC<FlexBoxProps> = (props) => {
70
+ return (
71
+ <FlexGrowCol {...props}>
72
+ <FlexGrowCol alignItems="stretch">
73
+ <FlexCol
74
+ alignItems="stretch"
75
+ justifyContent="flex-start"
76
+ position="absolute"
77
+ top={0}
78
+ left={0}
79
+ right={0}
80
+ bottom={0}
81
+ overflow="scroll"
82
+ borderRadius={1}
83
+ padding={1}
84
+ border={`1px solid ${theme.palette.grey['300']}`}
85
+ >
86
+ {reflectionGroups}
87
+ </FlexCol>
88
+ </FlexGrowCol>
89
+ </FlexGrowCol>
90
+ )
91
+ }
92
+
93
+ return (
94
+ <FlexRow alignItems="stretch" justifyContent="start" sx={{ overflowY: 'scroll' }} {...props}>
95
+ <NavigationCol minWidth={320} alignItems="stretch" justifyContent="flex-start" overflow="hidden" />
96
+ <DetailsCol marginLeft={1} alignItems="stretch" justifyContent="flex-start" overflow="hidden" />
97
+ </FlexRow>
98
+ )
99
+ }
@@ -0,0 +1,7 @@
1
+ import { ContainerReflection, DeclarationReflection } from 'typedoc'
2
+
3
+ export const createLookup = <T extends DeclarationReflection>(reflection: ContainerReflection) => {
4
+ const lookup: Record<number, T> = {}
5
+ reflection.children?.forEach((item) => (lookup[item.id] = item as unknown as T))
6
+ return lookup
7
+ }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ export * from './CommentViewer'
2
+ export * from './JsonViewerButton'
3
+ export * from './ProjectTwoPanelReflectionViewer'
4
+ export * from './ReflectionLookup'
5
+ export * from './ReflectionViewer'
6
+ export * from './SomeReflection'
7
+ export * from './SourceViewer'
8
+ export * from './TreeViewer'
9
+ export * from './TwoPanelReflectionViewer'
@@ -0,0 +1,24 @@
1
+ import { Reflection } from 'typedoc'
2
+
3
+ import { ReflectionLookup } from './ReflectionLookup'
4
+ import { SomeReflection } from './SomeReflection'
5
+
6
+ type ReflectionWithChildren = { children: Reflection[] }
7
+
8
+ export const resolveChildren = <T extends SomeReflection>(reflection: ReflectionWithChildren, lookup: ReflectionLookup = {}): T[] => {
9
+ return (reflection.children?.map((child) => {
10
+ switch (typeof child) {
11
+ case 'object':
12
+ return child
13
+ case 'number': {
14
+ const childObj = lookup[child]
15
+ if (childObj === undefined) {
16
+ throw Error(`Child Reference Not Found [${child}]`)
17
+ }
18
+ return childObj
19
+ }
20
+ default:
21
+ throw Error(`Invalid Child Type [${typeof child}, ${child}]`)
22
+ }
23
+ }) ?? []) as T[]
24
+ }
@@ -0,0 +1,6 @@
1
+ export const trimFlagLabel = (label: string) => {
2
+ if (label.startsWith('is')) {
3
+ return label.substring(2)
4
+ }
5
+ return label
6
+ }