Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/api docs #7990

Merged
merged 55 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
67310a1
initial template implementation
Aug 20, 2024
a71b22f
additional template functionality
Aug 22, 2024
a02f857
update modal
Aug 22, 2024
7e9db00
add api references json
Aug 29, 2024
b0237d6
add api categories
Aug 29, 2024
1967eda
update to template and display
Sep 5, 2024
607b121
revert changes to dev script
Sep 5, 2024
822306a
pass references to components
Sep 5, 2024
7f43348
remove build cache
Sep 5, 2024
c8ec4fb
remove pass through references
Sep 5, 2024
24f630b
clean references
Sep 5, 2024
8cabe59
add categories into clean references
Sep 5, 2024
0b96f5d
update references
Sep 5, 2024
8a1fb1b
update references with correct categories
Sep 5, 2024
fa57868
update references
Sep 6, 2024
b6c9c68
cleaned references
Sep 6, 2024
8106d66
update to clean references
Sep 6, 2024
bc8e502
update header and Toc
Sep 6, 2024
2231a12
update directories
Sep 6, 2024
5fd3b40
update generate directory
Sep 6, 2024
c1877af
add sub categories
Sep 6, 2024
5917c24
move references and rename to raw-references
Sep 6, 2024
a0eee84
update api docs template
Sep 9, 2024
0f1c394
undo unwanted changes
Sep 9, 2024
ea1739d
remove colons, some type updates, add keys (#7952)
hbuchel Sep 9, 2024
d571025
update TypeLink to output a button (#7953)
hbuchel Sep 9, 2024
4ec76ba
chore(api-docs-template): Update ApiModal styling/markup. Move breadc…
hbuchel Sep 10, 2024
75c2941
update to generateDirectory to add api reference pages (#7950)
jacoblogan Sep 11, 2024
df7efc1
add getApiStaticPath util function (#7949)
jacoblogan Sep 12, 2024
8cbc2f7
parse out markdown links in comments
Sep 16, 2024
01da321
update link to display literal type
Sep 16, 2024
aaf93da
Feature/api docs workflow (#7948)
jacoblogan Sep 17, 2024
98efe01
merge template changes
Sep 17, 2024
bccb11f
add dark mode to modal description text
Sep 17, 2024
1c8a870
update api function returns to use typeParameters
Sep 17, 2024
0c47b2f
remove space in promise display
Sep 17, 2024
b803bbc
close modal when click outside modal (#7969)
katiegoines Sep 17, 2024
1976e36
focus modal on open (#7970)
katiegoines Sep 17, 2024
eeef8e8
fix typo;
Sep 17, 2024
1494bc8
fix error in modal close
Sep 17, 2024
a439970
format "Returns" as code (#7971)
katiegoines Sep 17, 2024
44cd92c
add api link legend
Sep 17, 2024
6385358
update breadcrumbs separator, render nested typeArgs, render nested a…
Sep 19, 2024
62ac034
add function type display
Sep 19, 2024
6eb27d7
add error type
Sep 20, 2024
77150a6
update api legend and link colors
Sep 23, 2024
755e211
update cleaned references location
Sep 23, 2024
be3bfe4
update base references files
Sep 23, 2024
b0a2e9d
update scroll behavior
Sep 24, 2024
5115cf4
reverting uneeded changes to base.scss
Sep 24, 2024
dc13ada
update formatting
Sep 24, 2024
ac7bbea
add spacing to breadcrumbs
Sep 24, 2024
5cf25ff
remove extra space and add legend header
Sep 25, 2024
2a8c4ff
add formatting to api comments (#8000)
jacoblogan Sep 26, 2024
7dc4aac
update list parsing
Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
additional template functionality
  • Loading branch information
Jacob Logan committed Aug 22, 2024
commit a71b22f87b0b56439bda408d115ec2a3ef1c802e
9 changes: 7 additions & 2 deletions src/components/ApiDocs/ApiComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import { View } from '@aws-amplify/ui-react';
export const ApiComment = ({ apiComment }) => {
return (
<View>
{apiComment.map((snippet) => {
{apiComment.map((snippet, idx) => {
if (snippet.kind === "code") {
return <code>{snippet.text.replaceAll('`', '')}</code>
} else {
return snippet.text
const text = snippet.text;
if (idx === 0 && text.startsWith('-')) {
return text.slice(1);
} else {
return text;
}
}
})}
</View>
Expand Down
8 changes: 5 additions & 3 deletions src/components/ApiDocs/FunctionReference.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { View } from '@aws-amplify/ui-react';
import { FunctionSignature } from './FunctionSignature';

export const FunctionReference = ({ func }) => {
return (<View>
{func.signatures.map((sig) => <FunctionSignature sig={sig} />)}
</View>)

return (
<View>
{func.signatures.map((sig) => <FunctionSignature sig={sig} />)}
</View>)
}
22 changes: 21 additions & 1 deletion src/components/ApiDocs/FunctionReturn.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
import { View } from '@aws-amplify/ui-react';
import { MDXHeading } from '../MDXComponents';
import { Promise } from './display/Promise';
import { ApiComment } from './ApiComment';
import references from '../../directory/apiReferences.json';

export const FunctionReturn = ({ functionReturn }) => {
const name = functionReturn.name;
let display, description;
if (name === "Promise") {
const returnType = references[functionReturn.typeArguments[0].target];
display = <Promise typeObject={functionReturn} />
if (returnType?.comment?.summary) {
description = <ApiComment apiComment={returnType.comment.summary} />
}
} else {
const returnType = references[functionReturn.target];
display = name;
if (returnType?.comment?.summary) {
description = <ApiComment apiComment={returnType.comment.summary} />
}
}
return (
<View>
<MDXHeading level={3}>Returns:</MDXHeading>

{/* {references[fn].return.description} */}
{display}

{description}
</View>
)
}
4 changes: 2 additions & 2 deletions src/components/ApiDocs/Parameters.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { View } from '@aws-amplify/ui-react';
import { MDXHeading, MDXTable } from '../MDXComponents';
import { ApiComment } from './ApiComment';
import { ParameterType } from './display';
import references from '../../directory/apiReferences.json';

export const Parameters = ({ parameters }) => {
Expand All @@ -25,8 +26,7 @@ export const Parameters = ({ parameters }) => {
<code>{option.name}</code>
</td>
<td>{option?.flags?.isOptional ? 'false' : 'true'}</td>
{/* <td onClick={modalOpen}><Type typeData={option.value} /></td> */}
<td>Type</td>
<td><ParameterType typeData={option.type} /></td>
<td>{option?.comment?.summary && <ApiComment apiComment={option.comment.summary} />}</td>
</tr>
);
Expand Down
7 changes: 4 additions & 3 deletions src/components/ApiDocs/ReferencePage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import references from '../../directory/apiReferences.json';
import { FunctionReference } from './FunctionReference';
import { Divider, View } from '@aws-amplify/ui-react';

export const ReferencePage = ({ category }) => {

const cat = references['categories'].find((catObject) => catObject.name === category);
return <>
{cat.children.map((child) => <FunctionReference func={child} />)}
</>;
return <View className={'reference-page'}>
{cat.children.map((child, idx) => <>{idx !== 0 && <Divider marginTop={'medium'} />}<FunctionReference func={child} /></>)}
</View>;
}
122 changes: 122 additions & 0 deletions src/components/ApiDocs/display/ApiModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { View, Flex, Heading, Card, Divider, Button } from '@aws-amplify/ui-react'
import { IconX } from '../../Icons'
import { ParameterType } from './ParameterType';
import references from '../../../directory/apiReferences.json';
import { ApiComment } from '../ApiComment';

export const ApiModal = ({ data, showModal, close, breadCrumbs, clearBC }) => {
let name = data.name;
if (data.type === 'reference') {
data = references[data.target];
}
const description = data?.comment?.summary;

const closeModal = () => {
clearBC();
close();
}



let typeParameters = data.typeArguments;
if (data?.typeObject?.type == 'alias' && data.typeObject.typeParameters) {
typeParameters = data.typeObject.typeParameters;
} else if (data?.typeObject?.type == 'interface' && data.typeObject.typeParameters && data.typeObject.name == data.name) {
typeParameters = data.typeObject.typeParameters;
}
const params = typeParameters?.map((p) => {
return p.name;
});
if (params && params.length) {
name += `<${params.join(',')}>`
}
const typeData = data.typeObject || data.value;
// look for objects or interfaces to render additional data
const displayProperties = {};
function recursivelyParseType(typeData, displayProperties) {
if (!typeData) return;
if (typeData.type === 'alias') {
recursivelyParseType(typeData.value, displayProperties);
} else if (typeData.type === 'intersection') {
for (const key in typeData.types) {
recursivelyParseType(typeData.types[key], displayProperties);
}
} else if (typeData.type === 'union') {
for (const key in typeData.elements) {
recursivelyParseType(typeData.elements[key], displayProperties);
}
} else if (typeData.type === 'object' || typeData.type === 'interface') {
Object.keys(typeData.properties).forEach((key) => {
if (typeData.properties[key].description) { // only add displayProperties that have a description to be displayed
displayProperties[key] = typeData.properties[key];
}
});
}
}
recursivelyParseType(typeData, displayProperties);

let displayTypes;
if (Object.keys(displayProperties).length) {
displayTypes = Object.keys(displayProperties).map((key) => {
return <DisplayType key={key} data={displayProperties[key]} />
});
}





return (
<View display={showModal ? 'flex' : 'none'} className="api-modal-container">
<View
>
<Card
className="api-modal"
borderRadius="medium"
variation="outlined"
color="white"
textAlign="center"
>
<View padding="xs" fontSize="large">
<Flex>
{breadCrumbs.length && breadCrumbs.reduce((acc, bc, idx) => {
const next = bc.name;
if (idx > 0) {
acc.push(' > ');
}
acc.push(next);
return acc;
}, [])}
</Flex>
<Flex justifyContent="space-between">
<Heading padding="large" level={2} >{name}</Heading>
<Button onClick={closeModal} size="small" variation="link">
<IconX />
</Button>
</Flex>
<Divider padding="xs" />
<View fontSize="large">
<ParameterType typeData={data.type} />
</View>
{description && <>
<ApiComment apiComment={description} />
</>}
</View>
</Card>
</View>
</View >
)
}

const DisplayType = ({ data }) => {
return (
<Flex direction="column" key={data.name} marginTop="10px">
<Flex>
{data.name}: <code>{data.value.type}</code>
</Flex>
<Flex>
{data.description}
</Flex>
</Flex>
)
}
134 changes: 134 additions & 0 deletions src/components/ApiDocs/display/ParameterType.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { View, Flex } from '@aws-amplify/ui-react'
import { TypeLink } from './TypeLink';
import references from '../../../directory/apiReferences.json';

export const ParameterType = ({ typeData }) => {
if (!typeData) return;
const typeArgs = typeData.typeArguments;
const typeType = typeData.type;
switch (typeType) {
case 'reference':
return <>
<ReferenceType data={typeData} /> {typeArgs && <>&lt;{typeArgs.map((tArg) => {
return <TypeLink key={tArg.name} linkData={tArg} />
})}&gt;</>}
</>
case 'intersection':
const intersectionArgs = typeData.types;
return <>
{intersectionArgs.reduce((acc, item, index) => {
const comp = <ParameterType key={index} typeData={item} />;
if (index !== 0) {
acc.push(' & ');
}
acc.push(comp);
return acc;
}, [])}
</>
case 'reflection':
const reflectionChildren = typeData.children;
return <>
{'{'}
{/* {reflectionChildren.map((child) => {
return <>{child.name}: <ParameterType key={child.name} typeData={child} /></>
})} */}
{'}'}
</>
default:
return `${typeType} defaulted`;
}
}

const ReferenceType = ({ data }) => {
// should be a link that loads the next type when clicked on
const referencedObject = references[data.target];
if (!referencedObject) {
console.log("EMPTY")
console.log(data);
}

return <TypeLink linkData={referencedObject} />
}

const IntersectionType = ({ data }) => {
// should iterate over types putting & between and rendering each one
return (
<View>
{data.types.map((t, idx) => {
return (<View key={idx}><TypeLink linkData={t} /> {idx < data.types.length - 1 && <span>&</span>} </View>)
})}
</View>
)
}

const UnionType = ({ data }) => {
// should iterate over types putting | between and rendering each one
return (
<View>
{data.elements.map((t, idx) => {
return (<View key={idx}><TypeLink linkData={t} /> {idx < data.elements.length - 1 && <span>|</span>} </View>)
})}
</View>
)
}

const AliasType = ({ data }) => {
// should render the type object contained in value
return (<ParameterType typeData={data.value} />)
}

export const ApplicationType = ({ data }) => {
// example of application SomeType<AnotherType> it should render the "base" and "typeParameters"
const params = data.typeParameters.map((param, idx) => {
if (param.type === 'reference') {
return <><TypeLink linkData={param} />{idx < data.typeParameters.length - 1 ? ', ' : ''}</>
} else {
return <><code>{param.name || param.type}</code>{idx < data.typeParameters.length - 1 ? ', ' : ''}</>
}
});
return (
<View>
<TypeLink linkData={data.base} /> &lt; {params} &gt;
</View>
)
}

const InterfaceType = ({ data }) => {
// should render the "properties" as types
return (
<View>
{Object.keys(data.properties).map((key, idx) => {
return (
<Flex key={idx}>
{data.properties[key].name}: <ParameterType typeData={data.properties[key]} />
</Flex>
)
})}
</View>
)
}

const IdentifierType = ({ data }) => {
// should render the "typeObject" as a type if no typeObject exists then this is an end node
if (!data.typeObject) {
return <code>{data.name}</code>
} else {
return <ParameterType typeData={data.typeObject} />
}
}

const StringType = ({ }) => {
return (<code>string</code>)
}

const PropertyType = ({ data }) => {
if (data.value.name) {
return <TypeLink linkData={data.value} />
} else {
return (
<View>
<ParameterType typeData={data.value} />
</View>
)
}
}
12 changes: 12 additions & 0 deletions src/components/ApiDocs/display/Promise.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { View } from '@aws-amplify/ui-react';

export const Promise = ({ typeObject }) => {
const promiseTypes = typeObject.typeArguments.reduce((acc, val) => {
return `${acc}, ${val.name}`;
}, '').substring(2);
return (
<>
<View>Promise&lt;{promiseTypes}&gt;</View>
</>
);
}
22 changes: 22 additions & 0 deletions src/components/ApiDocs/display/TypeLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useContext } from 'react';
import { TypeContext } from "@/components/Layout/Layout";
import { ParameterType, ApplicationType } from './ParameterType';

export const TypeLink = ({ linkData }) => {
const { setModalData, modalOpen, addBreadCrumb } = useContext(TypeContext);
const name = linkData.name;

const onClickHandler = () => {
setModalData(linkData);
addBreadCrumb(linkData);
modalOpen();
}

if (linkData.type === 'application') {
return <ApplicationType data={linkData} />
} else if (linkData.type === 'interface' || linkData.type === 'object') {
return <ParameterType typeData={linkData} />
} else {
return <a className={'type-link'} onClick={onClickHandler}>{name}</a>
}
}
Loading