@sanity/tsdoc
Version:
Generate API reference docs from TypeScript projects and store in a Sanity-friendly JSON format. Render a static frontend, or as React components.
1 lines • 278 kB
Source Map (JSON)
{"version":3,"file":"react.mjs","sources":["../../src/react/app/helpers.ts","../../src/react/components/ColoredCode.tsx","../../src/react/lib/isArray.ts","../../src/react/lib/ui/LevelContext.ts","../../src/react/lib/ui/useLevel.ts","../../src/react/lib/ui/addResponsiveProp.ts","../../src/react/lib/ui/SizeContext.ts","../../src/react/lib/ui/useSize.ts","../../src/react/lib/ui/useHeadingSize.ts","../../src/react/lib/ui/useSpace.ts","../../src/react/lib/ui/H.tsx","../../src/react/lib/ui/Level.tsx","../../src/react/lib/ui/useTextSize.ts","../../src/react/lib/ui/P.tsx","../../src/react/lib/ui/Size.tsx","../../src/react/app/TSDocContext.ts","../../src/react/app/useTSDoc.ts","../../src/react/app/useExports.ts","../../src/react/app/usePackages.ts","../../src/react/app/nav/FlexSticky.ts","../../src/react/app/nav/getGroupedMembers.ts","../../src/react/components/UnformattedCode.tsx","../../src/react/app/TSDocMemberTitle.tsx","../../src/react/app/lib/compilePath.ts","../../src/react/app/useMemberLink.ts","../../src/react/app/nav/SyntaxTreeItem.ts","../../src/react/app/nav/MemberLink.tsx","../../src/react/app/nav/TreeItemFocus.ts","../../src/react/app/nav/GroupedMembersTree.tsx","../../src/react/app/nav/SyntaxMenuItem.tsx","../../src/react/app/nav/PackageMenuButton.tsx","../../src/react/app/nav/PackageTreeItem.tsx","../../src/react/app/nav/ReleaseMenuButton.tsx","../../src/react/app/nav/SearchWrapper.ts","../../src/react/app/nav/TreeNav.ts","../../src/react/app/useSymbolSearch.ts","../../src/react/app/nav/TSDocSearch.tsx","../../src/react/app/nav/TSDocNav.tsx","../../src/react/comment/CommentBox.tsx","../../src/react/comment/PortableText.tsx","../../src/react/comment/CommentDeprecatedCallout.tsx","../../src/react/comment/CommentExampleBlocks.tsx","../../src/react/comment/CommentRemarks.tsx","../../src/react/comment/CommentReturnType.tsx","../../src/react/comment/CommentSummary.tsx","../../src/react/app/lib/_compile.ts","../../src/react/tooltip/content/ClassTooltipContent.tsx","../../src/react/tooltip/content/EnumTooltipContent.tsx","../../src/react/article/members/helpers.ts","../../src/react/tooltip/content/FunctionTooltipContent.tsx","../../src/react/tooltip/content/InterfaceTooltipContent.tsx","../../src/react/tooltip/content/TypeAliasTooltipContent.tsx","../../src/react/tooltip/content/VariableTooltipContent.tsx","../../src/react/tooltip/ReferenceTooltip.tsx","../../src/react/article/ApiToken.tsx","../../src/react/article/CodeSnippet.tsx","../../src/react/article/TSDocCode.tsx","../../src/react/helpers.ts","../../src/react/article/members/MemberInheritedFrom.tsx","../../src/react/components/ReleaseBadgeTextWrapper.tsx","../../src/react/components/ReleaseBadge.tsx","../../src/react/article/members/TSMemberReleaseTag.tsx","../../src/react/article/members/TSCallSignatureMember.tsx","../../src/react/article/members/TSConstructorMember.tsx","../../src/react/article/members/TSConstructSignatureMember.tsx","../../src/react/article/members/TSEnumMember.tsx","../../src/react/article/members/TSIndexSignatureMember.tsx","../../src/react/article/members/TSMethodMember.tsx","../../src/react/article/members/TSMethodSignatureMember.tsx","../../src/react/article/members/TSPropertyMember.tsx","../../src/react/article/members/TSPropertySignatureMember.tsx","../../src/react/article/members/Members.tsx","../../src/react/article/content/ClassContent.tsx","../../src/react/article/content/FunctionContent.tsx","../../src/react/article/content/InterfaceContent.tsx","../../src/react/article/content/NamespaceContent.tsx","../../src/react/article/content/TypeAliasContent.tsx","../../src/react/article/members/TSVariableParamMember.tsx","../../src/react/article/content/VariableContent.tsx","../../src/react/article/content/ReferenceContent.tsx","../../src/react/article/TSDocArticle.tsx","../../src/react/app/useMember.ts","../../src/react/app/usePackage.ts","../../src/react/app/TSDocDetail.tsx","../../src/react/app/TSDocProvider.tsx","../../src/react/app/TSDocApp.tsx","../../src/react/app/useSymbol.ts","../../src/react/app/TSDocSymbol.tsx","../../src/react/app/TSDocSymbolPreview.tsx","../../src/react/mount.tsx"],"sourcesContent":["import {TSDocAppParams} from '@sanity/tsdoc/store'\n\n/** @beta */\nexport function parsePath(\n path: string,\n options: {basePath?: string; version?: string} = {},\n): TSDocAppParams {\n const {basePath = '', version = '0.0.0'} = options\n const baseSegments = basePath.split('/').filter(Boolean)\n const segments = path.split('/').filter(Boolean).slice(baseSegments.length)\n\n let packageScope: string | null = null\n let packageName: string | null = null\n let releaseVersion: string | null = null\n let exportPath: string | null = null\n let memberSlug: string | null = null\n\n packageName = segments.shift() || null\n\n if (packageName?.startsWith('@')) {\n packageScope = packageName\n packageName = segments.shift() || null\n }\n\n if (packageName) {\n releaseVersion = version\n }\n\n if (releaseVersion) {\n if (segments.length > 1) {\n memberSlug = segments.pop() || null\n exportPath = `./${segments.join('/')}`\n } else if (segments.length === 1) {\n // needs to be this since if the last element is popped then the export path needs to be \"empty\"\n memberSlug = segments.pop() || null\n exportPath = `.`\n }\n }\n\n const params: TSDocAppParams = {\n exportPath,\n packageName,\n packageScope,\n releaseVersion,\n memberSlug,\n }\n\n return params\n}\n","import {cyan, green, yellow} from '@sanity/color'\nimport {ThemeColor, ThemeColorSyntax} from '@sanity/ui'\nimport {css, styled} from 'styled-components'\n\nexport const SyntaxText = styled.code<{$deprecated?: boolean; $syntax?: keyof ThemeColorSyntax}>(\n ({$deprecated, $syntax, theme}) => {\n const {color} = theme.sanity\n\n return css`\n && {\n background-color: transparent;\n color: ${$syntax ? overrideSyntaxColors(color, $syntax) : undefined};\n text-decoration: ${$deprecated ? 'line-through' : undefined};\n }\n `\n },\n)\n\nconst overrideSyntaxColors = (color: ThemeColor, $syntax: keyof ThemeColorSyntax) => {\n const isDarkMode = color.dark\n\n // adds support for issues with light theme\n switch ($syntax) {\n case 'function':\n return !isDarkMode ? green[700].hex : color.syntax[$syntax]\n case 'string':\n return !isDarkMode ? yellow[700].hex : color.syntax[$syntax]\n case 'className':\n return !isDarkMode ? cyan[700].hex : color.syntax[$syntax]\n default:\n return color.syntax[$syntax]\n }\n}\n","export function isArray<T = unknown>(val: unknown): val is Array<T> {\n return Array.isArray(val)\n}\n","import {createContext} from 'react'\n\nexport const LevelContext = createContext<number | null>(null)\n","import {useContext} from 'react'\n\nimport {LevelContext} from './LevelContext'\n\nexport function useLevel(): number {\n const levelContext = useContext(LevelContext) || 1\n\n return levelContext\n}\n","import {isArray} from '../isArray'\n\nexport function addResponsiveProp(a: number | number[], b: number | number[]): number[] {\n const _a = isArray(a) ? a : [a]\n const _b = isArray(b) ? b : [b]\n\n const len = Math.max(_a.length, _b.length)\n const ret: number[] = []\n\n for (let i = 0; i < len; i += 1) {\n const aSize = _a[i] ?? _a[_a.length - 1] ?? 0\n const bSize = _b[i] ?? _b[_b.length - 1] ?? 0\n\n ret.push(aSize + bSize)\n }\n\n return ret\n}\n","import {createContext} from 'react'\n\nexport const SizeContext = createContext<number>(2)\n","import {useContext, useMemo} from 'react'\n\nimport {addResponsiveProp} from './addResponsiveProp'\nimport {SizeContext} from './SizeContext'\n\nexport function useSize(props?: {size?: number | number[]; min?: number; max?: number}): number[] {\n const {min = 0, max = Infinity, size = 0} = props || {}\n const delta = useContext(SizeContext) ?? 0\n\n const __cache_key__ = JSON.stringify([size, delta])\n\n return useMemo(\n () => addResponsiveProp(size, delta).map((s) => Math.min(Math.max(s, min), max)),\n\n // Improve performance: Keep object identify for a given hash of the value\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [__cache_key__],\n )\n}\n","import {useTheme} from '@sanity/ui'\nimport {useMemo} from 'react'\n\nimport {isArray} from '../isArray'\nimport {useLevel} from './useLevel'\nimport {useSize} from './useSize'\n\nexport function useHeadingSize(size: number | number[]): number[] {\n const {fonts} = useTheme().sanity\n const level = useLevel()\n\n const levelSize = useMemo(() => {\n const s = isArray(size) ? size : [size]\n\n return s.map((v) => v - level + 2)\n }, [level, size])\n\n return useSize({size: levelSize, min: 0, max: fonts.heading.sizes.length - 1})\n}\n","import {useTheme} from '@sanity/ui'\n\nimport {useSize} from './useSize'\n\nexport function useSpace(size: number | number[]): number[] {\n const {space} = useTheme().sanity\n\n return useSize({size, min: 0, max: space.length - 1})\n}\n","import {Box, Heading, HeadingProps} from '@sanity/ui'\nimport {HTMLProps} from 'react'\n\nimport {useHeadingSize} from './useHeadingSize'\nimport {useLevel} from './useLevel'\nimport {useSpace} from './useSpace'\n\nexport function H(\n props: Omit<HeadingProps, 'as'> & Omit<HTMLProps<HTMLDivElement>, 'as' | 'ref' | 'size'>,\n): React.ReactNode {\n const {size: sizeProp = 0, ...restProps} = props\n const level = useLevel()\n\n return (\n <Box\n marginTop={useSpace(level === 1 ? [1, 1, 2, 3] : [2, 2, 3, 4])}\n marginBottom={useSpace([2, 2, 2, 3])}\n >\n <Heading as={`h${level}` as 'h1'} {...restProps} size={useHeadingSize(sizeProp)} />\n </Box>\n )\n}\n","import {LevelContext} from './LevelContext'\nimport {useLevel} from './useLevel'\n\nexport function Level(props: {children?: React.ReactNode}): React.ReactNode {\n const {children} = props\n const level = useLevel()\n\n return <LevelContext.Provider value={level + 1}>{children}</LevelContext.Provider>\n}\n","import {useTheme} from '@sanity/ui'\n\nimport {useSize} from './useSize'\n\nexport function useTextSize(size: number | number[]): number[] {\n const {fonts} = useTheme().sanity\n\n return useSize({size, min: 0, max: fonts.text.sizes.length - 1})\n}\n","import {Box, Text, TextProps} from '@sanity/ui'\nimport {HTMLProps} from 'react'\n\nimport {useSpace} from './useSpace'\nimport {useTextSize} from './useTextSize'\n\nexport function P(\n props: Omit<TextProps, 'as'> & Omit<HTMLProps<HTMLDivElement>, 'as' | 'ref' | 'size'>,\n): React.ReactNode {\n const {size: sizeProp = 0, ...restProps} = props\n\n return (\n <Box data-ui=\"P\" marginTop={useSpace([-1, -1, -1])}>\n <Text as=\"p\" {...restProps} size={useTextSize(sizeProp)} />\n </Box>\n )\n}\n","import {useContext} from 'react'\n\nimport {SizeContext} from './SizeContext'\n\nexport function Size(props: {delta: number; children?: React.ReactNode}): React.ReactNode {\n const {delta, children} = props\n const parentSize = useContext(SizeContext)\n const size = parentSize + delta\n\n return <SizeContext.Provider value={size}>{children}</SizeContext.Provider>\n}\n","import {TSDocStore} from '@sanity/tsdoc/store'\nimport {TSDocAppParams} from '@sanity/tsdoc/store'\nimport {createContext} from 'react'\n\n/** @beta */\nexport interface TSDocContextValue {\n basePath: string\n path: string\n params: TSDocAppParams\n updateParams: (fn: (params: TSDocAppParams) => TSDocAppParams) => void\n onPathChange: (nextPath: string, replace?: boolean) => void\n store: TSDocStore\n}\n\nexport const TSDocContext = createContext<TSDocContextValue | null>(null)\n","import {useContext} from 'react'\n\nimport {TSDocContext, TSDocContextValue} from './TSDocContext'\n\n/** @beta */\nexport function useTSDoc(): TSDocContextValue {\n const tsdoc = useContext(TSDocContext)\n\n if (!tsdoc) throw new Error('TSDoc: missing context value')\n\n return tsdoc\n}\n","import {TSDocExportData} from '@sanity/tsdoc/store'\nimport {useEffect, useState} from 'react'\n\nimport {useTSDoc} from './useTSDoc'\n\n/** @beta */\nexport function useExports(): {\n data: TSDocExportData[] | null\n error: Error | null\n loading: boolean\n} {\n const {params, store} = useTSDoc()\n\n const [data, setData] = useState<TSDocExportData[] | undefined | null>(null)\n const [error, setError] = useState<Error | null>(null)\n const [loading, setLoading] = useState(false)\n\n useEffect(() => {\n if (!params.packageName || !params.releaseVersion) {\n setData(null)\n\n return\n }\n\n const queryParams = {\n packageScope: params.packageScope,\n packageName: params.packageName,\n releaseVersion: params.releaseVersion,\n }\n let cancelled = false\n\n async function run() {\n try {\n setLoading(true)\n setData(null)\n const data = await store.exports.get(queryParams)\n\n if (!cancelled) {\n setData(data)\n }\n } catch (err) {\n if (err instanceof Error && !cancelled) {\n setError(err)\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n\n run()\n\n return () => {\n cancelled = true\n }\n }, [params.packageScope, params.packageName, params.releaseVersion, store])\n\n // @ts-expect-error - find a way to fix this\n return {data, error, loading}\n}\n","import type {APIPackage} from '@sanity/tsdoc'\nimport {useEffect, useState} from 'react'\n\nimport {useTSDoc} from './useTSDoc'\n\n/** @beta */\nexport function usePackages(): {\n data: APIPackage[] | null\n error: Error | null\n loading: boolean\n} {\n const {store} = useTSDoc()\n const [data, setData] = useState<APIPackage[] | null>(null)\n const [error, setError] = useState<Error | null>(null)\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n let cancelled = false\n\n async function run() {\n try {\n setData(null)\n const data = await store.packages.get()\n\n if (!cancelled) {\n // @ts-expect-error - find a way to fix this\n setData(data)\n }\n } catch (err) {\n if (err instanceof Error && !cancelled) {\n setError(err)\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n\n run()\n\n return () => {\n cancelled = true\n }\n }, [store])\n\n return {data, error, loading}\n}\n","import {Box} from '@sanity/ui'\nimport {memo} from 'react'\nimport {styled} from 'styled-components'\n\nexport const BoxSticky = memo(styled(Box)`\n position: sticky;\n top: 0;\n`)\n","import {\n APIClass,\n APIEnum,\n APIFunction,\n APIInterface,\n APIMember,\n APINamespace,\n APITypeAlias,\n APIVariable,\n} from '@sanity/tsdoc'\n\nimport {TSDocNavGroupedMembers} from './TSDocNav'\n\nexport function getGroupedMembers(members: APIMember[]): TSDocNavGroupedMembers {\n const components = members.filter(\n (mem) =>\n (mem._type === 'api.class' || mem._type === 'api.function' || mem._type === 'api.variable') &&\n mem.isReactComponentType,\n ) as (APIClass | APIFunction | APIVariable)[]\n const hooks = members.filter(\n (mem) => mem._type === 'api.function' && mem.isReactHook,\n ) as APIFunction[]\n const classes = members.filter(\n (mem) => !components.includes(mem as any) && mem._type === 'api.class',\n ) as APIClass[]\n const enums = members.filter((mem) => mem._type === 'api.enum') as APIEnum[]\n const functions = members.filter(\n (mem) =>\n !components.includes(mem as any) &&\n !hooks.includes(mem as any) &&\n mem._type === 'api.function',\n ) as APIFunction[]\n const interfaces = members.filter((mem) => mem._type === 'api.interface') as APIInterface[]\n const namespaces = members.filter((mem) => mem._type === 'api.namespace') as APINamespace[]\n const typeAliases = members.filter((mem) => mem._type === 'api.typeAlias') as APITypeAlias[]\n const variables = members.filter(\n (mem) => !components.includes(mem as any) && mem._type === 'api.variable',\n ) as APIVariable[]\n\n return {\n classes,\n enums,\n functions,\n interfaces,\n namespaces,\n reactComponents: components,\n reactHooks: hooks,\n typeAliases,\n variables,\n }\n}\n","import {css, styled} from 'styled-components'\n\nexport const UnformattedCode = styled.code<{$deprecated?: boolean}>(({$deprecated}) => {\n return css`\n && {\n background-color: transparent;\n color: inherit;\n text-decoration: ${$deprecated ? 'line-through' : undefined};\n }\n `\n})\n","import {APIMember} from '@sanity/tsdoc'\n\nimport {SyntaxText} from '../components/ColoredCode'\nimport {UnformattedCode} from '../components/UnformattedCode'\n\n/** @beta */\nexport function TSDocMemberTitle(props: {data: APIMember}): React.ReactNode {\n const {data} = props\n const isDeprecated = Boolean(data.comment?.deprecated)\n\n if ('isReactComponentType' in data && data.isReactComponentType) {\n return (\n <>\n <UnformattedCode>{`<`}</UnformattedCode>\n <SyntaxText $deprecated={isDeprecated} $syntax=\"className\">\n {data.name}\n </SyntaxText>\n <UnformattedCode $deprecated={isDeprecated}>{` />`}</UnformattedCode>\n </>\n )\n }\n\n if (data._type === 'api.class') {\n return (\n <>\n {/* <SyntaxText $syntax=\"keyword\">class </SyntaxText> */}\n <SyntaxText $deprecated={isDeprecated} $syntax=\"className\">\n {data.name}\n </SyntaxText>\n </>\n )\n }\n\n if (data._type === 'api.enum') {\n return (\n <>\n {/* <SyntaxText $syntax=\"keyword\">enum </SyntaxText> */}\n <SyntaxText $deprecated={isDeprecated} $syntax=\"className\">\n {data.name}\n </SyntaxText>\n </>\n )\n }\n\n if (data._type === 'api.function') {\n return (\n <>\n {/* <SyntaxText $syntax=\"keyword\">function </SyntaxText> */}\n <SyntaxText $deprecated={isDeprecated} $syntax=\"function\">\n {data.name}\n </SyntaxText>\n <UnformattedCode $deprecated={isDeprecated}>()</UnformattedCode>\n </>\n )\n }\n\n if (data._type === 'api.interface') {\n return (\n <>\n {/* <SyntaxText $syntax=\"keyword\">interface </SyntaxText> */}\n <SyntaxText $deprecated={isDeprecated} $syntax=\"className\">\n {data.name}\n </SyntaxText>\n </>\n )\n }\n\n if (data._type === 'api.namespace') {\n return (\n <>\n {/* <SyntaxText $syntax=\"keyword\">namespace </SyntaxText> */}\n <SyntaxText $deprecated={isDeprecated} $syntax=\"className\">\n {data.name}\n </SyntaxText>\n </>\n )\n }\n\n if (data._type === 'api.typeAlias') {\n return (\n <>\n {/* <SyntaxText $syntax=\"keyword\">type </SyntaxText> */}\n <SyntaxText $deprecated={isDeprecated} $syntax=\"className\">\n {data.name}\n </SyntaxText>\n </>\n )\n }\n\n if (data._type === 'api.variable') {\n return <UnformattedCode $deprecated={isDeprecated}>{data.name}</UnformattedCode>\n }\n\n return <>Uknown</>\n}\n","import {TSDocAppParams} from '@sanity/tsdoc/store'\n\n/** @beta */\nexport function compilePath(params: TSDocAppParams): string {\n const segments: string[] = []\n\n if (params.packageName) {\n if (params.packageScope) {\n segments.push(params.packageScope)\n }\n\n segments.push(params.packageName)\n\n if (params.releaseVersion) {\n if (params.exportPath) {\n if (params.exportPath !== '.') {\n segments.push(params.exportPath.slice(2))\n }\n\n if (params.memberSlug) {\n segments.push(params.memberSlug)\n }\n }\n }\n }\n\n return `/${segments.join('/')}`\n}\n","import {TSDocAppParams} from '@sanity/tsdoc/store'\nimport {MouseEvent, useCallback, useMemo} from 'react'\n\nimport {compilePath} from './lib/compilePath'\nimport {useTSDoc} from './useTSDoc'\n\n/** @beta */\nexport function useMemberLink(props: {params: TSDocAppParams | null}): {\n href: string\n onClick: (event: MouseEvent | KeyboardEvent) => void\n} {\n const {params} = props\n const {basePath, onPathChange} = useTSDoc()\n const path = params && compilePath(params)\n const href = useMemo(() => `${basePath}${path || ''}`, [basePath, path])\n\n const onClick = useCallback(\n (event: MouseEvent | KeyboardEvent) => {\n if (!path) return\n\n event.preventDefault()\n\n onPathChange(path)\n },\n [onPathChange, path],\n )\n\n return {href, onClick}\n}\n","import {blue} from '@sanity/color'\nimport {type Theme, TreeItem} from '@sanity/ui'\nimport {memo} from 'react'\nimport {styled} from 'styled-components'\n\nexport const SyntaxTreeItem = memo(\n styled(TreeItem)(({theme}: {theme: Theme}) => {\n const isThemeDark = theme.sanity.color.dark\n const activeBackground = blue[50].hex\n const focusBackground = theme.sanity.color.selectable!.default.enabled.bg2\n const color = theme.sanity.color.selectable!.default.hovered.fg\n\n const selectedLight = isThemeDark\n ? ''\n : `&[data-selected] > [role='treeitem'] {\n background-color: ${activeBackground} !important\n }`\n\n return `\n // solely on changing the \"()\" color\n &:focus code,\n & > a:focus code {\n color: ${color} !important;\n }\n\n ${selectedLight}\n\n // change focus for api items trees\n & > a:focus {\n background-color: ${focusBackground} !important;\n }\n `\n }),\n)\n","import type {APIMember, APINamespace} from '@sanity/tsdoc'\nimport type {TSDocAppParams} from '@sanity/tsdoc/store'\nimport {Box, type CardTone, Flex} from '@sanity/ui'\nimport {useMemo} from 'react'\n\nimport {SyntaxText} from '../../components/ColoredCode'\nimport {useSize} from '../../lib/ui'\nimport {TSDocMemberTitle} from '../TSDocMemberTitle'\nimport {useMemberLink} from '../useMemberLink'\nimport {useTSDoc} from '../useTSDoc'\nimport {SyntaxTreeItem} from './SyntaxTreeItem'\n\nexport function MemberLink(props: {data: APIMember; namespace?: APINamespace}): React.ReactNode {\n const {data, namespace} = props\n const {basePath, path} = useTSDoc()\n const fontSize = useSize()\n\n const params: TSDocAppParams = useMemo(\n () => ({\n exportPath: data.export?.path || namespace?.export.path || '.',\n memberName: data.name,\n packageName: data.package.name,\n packageScope: data.package.scope || null,\n releaseVersion: data.release.version,\n memberSlug: data.slug.current,\n }),\n [data, namespace],\n )\n\n const linkProps = useMemberLink({params})\n\n const tone: CardTone | undefined = useMemo(() => {\n if (data.releaseTag === 'beta') return 'caution'\n if (data.releaseTag === 'alpha') return 'critical'\n\n return undefined\n }, [data.releaseTag])\n\n const tag = useMemo(() => {\n if (data.releaseTag === 'beta') {\n return (\n <Box>\n <SyntaxText $syntax=\"string\">@beta</SyntaxText>\n </Box>\n )\n }\n\n if (data.releaseTag === 'alpha') {\n return (\n <Box>\n <SyntaxText $syntax=\"builtin\">@alpha</SyntaxText>\n </Box>\n )\n }\n\n return null\n }, [data.releaseTag])\n\n const isSelected = `${basePath}${path}` === linkProps.href\n\n return (\n <SyntaxTreeItem\n {...linkProps}\n fontSize={fontSize}\n padding={2}\n selected={isSelected}\n text={\n <Flex gap={1}>\n <Box flex={1}>\n <TSDocMemberTitle data={data} />\n </Box>\n {tag}\n </Flex>\n }\n // @ts-expect-error - fix this\n tone={tone}\n />\n )\n}\n","import {type Theme, TreeItem} from '@sanity/ui'\nimport {memo} from 'react'\nimport {styled} from 'styled-components'\n\nexport const TreeItemFocus = memo(\n styled(TreeItem)(({theme}: {theme: Theme}) => {\n const text = theme.sanity.color.selectable!.default.enabled.fg\n\n return `\n &:focus > [data-ui='TreeItem__box'],\n &:focus > [data-ui=\"TreeItem\"] {\n background-color: transparent !important;\n\n & svg, & code, & [data-ui=\"Text\"] {\n color: ${text} !important;\n }\n }\n `\n }),\n)\n","import {useSize} from '../../lib/ui'\nimport {useTSDoc} from '../useTSDoc'\nimport {MemberLink} from './MemberLink'\nimport {TreeItemFocus} from './TreeItemFocus'\nimport {TSDocNavExportData} from './TSDocNav'\n\nexport function GroupedMembersTree(props: {\n exp: TSDocNavExportData\n expandSubPackages?: boolean\n}): React.ReactNode {\n const {exp, expandSubPackages} = props\n const {params} = useTSDoc()\n const fontSize = useSize()\n\n return (\n <>\n {exp.reactComponents.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.reactComponents.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Components\"\n weight=\"semibold\"\n >\n {exp.reactComponents.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.reactHooks.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.reactHooks.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Hooks\"\n weight=\"semibold\"\n >\n {exp.reactHooks.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.classes.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.classes.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Classes\"\n weight=\"semibold\"\n >\n {exp.classes.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.functions.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.functions.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Functions\"\n weight=\"semibold\"\n >\n {exp.functions.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.variables.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.variables.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Variables\"\n weight=\"semibold\"\n >\n {exp.variables.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.enums.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.enums.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Enumerations\"\n weight=\"semibold\"\n >\n {exp.enums.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.interfaces.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.interfaces.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Interfaces\"\n weight=\"semibold\"\n >\n {exp.interfaces.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.namespaces.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.namespaces.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Namespaces\"\n weight=\"semibold\"\n >\n {exp.namespaces.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n\n {exp.typeAliases.length > 0 && (\n <TreeItemFocus\n expanded={\n expandSubPackages\n ? expandSubPackages\n : exp.typeAliases.some((m) => m.name === params.memberName)\n }\n fontSize={fontSize}\n padding={2}\n text=\"Type aliases\"\n weight=\"semibold\"\n >\n {exp.typeAliases.map((member) => (\n <MemberLink data={member} key={member.name} />\n ))}\n </TreeItemFocus>\n )}\n </>\n )\n}\n","import {MenuItem} from '@sanity/ui'\nimport {memo} from 'react'\nimport {styled} from 'styled-components'\n\nexport const SyntaxMenuItem = memo(styled(MenuItem)`\n &:focus code,\n & > a:focus code {\n color: inherit !important;\n }\n\n & > a:focus {\n background: transparent !important;\n }\n`)\n","import {SelectIcon} from '@sanity/icons'\nimport {APIPackage} from '@sanity/tsdoc'\nimport {Button, Menu, MenuButton} from '@sanity/ui'\n\nimport {SyntaxText} from '../../components/ColoredCode'\nimport {useSize} from '../../lib/ui'\nimport {useTSDoc} from '../useTSDoc'\nimport {SyntaxMenuItem} from './SyntaxMenuItem'\n\nexport function PackageMenuButton(props: {\n currentPkg: APIPackage\n packages: APIPackage[]\n}): React.ReactNode {\n const {currentPkg, packages} = props\n const {updateParams} = useTSDoc()\n const fontSize = useSize()\n\n return (\n <MenuButton\n button={\n <Button\n fontSize={fontSize}\n iconRight={SelectIcon}\n mode=\"bleed\"\n padding={2}\n text={\n <SyntaxText>{[currentPkg.scope, currentPkg.name].filter(Boolean).join('/')}</SyntaxText>\n }\n />\n }\n id=\"package-menu\"\n menu={\n <Menu>\n {packages.map((p) => (\n <SyntaxMenuItem\n fontSize={fontSize}\n key={p.name}\n onClick={() => {\n updateParams((prev) => ({\n ...prev,\n exportPath: null,\n packageScope: p.scope || null,\n packageName: p.name,\n releaseVersion: p.latestRelease.version,\n memberName: null,\n }))\n }}\n padding={2}\n text={<SyntaxText>{[p.scope, p.name].filter(Boolean).join('/')}</SyntaxText>}\n />\n ))}\n </Menu>\n }\n popover={{\n constrainSize: true,\n matchReferenceWidth: true,\n portal: true,\n }}\n />\n )\n}\n","import {APIPackage} from '@sanity/tsdoc'\nimport {TreeItemProps} from '@sanity/ui'\nimport {useCallback} from 'react'\n\nimport {SyntaxText} from '../../components/ColoredCode'\nimport {compilePath} from '../lib/compilePath'\nimport {useTSDoc} from '../useTSDoc'\nimport {SyntaxTreeItem} from './SyntaxTreeItem'\n\nexport function PackageTreeItem(\n props: {pkg: APIPackage} & Omit<TreeItemProps, 'href' | 'onClick' | 'text'>,\n): React.ReactNode {\n const {pkg, ...restProps} = props\n const {params, updateParams} = useTSDoc()\n\n const href = compilePath({\n ...params,\n packageScope: pkg.scope || null,\n packageName: pkg.name,\n releaseVersion: pkg.latestRelease.version,\n })\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n event.preventDefault()\n\n updateParams((prev) => ({\n ...prev,\n packageScope: pkg.scope || null,\n packageName: pkg.name,\n releaseVersion: pkg.latestRelease.version,\n }))\n },\n [pkg, updateParams],\n )\n\n return (\n <SyntaxTreeItem\n {...restProps}\n href={href}\n // @ts-expect-error - fix this\n onClick={handleClick}\n text={<SyntaxText>{[pkg.scope, pkg.name].filter(Boolean).join('/')}</SyntaxText>}\n />\n )\n}\n","import {SelectIcon} from '@sanity/icons'\nimport {APIPackage, APIRelease} from '@sanity/tsdoc'\nimport {Button, Menu, MenuButton} from '@sanity/ui'\n\nimport {SyntaxText} from '../../components/ColoredCode'\nimport {useSize} from '../../lib/ui'\nimport {useTSDoc} from '../useTSDoc'\nimport {SyntaxMenuItem} from './SyntaxMenuItem'\n\nexport function ReleaseMenuButton(props: {\n currentPkg: APIPackage\n currentRelease: APIRelease\n}): React.ReactNode {\n const {currentPkg, currentRelease} = props\n const {updateParams} = useTSDoc()\n const fontSize = useSize()\n\n return (\n <MenuButton\n button={\n <Button\n fontSize={fontSize}\n iconRight={SelectIcon}\n mode=\"bleed\"\n padding={2}\n text={<SyntaxText $syntax=\"className\">{currentRelease.version}</SyntaxText>}\n />\n }\n id=\"version-menu\"\n menu={\n <Menu>\n {currentPkg.releases.map((r) => (\n <SyntaxMenuItem\n fontSize={fontSize}\n key={r.version}\n onClick={() => updateParams((prev) => ({...prev, releaseVersion: r.version}))}\n padding={2}\n selected={currentRelease.version === r.version}\n text={<SyntaxText $syntax=\"className\">{r.version}</SyntaxText>}\n />\n ))}\n </Menu>\n }\n popover={{\n constrainSize: true,\n matchReferenceWidth: true,\n portal: true,\n }}\n />\n )\n}\n","import {Box} from '@sanity/ui'\nimport {memo} from 'react'\nimport {styled} from 'styled-components'\n\nexport const SearchWrapper = memo(styled(Box)`\n background-color: var(--card-bg-color);\n`)\n","import {Tree} from '@sanity/ui'\nimport {memo} from 'react'\nimport {styled} from 'styled-components'\n\nexport const TreeNav = memo(styled(Tree)`\n overflow: auto;\n height: 100vh;\n`)\n","import type {APISymbol} from '@sanity/tsdoc'\nimport {useEffect, useRef, useState} from 'react'\n\nimport {useTSDoc} from './useTSDoc'\n\nconst DEBOUNCE_MS = 150\n\n/** @beta */\nexport function useSymbolSearch(props: {query: string | null}): {\n data: (APISymbol & {_id: string; members: {exportPath: string; releaseVersion: string}[]})[]\n error: Error | null\n loading: boolean\n} {\n const {query} = props\n const {params, store} = useTSDoc()\n\n const [data, setData] = useState<\n (APISymbol & {_id: string; members: {exportPath: string; releaseVersion: string}[]})[]\n >([])\n const [error, setError] = useState<Error | null>(null)\n const [loading, setLoading] = useState(false)\n const [debouncedQuery, setDebouncedQuery] = useState(query)\n const timeoutRef = useRef<NodeJS.Timeout | null>(null)\n\n useEffect(() => {\n let cancelled = false\n\n async function run() {\n if (!debouncedQuery || !params.packageName) {\n setData([])\n\n return\n }\n\n try {\n setLoading(true)\n const data = await store.symbol.search({\n query: debouncedQuery,\n packageName: params.packageName,\n packageScope: params.packageScope,\n })\n\n if (!cancelled) {\n setLoading(false)\n // @ts-expect-error - find a way to fix this\n setData(data)\n }\n } catch (err) {\n if (err instanceof Error && !cancelled) {\n setError(err)\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n\n setLoading(false)\n }\n\n run()\n\n return () => {\n cancelled = true\n }\n }, [debouncedQuery, params.packageName, params.packageScope, store])\n\n useEffect(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current)\n }\n\n timeoutRef.current = setTimeout(() => {\n setDebouncedQuery(query)\n timeoutRef.current = null\n }, DEBOUNCE_MS)\n }, [query])\n\n return {data, error, loading}\n}\n","import {SearchIcon} from '@sanity/icons'\nimport {APISymbol, SanitySlugValue} from '@sanity/tsdoc'\nimport {TSDocAppParams} from '@sanity/tsdoc/store'\nimport {\n Autocomplete,\n BaseAutocompleteOption,\n Box,\n Card,\n Flex,\n Popover,\n Stack,\n Text,\n} from '@sanity/ui'\nimport {ForwardedRef, forwardRef, useCallback, useMemo, useRef, useState} from 'react'\n\nimport {UnformattedCode} from '../../components/UnformattedCode'\nimport {useMemberLink} from '../useMemberLink'\nimport {useSymbolSearch} from '../useSymbolSearch'\n\ninterface TSDocSearchOption extends BaseAutocompleteOption {\n symbol: APISymbol & {_id: string; members: {exportPath: string; releaseVersion: string}[]}\n}\n\n/** @beta */\nexport function TSDocSearch(): React.ReactNode {\n const [query, setQuery] = useState<string | null>(null)\n const {data, loading} = useSymbolSearch({query})\n const [value, setValue] = useState<string | undefined>()\n const autocompletePopoverReferenceElementRef = useRef<HTMLDivElement | null>(null)\n\n const options: TSDocSearchOption[] = useMemo(\n () => data.map((result) => ({value: result._id, symbol: result})),\n [data],\n )\n\n const filterOption = useCallback(() => true, [])\n\n const handleSelect = useCallback((value: string) => {\n setValue(value)\n setTimeout(() => setValue(''), 0)\n }, [])\n\n const renderOption = useCallback((option: TSDocSearchOption) => {\n // @ts-expect-error - find a way to fix this\n return <SearchOption symbol={option.symbol} />\n }, [])\n\n const renderValue = useCallback(() => '', [])\n\n const renderPopover = useCallback(\n ({content, hidden}: {content: React.ReactNode | null; hidden: boolean}) => {\n return query ? (\n <Popover\n arrow={false}\n open={!loading && !hidden}\n overflow=\"auto\"\n placement=\"bottom-start\"\n matchReferenceWidth\n radius={0}\n content={\n content ? (\n content\n ) : (\n <Box padding={4}>\n <Flex align=\"center\" height=\"fill\" justify=\"center\">\n <Text align=\"center\" muted>\n No results for <strong>“{query}”</strong>\n </Text>\n </Flex>\n </Box>\n )\n }\n referenceElement={autocompletePopoverReferenceElementRef.current}\n />\n ) : null\n },\n [loading, query],\n )\n\n return (\n <div ref={autocompletePopoverReferenceElementRef}>\n <Autocomplete\n filterOption={filterOption}\n icon={SearchIcon}\n id=\"tsdoc-search\"\n loading={loading}\n onQueryChange={setQuery}\n onSelect={handleSelect}\n options={options}\n padding={3}\n placeholder=\"Search for API members\"\n radius={2}\n renderOption={renderOption}\n renderValue={renderValue}\n renderPopover={renderPopover}\n value={value}\n />\n </div>\n )\n}\n\nconst SearchOption = forwardRef(function SearchOption(\n props: {\n symbol: APISymbol & {\n members: {slug: SanitySlugValue; exportPath: string; releaseVersion: string}[]\n }\n },\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const {symbol, ...restProps} = props\n\n const latestMember = symbol.members[0]\n\n const params: TSDocAppParams = useMemo(\n () => ({\n exportPath: latestMember ? latestMember.exportPath : '.',\n packageName: symbol.package.name,\n packageScope: symbol.package.scope || null,\n memberName: symbol.name,\n releaseVersion: latestMember ? latestMember.releaseVersion : '0.0.0',\n memberSlug: latestMember ? latestMember.slug.current : '',\n }),\n [latestMember, symbol],\n )\n\n const link = useMemberLink({params})\n\n return (\n <Card\n {...restProps}\n as=\"a\"\n href={link.href}\n onClick={link.onClick}\n padding={3}\n radius={2}\n ref={ref}\n >\n <Stack space={3}>\n <Text size={1} weight=\"medium\">\n <UnformattedCode>{symbol.name}</UnformattedCode>\n </Text>\n <Text muted size={1}>\n <UnformattedCode>\n {[\n [\n symbol.package.scope,\n symbol.package.name,\n latestMember?.exportPath === '.'\n ? undefined\n : latestMember?.exportPath.replace('./', '/'),\n ].filter(Boolean),\n ]}\n </UnformattedCode>\n </Text>\n </Stack>\n </Card>\n )\n})\n","import {\n APIClass,\n APIEnum,\n APIFunction,\n APIInterface,\n APINamespace,\n APITypeAlias,\n APIVariable,\n} from '@sanity/tsdoc'\nimport {TSDocExportData} from '@sanity/tsdoc/store'\nimport {Box, Card, Flex, Layer, Spinner, Stack, Text, Tree} from '@sanity/ui'\nimport {useMemo} from 'react'\n\nimport {SyntaxText} from '../../components/ColoredCode'\nimport {Size, useSize} from '../../lib/ui'\nimport {useExports} from '../useExports'\nimport {usePackages} from '../usePackages'\nimport {useTSDoc} from '../useTSDoc'\nimport {BoxSticky} from './FlexSticky'\nimport {getGroupedMembers} from './getGroupedMembers'\nimport {GroupedMembersTree} from './GroupedMembersTree'\nimport {PackageMenuButton} from './PackageMenuButton'\nimport {PackageTreeItem} from './PackageTreeItem'\nimport {ReleaseMenuButton} from './ReleaseMenuButton'\nimport {SearchWrapper} from './SearchWrapper'\nimport {TreeItemFocus} from './TreeItemFocus'\nimport {TreeNav} from './TreeNav'\nimport {TSDocSearch} from './TSDocSearch'\n\n/** @internal */\nexport interface TSDocNavGroupedMembers {\n classes: APIClass[]\n enums: APIEnum[]\n functions: APIFunction[]\n interfaces: APIInterface[]\n namespaces: APINamespace[]\n reactComponents: (APIClass | APIFunction | APIVariable)[]\n reactHooks: APIFunction[]\n typeAliases: APITypeAlias[]\n variables: APIVariable[]\n}\n\n/** @internal */\nexport interface TSDocNavExportData\n extends Omit<TSDocExportData, 'members'>,\n TSDocNavGroupedMembers {\n // intentionally empty\n}\n\n/** @beta */\nexport function TSDocNav(props: {\n showVersionMenu?: boolean\n expandPackages?: boolean\n expandSubPackages?: boolean\n}): React.ReactNode {\n return (\n <Size delta={-1}>\n <TSDocNavView {...props} />\n </Size>\n )\n}\n\ninterface ExportData {\n packageScope: string | null\n packageName: string\n name: string\n versions: TSDocNavExportData[]\n}\n\nfunction TSDocNavView(props: {\n showVersionMenu?: boolean\n expandPackages?: boolean\n expandSubPackages?: boolean\n}): React.ReactNode {\n const {params} = useTSDoc()\n const _exports = useExports()\n const packages = usePackages()\n const fontSize = useSize()\n const {showVersionMenu, expandPackages, expandSubPackages} = props\n\n const currentPkg = packages.data?.find(\n (p) => p.scope === params.packageScope && p.name === params.packageName,\n )\n\n const currentRelease = currentPkg?.releases.length\n ? currentPkg?.releases.find((r) =>\n params.releaseVersion\n ? r.version === params.releaseVersion\n : r.version == currentPkg.latestRelease.version,\n )\n : currentPkg?.latestRelease\n\n const currentVersion = currentRelease?.version\n\n const currentExportName =\n currentPkg &&\n params.exportPath &&\n [currentPkg.scope, currentPkg.name, params.exportPath].filter(Boolean).join('/')\n\n const exports: ExportData[] = useMemo(() => {\n if (!_exports.data) return []\n\n const items: {\n packageScope: string | null\n packageName: string\n name: string\n versions: TSDocNavExportData[]\n }[] = []\n\n for (const exp of _exports.data) {\n if (exp.members.length === 0) {\n continue // skip\n }\n\n const {members, name, package: pkg, ...restExp} = exp\n\n const item = items.find(\n (e) => e.packageScope === pkg.scope && e.packageName === pkg.name && e.name === exp.name,\n )\n\n const data: TSDocNavExportData = {\n name,\n package: pkg,\n ...restExp,\n ...getGroupedMembers(members),\n }\n\n if (item) {\n item.versions.push(data)\n } else {\n items.push({\n packageScope: pkg.scope,\n packageName: pkg.name,\n name,\n versions: [data],\n })\n }\n }\n\n return items || []\n }, [_exports.data])\n\n return (\n <BoxSticky paddingTop={3}>\n <Flex direction=\"column\" height=\"fill\" overflow=\"hidden\">\n {!currentPkg && !packages.loading && (\n <Card overflow=\"auto\" padding={3}>\n <Stack space={1}>\n <Box padding={2}>\n <Text size={fontSize} weight=\"bold\">\n Choose package\n </Text>\n </Box>\n\n <Tree>\n {packages.data?.map((pkg) => (\n <PackageTreeItem key={pkg.name} pkg={pkg} fontSize={fontSize} padding={2} />\n ))}\n </Tree>\n </Stack>\n </Card>\n )}\n\n {currentPkg && (\n <>\n {showVersionMenu && (\n <Layer style={{flex: 'none', position: 'sticky', top: 0}}>\n <Card padding={[2, 2, 3]} shadow={1}>\n <Flex gap={1}>\n {packages.data && (\n <Stack flex={1}>\n <PackageMenuButton currentPkg={currentPkg} packages={packages.data} />\n </Stack>\n )}\n\n {currentRelease && (\n <Stack flex=\"none\">\n <ReleaseMenuButton\n currentPkg={currentPkg}\n currentRelease={currentRelease}\n />\n </Stack>\n )}\n </Flex>\n </Card>\n </Layer>\n )}\n\n {_exports.loading && (\n <Flex align=\"center\" height=\"fill\" justify=\"center\">\n <Spinner muted />\n </Flex>\n )}\n\n {!_exports.loading && (\n <Stack flex={1} overflow=\"auto\">\n {currentPkg && (\n <SearchWrapper padding={1}>\n <TSDocSearch />\n </SearchWrapper>\n )}\n {exports.length === 1 ? (\n <SingleExportTree currentVersion={currentVersion} exp={exports[0]!} />\n ) : (\n <MultiExportTree\n currentExportName={currentExportName}\n currentVersion={currentVersion}\n exports={exports}\n fontSize={fontSize}\n expandPackages={expandPackages}\n expandSubPackages={expandSubPackages}\n />\n )}\n </Stack>\n )}\n </>\n )}\n </Flex>\n </BoxSticky>\n )\n}\n\nfunction SingleExportTree(props: {currentVersion?: string; exp: ExportData}) {\n const {currentVersion, exp} = props\n\n const versionedExports = useMemo(\n () => exp.versions.filter((d) => d.release.version === currentVersion),\n [currentVersion, exp],\n )\n\n return (\n <TreeNav>\n {versionedExports.map((exp) => (\n <GroupedMembersTree exp={exp} key={exp.release.version} />\n ))}\n </TreeNav>\n )\n}\n\nfunction MultiExportTree(props: {\n currentExportName?: string | null\n currentVersion?: string\n fontSize?: number[]\n exports: ExportData[]\n expandPackages?: boolean\n expandSubPackages?: boolean\n}) {\n const {currentExportName, currentVersion, fontSize, exports, expandPackages, expandSubPackages} =\n props\n\n const versionedExports = useMemo(\n () => exports.filter((data) => data.versions.some((v) => v.release.version === currentVersion)),\n [currentVersion, exports],\n )\n\n return (\n <TreeNav>\n {versionedExports.map((data) => (\n <TreeItemFocus\n expanded={expandPackages ? expandPackages : data.name === currentExportName}\n tabIndex={0}\n fontSize={fontSize}\n key={data.name}\n padding={2}\n text={<SyntaxText>{data.name}</SyntaxText>}\n weight=\"semibold\"\n >\n {data.versions\n .filter((d) => d.release.version === currentVersion)\n .map((exp) => (\n <GroupedMembersTree\n exp={exp}\n key={exp.release.version}\n expandSubPackages={expandSubPackages}\n />\n ))}\n </TreeItemFocus>\n ))}\n </TreeNav>\n )\n}\n","import {Box} from '@sanity/ui'\nimport {styled} from 'styled-components'\n\nexport const CommentBox = styled(Box)`\n /* border-top: 1px solid var(--card-border-color); */\n\n & >