Skip to content

Commit 40220a6

Browse files
authored
Add components to build CLI commands page (aws-amplify#6121)
* Add components for rendering CLI commands * Add pages for CLI commands * Update cli command heading styling and refactor heading component * Remove console.log * Add 'key' prop to lists; Clean up heading components * Add prop to show/hide line numbers in MDXCode component * Update command page styles * Update subcommand font size * Make subheading font smaller
1 parent 5101c91 commit 40220a6

File tree

11 files changed

+290
-3
lines changed

11 files changed

+290
-3
lines changed
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { CliCommand, CliCommandFlag } from '@/data/cli-commands';
2+
import { Heading, Text, Flex, View } from '@aws-amplify/ui-react';
3+
import { MDXCode } from '../MDXComponents';
4+
import { CommandHeading, SubCommandHeading } from './CommandHeading';
5+
import { Fragment } from 'react';
6+
7+
export function Command({
8+
name,
9+
description,
10+
usage,
11+
flags,
12+
subCommands
13+
}: CliCommand) {
14+
return (
15+
<Flex className="commands-list__command">
16+
<CommandHeading>{name}</CommandHeading>
17+
<Text>{description}</Text>
18+
<MDXCode language="terminal" codeString={usage} showLineNumbers={false} />
19+
{flags && flags.length > 0 && (
20+
<Flex className="commands-list__command__flags">
21+
{flags.map((flag: CliCommandFlag) => (
22+
<Fragment key={`${name}-${flag.short}`}>
23+
<code className="commands-list__command__flags__code">
24+
{flag.short && <span>-{flag.short}|</span>}
25+
<span>--{flag.long}</span>
26+
</code>
27+
<Text>{flag.description}</Text>
28+
</Fragment>
29+
))}
30+
</Flex>
31+
)}
32+
{subCommands && subCommands.length > 0 && (
33+
<Flex className="commands-list__command__subcommands">
34+
{subCommands.map((subCommand) => (
35+
<Fragment key={`${name}-${subCommand.name}`}>
36+
<SubCommandHeading parentCommand={name}>
37+
{subCommand.name}
38+
</SubCommandHeading>
39+
<Text>{subCommand.description}</Text>
40+
<MDXCode
41+
language="terminal"
42+
codeString={`amplify ${name} ${subCommand.name}`}
43+
showLineNumbers={false}
44+
/>
45+
</Fragment>
46+
))}
47+
</Flex>
48+
)}
49+
</Flex>
50+
);
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Heading, Link } from '@aws-amplify/ui-react';
2+
import { ReactNode } from 'react';
3+
4+
type CommandHeadingProps = {
5+
children: string;
6+
};
7+
8+
type SubCommandHeadingProps = {
9+
children: ReactNode;
10+
parentCommand: string;
11+
};
12+
13+
export function CommandHeading({ children }: CommandHeadingProps) {
14+
return (
15+
<Heading id={children} level={2}>
16+
<Link className="commands-list__link" href={`#${children}`}>
17+
{children}
18+
</Link>
19+
</Heading>
20+
);
21+
}
22+
23+
export function SubCommandHeading({
24+
parentCommand,
25+
children
26+
}: SubCommandHeadingProps) {
27+
const value = encodeURI(`${parentCommand}-${children}`);
28+
29+
return (
30+
<Heading
31+
className="commands-list__command__subcommands__heading"
32+
id={value}
33+
level={3}
34+
>
35+
<Link className="commands-list__link" href={`#${value}`}>
36+
{children}
37+
</Link>
38+
</Heading>
39+
);
40+
}

src/components/CliCommands/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { CommandHeading, SubCommandHeading } from './CommandHeading';
2+
export { Command } from './Command';

src/components/Layout/Layout.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ export const Layout = ({
6161

6262
useEffect(() => {
6363
const headings: Heading[] = [];
64-
const pageHeadings = document.querySelectorAll('.main > h2, .main > h3');
64+
65+
const defaultHeadings = '.main > h2, .main > h3';
66+
const cliCommandHeadings =
67+
'.commands-list__command > h2, .commands-list__command > .commands-list__command__subcommands > h3';
68+
const headingSelectors = [defaultHeadings, cliCommandHeadings];
69+
70+
const pageHeadings = document.querySelectorAll(headingSelectors.join(', '));
6571

6672
pageHeadings.forEach((node) => {
6773
const { innerText, id, localName } = node as HTMLElement;

src/components/MDXComponents/MDXCode.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const addVersions = (code: string) => {
2525
};
2626

2727
export const MDXCode = (props) => {
28-
const { codeString, language, fileName } = props;
28+
const { codeString, language, fileName, showLineNumbers = true } = props;
2929
const [copied, setCopied] = React.useState(false);
3030
const [code, setCode] = React.useState(codeString);
3131
const copy = () => {
@@ -55,7 +55,9 @@ export const MDXCode = (props) => {
5555
<pre style={style} className="pre">
5656
{tokens.map((line, i) => (
5757
<div key={i} {...getLineProps({ line })}>
58-
<span className="line-number">{i + 1}</span>
58+
{showLineNumbers && (
59+
<span className="line-number">{i + 1}</span>
60+
)}
5961
{line.map((token, key) => (
6062
<span key={key} {...getTokenProps({ token })} />
6163
))}

src/directory/directory.mjs

+13
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ export const directory = {
5959
isExternal: true
6060
}
6161
]
62+
},
63+
{
64+
path: 'src/pages/[platform]/tools/index.mdx',
65+
children: [
66+
{
67+
path: 'src/pages/[platform]/tools/cli/index.mdx',
68+
children: [
69+
{
70+
path: 'src/pages/[platform]/tools/cli/commands.tsx'
71+
}
72+
]
73+
}
74+
]
6275
}
6376
]
6477
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { getCustomStaticPath } from '@/utils/getCustomStaticPath';
2+
import { Flex, Heading, View } from '@aws-amplify/ui-react';
3+
import { commands } from '@/data/cli-commands.mjs';
4+
import { Command } from '@/components/CliCommands';
5+
6+
export const meta = {
7+
title: 'Commands',
8+
description: 'Commands',
9+
platforms: [
10+
'android',
11+
'angular',
12+
'flutter',
13+
'javascript',
14+
'nextjs',
15+
'react',
16+
'react-native',
17+
'swift',
18+
'vue'
19+
]
20+
};
21+
22+
export const getStaticPaths = async () => {
23+
return getCustomStaticPath(meta.platforms);
24+
};
25+
26+
export function getStaticProps(context) {
27+
const sortedCommands = commands.sort((a, b) => (a.name > b.name ? 1 : -1));
28+
29+
return {
30+
props: {
31+
platform: context.params.platform,
32+
meta,
33+
sortedCommands
34+
}
35+
};
36+
}
37+
38+
function CommandsPage({ sortedCommands }) {
39+
return (
40+
<>
41+
<Heading level={1}>Commands</Heading>
42+
<Flex className="commands-list">
43+
{sortedCommands.map((command) => (
44+
<Command key={command.name} {...command} />
45+
))}
46+
</Flex>
47+
</>
48+
);
49+
}
50+
51+
export default CommandsPage;
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { getCustomStaticPath } from '@/utils/getCustomStaticPath';
2+
3+
export const meta = {
4+
title: 'CLI',
5+
description: 'CLI',
6+
platforms: [
7+
'android',
8+
'angular',
9+
'flutter',
10+
'javascript',
11+
'nextjs',
12+
'react',
13+
'react-native',
14+
'swift',
15+
'vue'
16+
]
17+
};
18+
19+
export const getStaticPaths = async () => {
20+
return getCustomStaticPath(meta.platforms);
21+
};
22+
23+
export function getStaticProps(context) {
24+
return {
25+
props: {
26+
platform: context.params.platform,
27+
meta
28+
}
29+
};
30+
}
31+
32+
# CLI
33+
34+
This page is just here for testing purposes.

src/pages/[platform]/tools/index.mdx

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { getCustomStaticPath } from '@/utils/getCustomStaticPath';
2+
import { getChildPageNodes } from '@/utils/getChildPageNodes';
3+
import directory from 'src/directory/directory.json';
4+
5+
export const meta = {
6+
title: 'Tools',
7+
description: 'Tools',
8+
platforms: [
9+
'android',
10+
'angular',
11+
'flutter',
12+
'javascript',
13+
'nextjs',
14+
'react',
15+
'react-native',
16+
'swift',
17+
'vue'
18+
],
19+
route: '/[platform]/tools'
20+
};
21+
22+
export const getStaticPaths = async () => {
23+
return getCustomStaticPath(meta.platforms);
24+
};
25+
26+
export function getStaticProps(context) {
27+
const childPageNodes = getChildPageNodes(meta.route);
28+
return {
29+
props: {
30+
platform: context.params.platform,
31+
meta,
32+
childPageNodes
33+
}
34+
};
35+
}
36+
37+
# Tools
38+
39+
<Overview childPageNodes={props.childPageNodes} />

src/styles/commands.scss

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
.commands-list {
2+
flex-direction: column;
3+
4+
&__link,
5+
&__link:visited {
6+
color: var(--amplify-colors-font-primary);
7+
text-decoration: none;
8+
}
9+
10+
&__link:hover {
11+
color: var(--amplify-colors-font-primary);
12+
text-decoration: underline;
13+
}
14+
15+
&__command {
16+
flex-direction: column;
17+
gap: var(--amplify-space-medium);
18+
margin-top: var(--amplify-space-large);
19+
border-top: var(--amplify-border-widths-large) solid
20+
var(--amplify-colors-border-secondary);
21+
22+
&:first-child {
23+
border-top: none;
24+
margin-top: 0;
25+
}
26+
27+
&__flags {
28+
flex-direction: column;
29+
gap: var(--amplify-space-small);
30+
margin-top: var(--amplify-space-medium);
31+
32+
&__code {
33+
width: fit-content;
34+
}
35+
}
36+
37+
&__subcommands {
38+
flex-direction: column;
39+
margin-top: var(--amplify-space-medium);
40+
margin-left: var(--amplify-space-large);
41+
gap: var(--amplify-space-medium);
42+
43+
&__heading {
44+
font-size: var(--amplify-font-sizes-large);
45+
}
46+
}
47+
}
48+
}

src/styles/styles.scss

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
@import './banner.scss';
1212
@import './callout.scss';
1313
@import './code.scss';
14+
@import './commands.scss';
1415
@import './feature-links.scss';
1516
@import './footer.scss';
1617
@import './framework-grid.scss';

0 commit comments

Comments
 (0)