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

Automated PR: staging to main #367

Merged
merged 14 commits into from
May 28, 2024
15 changes: 2 additions & 13 deletions src/app/[contentPageGroup]/[contentPage]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
'use client';

import { css } from '@emotion/css';
import startCase from 'lodash/startCase';
import { useEffect, useState } from 'react';

import { ContentstackRichText } from '@/components/content-stack';
import { getContentPage } from '@/utils/ContentStack/getContentstackResources';
import { ContentPage as ContentPageType } from '@/utils/ContentStack/types';

export default function ContentPage({
export default async function ContentPage({
params: { contentPage: contentPageName },
}: {
params: { contentPage: string };
}) {
const [contentPage, setContentPage] = useState<ContentPageType>();

useEffect(() => {
(async function () {
const contentPageObj = await getContentPage(startCase(contentPageName));
setContentPage(contentPageObj);
})();
}, [contentPageName]);
const contentPage = await getContentPage(startCase(contentPageName));

return (
<div
Expand Down
7 changes: 0 additions & 7 deletions src/app/[contentPageGroup]/loading.tsx

This file was deleted.

33 changes: 33 additions & 0 deletions src/app/component/[component]/code-docs/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use client';
import {
InstallCard,
PropTableState,
PropsTable,
VersionCard,
} from '@/components/code-docs';
import { codeDocsMetaCardsStyles, codeDocsPageStyles } from './codeDocs.styles';

interface CodeDocsContentProps {
componentName: string;
componentProps?: Array<PropTableState>;
changelog: string | null;
}

export const CodeDocsContent = ({
componentName,
componentProps,
changelog,
}: CodeDocsContentProps) => {
return (
<div className={codeDocsPageStyles}>
<div className={codeDocsMetaCardsStyles}>
<InstallCard component={componentName} />
<VersionCard component={componentName} changelog={changelog} />
</div>

{componentProps?.map(({ name, props }) => {
return <PropsTable key={name} name={name} props={props} />;
})}
</div>
);
};
19 changes: 19 additions & 0 deletions src/app/component/[component]/code-docs/codeDocs.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { css } from '@emotion/css';
import { breakpoints, spacing } from '@leafygreen-ui/tokens';

export const codeDocsPageStyles = css`
display: flex;
flex-direction: column;
gap: ${spacing[800]}px;
`;

export const codeDocsMetaCardsStyles = css`
display: grid;
gap: ${spacing[800]}px;
grid-template-columns: 2fr 1fr;
max-width: 100%;

@media (max-width: ${breakpoints.Tablet}px) {
grid-template-columns: 1fr;
}
`;
16 changes: 16 additions & 0 deletions src/app/component/[component]/code-docs/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client';
import { CardSkeleton } from '@leafygreen-ui/skeleton-loader';
import { codeDocsMetaCardsStyles, codeDocsPageStyles } from './codeDocs.styles';

export default function Loading() {
return (
<div className={codeDocsPageStyles}>
<div className={codeDocsMetaCardsStyles}>
<CardSkeleton />
<CardSkeleton />
</div>

<CardSkeleton />
</div>
);
}
118 changes: 17 additions & 101 deletions src/app/component/[component]/code-docs/page.tsx
Original file line number Diff line number Diff line change
@@ -1,107 +1,23 @@
'use client';
import { fetchTSDocs, fetchChangelog } from './server';
import { CodeDocsContent } from './client';
import { parseComponentPropsFromTSDocs } from './utils';

import { useEffect, useState } from 'react';
import { css } from '@emotion/css';
import { TableSkeleton } from '@leafygreen-ui/skeleton-loader';
import { spacing } from '@leafygreen-ui/tokens';
import { InstallCard, PropsTable, VersionCard } from '@/components/code-docs';
import { useMediaQuery } from '@/hooks/useMediaQuery';
import { components } from '@/utils';
import {
TSDocResponse,
PropTableState,
mergeProps,
} from '@/components/code-docs';
export default async function Page({
params,
}: {
params: { component: string };
}) {
const componentName = params.component;

import { getTSDocFromServer, getChangelogFromServer } from './server';

export default function Page({ params }: { params: { component: string } }) {
const [isTablet] = useMediaQuery(['(max-width: 768px)'], {
fallback: [true],
});
const [isLoading, setIsLoading] = useState(true);
const [componentProps, setComponentProps] = useState<Array<PropTableState>>(
[],
);

useEffect(() => {
if (!params.component) {
return;
}

const component = params.component;
const subComponents = components.find(
componentMeta =>
componentMeta.name.toLowerCase().replace(/\s/g, '') ===
component.split('-').join(''),
)?.subComponents;

getTSDocFromServer(component)
.then((response: Array<TSDocResponse>) => {
if (response != null) {
if (!!subComponents) {
const propTables = response.filter(response =>
subComponents.includes(response.displayName),
);

const reducedPropTables: Array<PropTableState> = propTables.reduce(
(acc: Array<PropTableState>, value: TSDocResponse) => {
const mergedProps = mergeProps(value.props);
return [
...acc,
{ name: value.displayName, props: mergedProps },
];
},
[],
);

setComponentProps(reducedPropTables);
} else {
const centralProps = response.find(response => {
return response.displayName
.toLowerCase()
.replace(/\s/g, '')
.includes(component.toLowerCase().split('-').join(''));
});
const mergedProps = mergeProps(centralProps?.props);
setComponentProps([{ name: component, props: mergedProps }]);
}
}
})
.finally(() => setIsLoading(false));
}, [params.component]);
const tsDocs = await fetchTSDocs(componentName);
const componentProps = parseComponentPropsFromTSDocs(tsDocs, componentName);
const changelog = await fetchChangelog(componentName);

return (
<div
className={css`
display: flex;
flex-direction: column;
gap: ${spacing[800]}px;
`}
>
<div
className={css`
display: grid;
gap: ${spacing[800]}px;
grid-template-columns: ${isTablet ? '1fr' : '2fr 1fr'};
max-width: 100%;
`}
>
<InstallCard component={params.component} />

<VersionCard
component={params.component}
getChangelog={getChangelogFromServer}
/>
</div>

{isLoading ? (
<TableSkeleton />
) : (
componentProps.map(({ name, props }) => {
return <PropsTable key={name} name={name} props={props} />;
})
)}
</div>
<CodeDocsContent
componentName={componentName}
componentProps={componentProps}
changelog={changelog}
/>
);
}
31 changes: 13 additions & 18 deletions src/app/component/[component]/code-docs/server.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
"use server";
'use server';

import { marked } from "marked";
import { TSDocResponse } from '@/components/code-docs';
import { marked } from 'marked';

export async function getTSDocs(componentName: string = "button") {
if (typeof componentName !== "string") return null;
export async function fetchTSDocs(
componentName: string,
): Promise<Array<TSDocResponse> | null> {
if (typeof componentName !== 'string') return null;

try {
return await import(`@leafygreen-ui/${componentName}/tsdoc.json`).then(
(response) => {
response => {
return response.default;
}
},
);
} catch (error) {
console.warn(error);
return null;
}
}

export async function getTSDocFromServer(component: string) {
return await getTSDocs(component);
}

export async function getChangelog(
componentName: string
export async function fetchChangelog(
componentName: string,
): Promise<string | null> {
try {
const response = await fetch(
`https://cdn.jsdelivr.net/npm/@leafygreen-ui/${componentName}/CHANGELOG.md`
`https://cdn.jsdelivr.net/npm/@leafygreen-ui/${componentName}/CHANGELOG.md`,
);
if (!response.ok) {
throw new Error("Failed to fetch Markdown file");
throw new Error('Failed to fetch Markdown file');
}
const markdown = await response.text();
const parsedMarkdown = marked(markdown);
Expand All @@ -40,7 +39,3 @@ export async function getChangelog(
return null;
}
}

export async function getChangelogFromServer(component: string) {
return await getChangelog(component);
}
45 changes: 45 additions & 0 deletions src/app/component/[component]/code-docs/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
PropTableState,
TSDocResponse,
mergeProps,
} from '@/components/code-docs';
import { findComponent } from '@/utils/components';
import { kebabCase } from 'lodash';

export function parseComponentPropsFromTSDocs(
tsDocs: Array<TSDocResponse> | null,
componentName: string,
): Array<PropTableState> | undefined {
if (!tsDocs) return;

const componentMeta = findComponent(componentName);
const subComponents = componentMeta?.subComponents;

if (!!subComponents) {
const propTables = tsDocs.filter(tsdoc =>
subComponents.includes(tsdoc.displayName),
);

const reducedPropTables: Array<PropTableState> = propTables.reduce(
(acc: Array<PropTableState>, value: TSDocResponse) => {
const mergedProps = mergeProps(value.props);
return [...acc, { name: value.displayName, props: mergedProps }];
},
[],
);

return reducedPropTables;
} else {
const centralProps = tsDocs.find(tsdoc => {
console.log({
displayName: tsdoc.displayName,
kebabCaseDisplay: kebabCase(tsdoc.displayName),
componentName,
kebabCaseName: kebabCase(componentName),
});
return kebabCase(tsdoc.displayName).includes(kebabCase(componentName));
});
const mergedProps = mergeProps(centralProps?.props);
return [{ name: componentName, props: mergedProps }];
}
}
13 changes: 13 additions & 0 deletions src/app/component/[component]/design-docs/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client';

import { ContentstackRichText } from '@/components/content-stack';
import { CSNode } from '@/components/content-stack/types';
import { ErrorBoundary } from 'next/dist/client/components/error-boundary';

interface DesignDocsContentProps {
content?: CSNode;
}

export const DesignDocsContent = ({ content }: DesignDocsContentProps) => {
return <ContentstackRichText content={content} />;
};
10 changes: 10 additions & 0 deletions src/app/component/[component]/design-docs/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use client';
import { ParagraphSkeleton } from '@leafygreen-ui/skeleton-loader';

export default function Loading() {
return (
<div>
<ParagraphSkeleton />
</div>
);
}
14 changes: 7 additions & 7 deletions src/app/component/[component]/design-docs/page.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
'use client';

import { css } from '@emotion/css';

import { ContentstackRichText } from '@/components/content-stack';
import useComponentFields from '@/hooks/useComponentFields';
import { fetchComponent } from '@/utils/ContentStack/getContentstackResources';
import { DesignDocsContent } from './client';

export default function Page({
export default async function Page({
params: { component: componentName },
}: {
params: { component: string };
}) {
const component = useComponentFields({ componentName, includeContent: true });
const component = await fetchComponent(componentName, {
includeContent: true,
});

return (
<div
className={css`
max-width: 700px; // TODO: Make this responsive
`}
>
<ContentstackRichText content={component?.designguidelines} />
<DesignDocsContent content={component?.designguidelines} />
</div>
);
}
Loading
Loading