From 904bac094bf2d7999e553865d217234da13a5b02 Mon Sep 17 00:00:00 2001 From: Jacob <64662184+aarthificial@users.noreply.github.com> Date: Tue, 19 Dec 2023 21:56:58 +0100 Subject: [PATCH] docs: add experimental features (#874) --- packages/docs/src/Icon/Science/index.tsx | 20 ++++++++++ packages/docs/src/components/Api/ApiItem.tsx | 14 ++++++- .../docs/src/components/Api/Comment/index.tsx | 20 ++++++++++ .../docs/src/components/Release/Issue.tsx | 9 ++++- packages/docs/src/css/custom.css | 8 ++++ packages/docs/src/theme/Admonition/index.tsx | 21 ++++++++-- packages/docs/typedoc.js | 40 +++++++++++++++++++ tsdoc.json | 3 +- 8 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 packages/docs/src/Icon/Science/index.tsx diff --git a/packages/docs/src/Icon/Science/index.tsx b/packages/docs/src/Icon/Science/index.tsx new file mode 100644 index 00000000..82038674 --- /dev/null +++ b/packages/docs/src/Icon/Science/index.tsx @@ -0,0 +1,20 @@ +import React, {ComponentProps} from 'react'; + +export default function IconScience({ + width = 24, + height = 24, + ...props +}: ComponentProps<'svg'>): JSX.Element { + return ( + + + + ); +} diff --git a/packages/docs/src/components/Api/ApiItem.tsx b/packages/docs/src/components/Api/ApiItem.tsx index c9dd24b6..51d75d73 100644 --- a/packages/docs/src/components/Api/ApiItem.tsx +++ b/packages/docs/src/components/Api/ApiItem.tsx @@ -12,6 +12,16 @@ import React, {useMemo} from 'react'; import type {JSONOutput} from 'typedoc'; import {ReflectionKind} from './ReflectionKind'; +const ExperimentalIcon = ` + + +`; + interface ApiItemProps { route: { reflectionId: number; @@ -49,7 +59,9 @@ export default function ApiItem({route}: ApiItemProps): JSX.Element { continue; } toc.push({ - value: `${child.name}`, + value: `${child.experimental ? ExperimentalIcon : ''}${ + child.name + }`, id: child.anchor, level: 3, }); diff --git a/packages/docs/src/components/Api/Comment/index.tsx b/packages/docs/src/components/Api/Comment/index.tsx index 85e276f9..55a255e0 100644 --- a/packages/docs/src/components/Api/Comment/index.tsx +++ b/packages/docs/src/components/Api/Comment/index.tsx @@ -1,5 +1,6 @@ import {Collapsible} from '@docusaurus/theme-common'; import Summary from '@site/src/components/Api/Comment/Summary'; +import Admonition from '@theme/Admonition'; import clsx from 'clsx'; import React, {useMemo, useState} from 'react'; import type {JSONOutput} from 'typedoc'; @@ -18,6 +19,7 @@ export default function Comment({ return ( <> + {full && } {full && } @@ -25,6 +27,24 @@ export default function Comment({ ); } +function Experimental({comment}: {comment: JSONOutput.Comment}) { + const experimental = useMemo( + () => comment?.modifierTags?.includes('@experimental'), + [comment], + ); + + return ( + <> + {experimental && ( + + This is an experimental feature. The behavior and API may change + drastically between major releases. + + )} + + ); +} + function FullComment({comment}: {comment: JSONOutput.Comment}) { const [collapsed, setCollapsed] = useState(true); const preview = useMemo( diff --git a/packages/docs/src/components/Release/Issue.tsx b/packages/docs/src/components/Release/Issue.tsx index decf5efb..5d045d80 100644 --- a/packages/docs/src/components/Release/Issue.tsx +++ b/packages/docs/src/components/Release/Issue.tsx @@ -1,3 +1,4 @@ +import IconScience from '@site/src/Icon/Science'; import Contributor from '@site/src/components/Release/Contributor'; import PullRequest from '@site/src/components/Release/PullRequest'; import styles from '@site/src/components/Release/styles.module.css'; @@ -6,13 +7,19 @@ import React, {ReactNode} from 'react'; export interface IssueProps { user: string; pr?: number; + experimental?: boolean; children: ReactNode | ReactNode[]; } -export default function Issue({user, pr, children}: IssueProps) { +export default function Issue({user, pr, experimental, children}: IssueProps) { return (
  • + {experimental && ( + + + + )} {children} {pr && }
  • diff --git a/packages/docs/src/css/custom.css b/packages/docs/src/css/custom.css index c8367c6a..8d047bdb 100644 --- a/packages/docs/src/css/custom.css +++ b/packages/docs/src/css/custom.css @@ -190,6 +190,14 @@ a.button:hover { margin: 0 0.3rem; } +.experimental { + width: 1em; + height: 1em; + margin-right: 0.2em; + vertical-align: middle; + display: inline-block; +} + [data-theme='light']:root, [data-theme='dark']:root { --docsearch-primary-color: var(--ifm-color-primary); diff --git a/packages/docs/src/theme/Admonition/index.tsx b/packages/docs/src/theme/Admonition/index.tsx index 09ad97d5..77de5f21 100644 --- a/packages/docs/src/theme/Admonition/index.tsx +++ b/packages/docs/src/theme/Admonition/index.tsx @@ -1,3 +1,4 @@ +import IconScience from '@site/src/Icon/Science'; import IconDanger from '@site/src/theme/Icon/Danger'; import IconInfo from '@site/src/theme/Icon/Info'; import IconLightBulb from '@site/src/theme/Icon/LightBulb'; @@ -6,23 +7,35 @@ import Admonition from '@theme-original/Admonition'; import React, {useMemo} from 'react'; import styles from './styles.module.css'; -export default function AdmonitionWrapper(props) { +export default function AdmonitionWrapper({title, type, ...props}) { const Icon = useMemo(() => { - switch (props.type) { + switch (type) { case 'tip': return IconLightBulb; case 'caution': return IconWarning; case 'danger': return IconDanger; + case 'experimental': + return IconScience; default: return IconInfo; } - }, [props.type]); + }, [type]); + + if (type === 'experimental') { + title ??= 'Experimental'; + type = 'caution'; + } return ( <> - } {...props} /> + } + title={title} + type={type} + {...props} + /> ); } diff --git a/packages/docs/typedoc.js b/packages/docs/typedoc.js index 27bad781..1d0e3a7d 100644 --- a/packages/docs/typedoc.js +++ b/packages/docs/typedoc.js @@ -297,6 +297,31 @@ async function parseTypes(options, projectName, externalProject) { }, }); + app.serializer.addSerializer({ + priority: -Infinity, + supports(item) { + return item instanceof Reflection; + }, + toObject(item, obj) { + obj.experimental = isExperimental(item); + + if (!obj.experimental && item instanceof DeclarationReflection) { + const signatures = [ + ...(obj.signatures ?? []), + obj.setSignature, + obj.getSignature, + obj.indexSignature, + ].filter(item => !!item); + + obj.experimental = signatures.some(signature => + isExperimental(lookup[signature.id]), + ); + } + + return obj; + }, + }); + app.serializer.addSerializer({ priority: -Infinity, supports(item) { @@ -399,3 +424,18 @@ function partsToText(parts) { }) .join(''); } + +function isExperimental(reflection) { + const tags = reflection?.comment?.modifierTags; + if (!tags) return false; + + if (typeof tags === 'string') { + return tags === '@experimental'; + } + + if (Array.isArray(tags)) { + return tags.some(tag => tag === '@experimental'); + } + + return tags.has('@experimental'); +} diff --git a/tsdoc.json b/tsdoc.json index 99b4ab04..2200c325 100644 --- a/tsdoc.json +++ b/tsdoc.json @@ -35,6 +35,7 @@ "@ignore": true, "@inheritDoc": true, "@defaultValue": true, - "@see": true + "@see": true, + "@experimental": true } }