Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions docs/generators/channels.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: channels
---

# Channels
Expand Down
2 changes: 2 additions & 0 deletions docs/generators/client.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: client
---

# Client
Expand Down
2 changes: 2 additions & 0 deletions docs/generators/custom.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: custom
---

# Custom generator
Expand Down
2 changes: 2 additions & 0 deletions docs/generators/headers.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: headers
---

# Headers
Expand Down
4 changes: 3 additions & 1 deletion docs/generators/models.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: models
---

# 🏗️ Models
# Models

```js
export default {
Expand Down
2 changes: 2 additions & 0 deletions docs/generators/parameters.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: parameters
---

# Parameters
Expand Down
4 changes: 3 additions & 1 deletion docs/generators/payloads.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: payloads
---

# 🐔 Payloads
# Payloads

```js
export default {
Expand Down
2 changes: 2 additions & 0 deletions docs/generators/types.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
sidebar_position: 99
sidebar_custom_props:
generatorPreset: types
---

# Types
Expand Down
44 changes: 41 additions & 3 deletions website/scripts/move_docs.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,48 @@
const path = require('path');
const { cp } = require('fs/promises');
const { cp, readFile, writeFile } = require('fs/promises');
const DOCS_ROOT_PATH = path.join(__dirname, '../../docs');
const DOCS_DOCU_PATH = path.join(__dirname, '../docs');

const ASSETS_ROOT_PATH = path.join(__dirname, '../../assets');
const ASSETS_DOCU_PATH = path.join(__dirname, '../static/assets');

cp(DOCS_ROOT_PATH, DOCS_DOCU_PATH, {recursive: true});
cp(ASSETS_ROOT_PATH, ASSETS_DOCU_PATH, {recursive: true});
/**
* The plain list of presets in `docs/generators/README.md`.
*
* The docs also have to render on GitHub, so the repo copy stays plain markdown
* with no imports or JSX. On the website we swap that list for the same preset
* card grid the landing page uses - `<GeneratorCards />` is registered globally
* in `src/theme/MDXComponents.tsx`, so the injected tag needs no import.
*/
const GENERATOR_LIST_PATTERN =
/^All available generators, across languages and inputs:\r?\n(?:- \[`[a-z]+`\]\([^)]+\)\r?\n)+/m;

async function replaceGeneratorList() {
const readmePath = path.join(DOCS_DOCU_PATH, 'generators/README.md');
const content = await readFile(readmePath, 'utf-8');

if (!GENERATOR_LIST_PATTERN.test(content)) {
throw new Error(
`Could not find the generator list in ${readmePath} to replace with <GeneratorCards />. ` +
'If the wording of that list changed, update GENERATOR_LIST_PATTERN in website/scripts/move_docs.js.'
);
}

await writeFile(
readmePath,
content.replace(GENERATOR_LIST_PATTERN, '<GeneratorCards />\n')
);
}

async function main() {
await Promise.all([
cp(DOCS_ROOT_PATH, DOCS_DOCU_PATH, { recursive: true }),
cp(ASSETS_ROOT_PATH, ASSETS_DOCU_PATH, { recursive: true }),
]);
await replaceGeneratorList();
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
31 changes: 31 additions & 0 deletions website/src/components/GeneratorCards/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Link from '@docusaurus/Link';
import {
GENERATOR_PRESETS,
GeneratorIcon
} from '@site/src/data/generatorPresets';
import styles from './styles.module.css';

/**
* The preset grid from the landing page, sized for a docs column.
*
* Rendered into `docs/generators/README.md` by `scripts/move_docs.js`, which
* swaps the plain markdown list for this component when it copies the docs in -
* the list stays in the repo so the file still reads on GitHub.
*/
export default function GeneratorCards(): JSX.Element {
return (
<div className={styles.grid}>
{GENERATOR_PRESETS.map((generator) => (
<Link key={generator.preset} to={generator.href} className={styles.card}>
<span className={styles.iconWrap} aria-hidden="true">
<GeneratorIcon preset={generator.preset} />
</span>
<span className={styles.cardTitle}>
<code>{generator.preset}</code>
</span>
<span className={styles.cardBlurb}>{generator.blurb}</span>
</Link>
))}
</div>
);
}
99 changes: 99 additions & 0 deletions website/src/components/GeneratorCards/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* Same card language as the landing page grid, narrowed for the docs column. */
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.85rem;
margin: 1.5rem 0 2rem;
}

.card {
position: relative;
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1.1rem;
border-radius: 14px;
border: 1px solid var(--ifm-color-emphasis-200);
background: var(--ifm-card-background-color);
color: var(--ifm-font-color-base);
overflow: hidden;
transition:
transform 180ms ease,
border-color 180ms ease,
box-shadow 180ms ease;
}

/* Accent wash that grows on hover - keeps the grid calm until you engage. */
.card::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(
120% 90% at 0% 0%,
var(--cg-accent-12),
transparent 60%
);
opacity: 0;
transition: opacity 180ms ease;
}

.card:hover {
text-decoration: none;
color: var(--ifm-font-color-base);
transform: translateY(-3px);
border-color: var(--cg-accent-45);
box-shadow: 0 16px 34px -22px var(--cg-accent-60);
}

.card:hover::before {
opacity: 1;
}

.iconWrap {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.1rem;
height: 2.1rem;
border-radius: 10px;
border: 1px solid var(--cg-accent-30);
background: var(--cg-accent-10);
color: var(--cg-accent-strong);
}

.iconWrap svg {
width: 1.1rem;
height: 1.1rem;
}

.cardTitle {
position: relative;
font-weight: 600;
}

.cardTitle code {
padding: 0.1rem 0.4rem;
border: 0;
background: var(--ifm-color-emphasis-100);
font-size: 0.9rem;
}

.cardBlurb {
position: relative;
font-size: 0.85rem;
line-height: 1.55;
color: var(--ifm-color-emphasis-700);
}

@media screen and (max-width: 576px) {
.grid {
grid-template-columns: minmax(0, 1fr);
}
}

@media (prefers-reduced-motion: reduce) {
.card:hover {
transform: none;
}
}
101 changes: 101 additions & 0 deletions website/src/components/Home/CodePane/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import clsx from 'clsx';
import {Highlight, themes} from 'prism-react-renderer';
import type {Language} from '../demos';
import styles from './styles.module.css';

/**
* A read-only, editor-looking code surface with a "streaming in" reveal.
*
* The reveal is done with a per-line CSS animation delay rather than by
* re-rendering a growing substring: highlighting runs once, the browser handles
* the 60fps part on the compositor, and there is nothing to throttle. Replaying
* it means remounting the element, which restarts the CSS animations from zero.
*
* The remount key is derived from `code` itself, so a pane only re-animates when
* what it shows actually changed. Callers do not have to work out which of their
* controls affect which pane - and a pane sitting next to one the reader just
* switched stays still instead of flickering for no reason.
*/
export default function CodePane({
code,
language,
replayToken,
animate = true,
showLineNumbers = true,
panelLabel,
className
}: {
code: string;
language: Language;
/**
* Changes to this force a replay even when `code` is unchanged - for an
* explicit "run it again" control. Leave unset to animate on content change
* only.
*/
replayToken?: string | number;
animate?: boolean;
/** Off for shell snippets, where numbered "lines" are meaningless. */
showLineNumbers?: boolean;
/**
* Set when the pane is the content a tablist switches between: it makes the
* pane the tabpanel those tabs are missing, named after the current file.
*/
panelLabel?: string;
className?: string;
}): JSX.Element {
return (
<div
className={clsx(styles.pane, className)}
role={panelLabel ? 'tabpanel' : undefined}
aria-label={panelLabel}
>
{/* `oneDark` over the more obvious `vsDark`: vsDark has no style for the
`atrule` token type, which is what Prism's YAML grammar tags every key
as - so a whole YAML document would render as flat, unhighlighted
text. Keep `--cg-code-plain` in sync with this theme's plain colour. */}
<Highlight theme={themes.oneDark} code={code} language={language}>
{({tokens, getLineProps, getTokenProps}) => (
<pre
key={`${replayToken ?? ''}:${code}`}
className={clsx(
styles.pre,
animate && styles.animated,
!showLineNumbers && styles.noGutter
)}
tabIndex={0}
>
<code>
{tokens.map((line, i) => {
const {style: _ignoredLineStyle, ...lineProps} = getLineProps({
line
});
return (
<span
key={i}
{...lineProps}
className={clsx(styles.line, lineProps.className)}
// Staggered so the file appears to stream in. Capped so a
// long file still finishes in well under a second.
style={{animationDelay: `${Math.min(i * 14, 620)}ms`}}
>
{showLineNumbers && (
<span className={styles.lineNo} aria-hidden="true">
{i + 1}
</span>
)}
<span className={styles.lineContent}>
{line.map((token, key) => {
const {style, ...rest} = getTokenProps({token});
return <span key={key} {...rest} style={style} />;
})}
</span>
</span>
);
})}
</code>
</pre>
)}
</Highlight>
</div>
);
}
Loading
Loading