docs(core): restructure & update intro page

Co-authored-by: Isaac Mann <isaacplmann@gmail.com>
This commit is contained in:
Juri 2023-08-02 15:08:10 +02:00 committed by Juri Strumpflohner
parent 90ca436d81
commit dd377d4597
21 changed files with 1123 additions and 144 deletions

View File

@ -201,7 +201,7 @@ Yarn related information.
##### Youtube ##### Youtube
Embed a YouTube video directly with the following shortcode, control the title and the associated width. Embed a YouTube video directly with the following shortcode, control the title and the associated width. `src` can be the Youtube URL from the browser, the "share" button (short YT url) or the embed URL.
```markdown ```markdown
{% youtube {% youtube

View File

@ -4,16 +4,21 @@
Here are some of our feature highlights: Here are some of our feature highlights:
{% cards cols="2" %} {% youtube
{% card title="Combine the Power of Nx Graph and Nx Console" type="video" url="https://youtu.be/ZST_rmhzRXI" /%} src="https://youtu.be/ZST_rmhzRXI"
{% /cards %} title="Nx Console Run UI Form"
width="100%" /%}
## Breaking Changes ## Breaking Changes
Use [the `nx migrate` command](/core-features/automate-updating-dependencies) to automatically account for these breaking changes. Use [the `nx migrate` command](/core-features/automate-updating-dependencies) to automatically account for these breaking changes.
{% cards cols="2" %} {% cards cols="1" smCols="2" mdCols="3" %}
{% card title="Removed UMD format support for rollup" type="external" url="https://github.com/nrwl/nx/pull/12426" /%} {% card title="Removed UMD format support for rollup" type="external" url="https://github.com/nrwl/nx/pull/12426" /%}
{% card title="Removed --only-failed option" type="external" url="https://github.com/nrwl/nx/pull/12471" /%} {% card title="Removed --only-failed option" type="external" url="https://github.com/nrwl/nx/pull/12471" /%}
{% card title="Infer projects from package.json and project.json" description="Nx will now also include folders with package.json/project.json in its graph of projects. You can ignore any unwanted projects by adding the directory to .nxignore." type="external" url="https://github.com/nrwl/nx/releases/tag/15.0.0" /%} {% card title="Infer projects from package.json and project.json" description="Nx will now also include folders with package.json/project.json in its graph of projects. You can ignore any unwanted projects by adding the directory to .nxignore." type="external" url="https://github.com/nrwl/nx/releases/tag/15.0.0" /%}
{% /cards %} {% /cards %}

View File

@ -8,7 +8,7 @@ title="What&#39;s new in Nx 15.3?"
/%} /%}
Here are some of our feature highlights: Here are some of our feature highlights:
{% cards cols="2" %} {% cards cols="1" smCols="2" mdCols="2" lgCols="3" %}
{% card title="Introducing the Nx Task Graph Visualization" type="video" url="https://youtu.be/wOE3r4299fs" /%} {% card title="Introducing the Nx Task Graph Visualization" type="video" url="https://youtu.be/wOE3r4299fs" /%}
{% card title="Standalone Applications with Nx" type="video" url="https://youtu.be/qEaVzh-oBBc" /%} {% card title="Standalone Applications with Nx" type="video" url="https://youtu.be/qEaVzh-oBBc" /%}
{% card title="Add Nx to any Project" type="video" url="https://youtu.be/VmGCZ77ao_I" /%} {% card title="Add Nx to any Project" type="video" url="https://youtu.be/VmGCZ77ao_I" /%}

View File

@ -9,6 +9,6 @@ title="Nx 15.4 is out! Here&#39;s all you need to know"
Here are some of our feature highlights: Here are some of our feature highlights:
{% cards cols="2" %} {% cards cols="2" smCol="2" mdCol="2" lgCol="2" %}
{% card title="One Command to Run Multiple Tasks in Parallel" type="video" url="https://youtu.be/ROTO89i5m_4" /%} {% card title="One Command to Run Multiple Tasks in Parallel" type="video" url="https://youtu.be/ROTO89i5m_4" /%}
{% /cards %} {% /cards %}

View File

@ -33,7 +33,7 @@
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "5 min Tutorials", "name": "Tutorials",
"path": "/getting-started/tutorials", "path": "/getting-started/tutorials",
"id": "tutorials", "id": "tutorials",
"isExternal": false, "isExternal": false,
@ -109,7 +109,7 @@
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "5 min Tutorials", "name": "Tutorials",
"path": "/getting-started/tutorials", "path": "/getting-started/tutorials",
"id": "tutorials", "id": "tutorials",
"isExternal": false, "isExternal": false,

View File

@ -37,7 +37,7 @@
}, },
{ {
"id": "tutorials", "id": "tutorials",
"name": "5 min Tutorials", "name": "Tutorials",
"description": "Get started with basic information, concepts and tutorials.", "description": "Get started with basic information, concepts and tutorials.",
"file": "", "file": "",
"itemList": [ "itemList": [
@ -133,7 +133,7 @@
}, },
"/getting-started/tutorials": { "/getting-started/tutorials": {
"id": "tutorials", "id": "tutorials",
"name": "5 min Tutorials", "name": "Tutorials",
"description": "Get started with basic information, concepts and tutorials.", "description": "Get started with basic information, concepts and tutorials.",
"file": "", "file": "",
"itemList": [ "itemList": [

View File

@ -29,7 +29,7 @@
"file": "shared/getting-started/why-nx" "file": "shared/getting-started/why-nx"
}, },
{ {
"name": "5 min Tutorials", "name": "Tutorials",
"id": "tutorials", "id": "tutorials",
"description": "Get started with basic information, concepts and tutorials.", "description": "Get started with basic information, concepts and tutorials.",
"itemList": [ "itemList": [

View File

@ -1,5 +1,10 @@
# What is Nx Cloud? # What is Nx Cloud?
{% youtube
src="https://www.youtube.com/embed/NZF0ZJpgaJM?si=1KJRAWJJmfw9c0c0"
title="What is Nx Cloud?"
width="100%" /%}
Nx partitions a command into smaller tasks and runs them in parallel, in the correct order. Nx Cloud takes it one step further and [runs any command across multiple machines](/core-features/distribute-task-execution), while giving you a consolidated view of the command as if it ran locally. Nx partitions a command into smaller tasks and runs them in parallel, in the correct order. Nx Cloud takes it one step further and [runs any command across multiple machines](/core-features/distribute-task-execution), while giving you a consolidated view of the command as if it ran locally.
Nx caches the output of any previously run command such as testing and building, so it can replay the cached results instead of rerunning it. Nx Cloud allows you to [share the computation cache](/core-features/remote-cache) across everyone in your team and CI. Nx caches the output of any previously run command such as testing and building, so it can replay the cached results instead of rerunning it. Nx Cloud allows you to [share the computation cache](/core-features/remote-cache) across everyone in your team and CI.

View File

@ -1,100 +1,91 @@
# Intro to Nx # Intro to Nx
Nx is a powerful open-source build system that provides tools and techniques for enhancing developer productivity, optimizing CI performance, and maintaining code quality. Find out more about [why you should use Nx](/getting-started/why-nx). Nx is a powerful open-source build system that provides tools and techniques for enhancing developer productivity, optimizing CI performance, and maintaining code quality. [Check out our video](/getting-started/why-nx) to learn more about what Nx is about.
If instead you want to jump right into it, run the following command. It will guide you through the setup: ## Core Features
{% tabs %} - **Run Tasks Efficiently**: Nx [runs tasks in parallel](/core-features/run-tasks) and orders the tasks based on the dependencies between them.
{% tab label="npm" %} - **Cache Locally & Remotely**: With [local](/core-features/cache-task-results) and [remote caching](/core-features/remote-cache), Nx prevents unnecessary re-runs of tasks, saving you valuable dev time.
- **Automate Dependency Updates**: if you leverage Nx plugins you gain additional features such as [code generation](/core-features/plugin-features/use-code-generators) and tools to [automatically upgrade](core-features/automate-updating-dependencies) your codebase and dependencies.
- **Make it Your Own**: Nx is highly customizable and extensible. Fine-tune it by [creating your own plugins](/extending-nx/intro/getting-started) and optionally [share them with the community](/extending-nx/tutorials/publish-plugin#publish-your-nx-plugin).
<!-- - **Monorepo and Single Projects**: Nx supports both, monorepos as well as single-project (standalone) workspaces. -->
Find out more about [why you should use Nx](/getting-started/why-nx) or browse our [core features](/core-features).
## Try Nx Yourself!
```shell ```shell
npx create-nx-workspace npx create-nx-workspace@latest
``` ```
{% /tab %} ## Learn Nx
{% tab label="yarn" %}
```shell {% cards cols="2" lgCols="6" mdCols="4" smCols="2" %}
npx create-nx-workspace --pm yarn
```
{% /tab %} {% link-card title="Nx in 10 minutes!" type="video" url="https://youtu.be/-_4WMl-Fn0w" icon="nx" /%}
{% tab label="pnpm" %}
```shell {% link-card title="What is Nx Cloud?" type="video" url="https://youtu.be/NZF0ZJpgaJM" icon="nxcloud" /%}
npx create-nx-workspace --pm pnpm
```
{% /tab %} {% link-card title="PNPM Monorepos with Nx" type="video" url="https://youtu.be/ngdoUQBvAjo" icon="pnpm" /%}
{% /tabs %}
You can use Nx to quickly scaffold a new project or even an entire monorepo. It can be incrementally adopted and will grow with your project as it scales. {% link-card title="More On Youtube" type="video" url="https://www.youtube.com/@nxdevtools" icon="youtube" /%}
{% cards cols="3" %}
{% title-card title="New Monorepo" url="#get-started-with-the-basics" /%}
{% title-card title="Choose a Stack" url="#learn-about-nx-and-your-favorite-stack" /%}
{% title-card title="Add to an Existing Project" url="#adding-nx-to-an-existing-project" /%}
{% /cards %} {% /cards %}
## Get Started with the Basics {% cards cols="2" lgCols="6" mdCols="5" smCols="2" %}
Its modular architecture lets you adopt Nx for package-based monorepos in combination with NPM, Yarn or PNPM, or create a fully integrated monorepo using Nx plugins. Learn more with the tutorials below. {% link-card title="Package Based Monorepos" type="tutorial" url="/getting-started/tutorials/package-based-repo-tutorial" icon="jsMono" /%}
{% personas %} {% link-card title="Integrated Monorepos" type="tutorial" url="/getting-started/tutorials/integrated-repo-tutorial" icon="nx" /%}
{% persona type="javascript" title="New Package-Based Repo" url="/getting-started/tutorials/package-based-repo-tutorial" %}
Create a monorepo with Yarn, NPM or PNPM. Nx makes it fast, but lets you run things your way.
- [Get started with your package-based repo](/getting-started/tutorials/package-based-repo-tutorial) {% link-card title="Single React App" type="tutorial" url="/getting-started/tutorials/react-standalone-tutorial" icon="react" /%}
{% /persona %} {% link-card title="Single Angular App" type="tutorial" url="/getting-started/tutorials/angular-standalone-tutorial" icon="angular" /%}
{% persona type="integrated" title="New Integrated Repo" url="/getting-started/tutorials/integrated-repo-tutorial" %} {% link-card title="Single Node App" type="tutorial" url="/getting-started/tutorials/node-server-tutorial" icon="node" /%}
Get a pre-configured setup. Nx configures your favorite frameworks and lets you focus on shipping features. <!-- {% link-card title="React Monorepo" type="tutorial" url="/getting-started/tutorials/react-standalone-tutorial" icon="reactMono" /%}
- [Get started with your integrated repo](/getting-started/tutorials/integrated-repo-tutorial) {% link-card title="Angular Monorepo" type="tutorial" url="/getting-started/tutorials/angular-standalone-tutorial" icon="angularMono" /%}
{% /persona %} {% link-card title="Node Monorepo" type="tutorial" url="/getting-started/tutorials/node-server-tutorial" icon="nodeMono" /%} -->
{% /personas %}
{% /cards %} {% /cards %}
## Learn About Nx and Your Favorite Stack ## Pick Your Stack!
Nx works well not just for monorepos. Nx plugins help you scaffold new projects with pre-configured tooling and modularize your codebase with local libraries. {% cards cols="3" lgCols="8" mdCols="6" smCols="5" moreLink="/showcase/example-repos" %}
{% cards cols="3" %} {% link-card title="Express" appearance="small" url="/packages/express" icon="express" /%}
{% link-card title="Vue" appearance="small" url="/showcase/example-repos/add-vue" icon="vue" /%}
{% link-card title="Next" appearance="small" url="/packages/next" icon="nextjs" /%}
{% link-card title="Nuxt" appearance="small" url="/showcase/example-repos/add-nuxt" icon="nuxt" /%}
{% link-card title="Nest" appearance="small" url="/packages/nest" icon="nestjs" /%}
{% link-card title="Remix" appearance="small" url="/recipes/react/remix" icon="remix" /%}
{% link-card title="Expo" appearance="small" url="/packages/expo" icon="expo" /%}
{% link-card title="React Native" appearance="small" url="/packages/react-native" icon="react" /%}
{% link-card title="Fastify" appearance="small" url="/showcase/example-repos/mongo-fastify" icon="fastify" /%}
{% link-card title="Deno" appearance="small" url="https://github.com/nrwl/nx-labs/tree/main/packages/deno" icon="deno" /%}
{% link-card title="Svelte" appearance="small" url="/showcase/example-repos/add-svelte" icon="svelte" /%}
{% link-card title="Solid" appearance="small" url="/showcase/example-repos/add-solid" icon="solid" /%}
{% link-card title="Lit" appearance="small" url="/showcase/example-repos/add-lit" icon="lit" /%}
{% link-card title="Astro" appearance="small" url="/showcase/example-repos/add-astro" icon="astro" /%}
{% link-card title="Qwik" appearance="small" url="/showcase/example-repos/add-qwik" icon="qwik" /%}
{% persona type="react" title="Create a React app" url="/getting-started/tutorials/react-standalone-tutorial" %} {% link-card title="Rust" appearance="small" url="/showcase/example-repos/add-rust" icon="rust" /%}
{% link-card title="Go" appearance="small" url="https://github.com/nrwl/nx-recipes/blob/main/go/README.md" icon="go" /%}
A modern React setup with built-in support for Vite, ESLint, Cypress, and more. Think CRA but modern, always up-to-date and scalable. {% link-card title=".NET" appearance="small" url="https://github.com/nrwl/nx-recipes/tree/main/dot-net-standalone" icon="dotnet" /%}
{% link-card title="Cypress" appearance="small" url="/packages/cypress" icon="cypress" /%}
- [Create a React app](/getting-started/tutorials/react-standalone-tutorial) {% link-card title="Playwright" appearance="small" url="/packages/playwright" icon="playwright" /%}
{% link-card title="Vite" appearance="small" url="/packages/vite" icon="vite" /%}
{% /persona %} {% link-card title="Storybook" appearance="small" url="/packages/storybook" icon="storybook" /%}
{% link-card title="Jest" appearance="small" url="/packages/jest" icon="jest" /%}
{% persona type="angular" title="Create an Angular app" url="/getting-started/tutorials/angular-standalone-tutorial" %} {% link-card title="Rspack" appearance="small" url="packages/rspack" icon="rspack" /%}
A modern Angular development experience powered by advanced generators and integrations with modern tooling.
- [Create an Angular app](/getting-started/tutorials/angular-standalone-tutorial)
{% /persona %}
{% persona type="node" title="Create a Node server" url="/getting-started/tutorials/node-server-tutorial" %}
A modern Node server with scaffolding for Express, Fastify or Koa. There's also Docker support built-in.
- [Create a Node server](/getting-started/tutorials/node-server-tutorial)
{% /persona %}
{% /cards %} {% /cards %}
## Adding Nx to an Existing Project ## Have an Existing Project? Add Nx to it!
If you have an existing project and want to adopt Nx or migrate to Nx just run the following command which guides you through the migration process: If you have an existing project and want to adopt Nx or migrate to Nx just run the following command which guides you through the migration process:
@ -104,22 +95,23 @@ npx nx@latest init
Alternatively, here are some recipes that give you more details based on the technology stack you're using: Alternatively, here are some recipes that give you more details based on the technology stack you're using:
{% cards cols="2" %} {% cards cols="2" mdCols="4" smCols="2" moreLink="/recipes/adopting-nx" %}
{% persona type="extend" title="Add to Existing Monorepo" url="/recipes/adopting-nx/adding-to-monorepo" %} {% link-card title="Add to Existing Monorepo" appearance="small" url="/recipes/adopting-nx/adding-to-monorepo" icon="pnpm" /%}
Add Nx to your existing NPM/YARN/PNPM workspace
{% /persona %}
{% persona title="Add to any Project" type="extend" url="/recipes/adopting-nx/adding-to-existing-project" %} {% link-card title="Add to Any Project" appearance="small" url="/recipes/adopting-nx/adding-to-existing-project" icon="nx" /%}
Add Nx to a project
{% /persona %}
{% persona title="Migrate from CRA" type="react" url="/recipes/react/migration-cra" %} {% link-card title="Migrate from CRA" appearance="small" url="/recipes/react/migration-cra" icon="cra" /%}
Migrate from a CRA setup and automatically switch to Vite
{% /persona %}
{% persona title="Migrate from Angular CLI" type="angular" url="/recipes/angular/migration/angular" %} {% link-card title="Migrate from Angular CLI" appearance="small" url="/recipes/angular/migration/angular" icon="angular" /%}
Automatically migrate from the Angular CLI
{% /persona %}
{% /cards %} {% /cards %}
## Connect With Us
Connect on our channels and with the Nx Community to ask questions, get help and keep up to date with the latest news.
- Join our [Discord Community](http://go.nx.dev/community)
- Subscribe to our [Youtube Channel](https://www.youtube.com/@nxdevtools)
- Follow us on [Twitter](https://twitter.com/nxdevtools)
- Subscribe [to our tech newsletter](https://go.nrwl.io/nx-newsletter)

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

View File

@ -2,12 +2,12 @@
Nx plugins contain [generators](/core-features/plugin-features/use-code-generators) and [executors](/core-features/plugin-features/use-task-executors) that extend the capabilities of an Nx workspace. They can be shared as npm packages or referenced locally within the same repo. Nx plugins contain [generators](/core-features/plugin-features/use-code-generators) and [executors](/core-features/plugin-features/use-task-executors) that extend the capabilities of an Nx workspace. They can be shared as npm packages or referenced locally within the same repo.
{% cards cols="2" %} {% cards cols="4" %}
{% title-card title="Use a Plugin" url="#use-a-plugin" /%} {% link-card title="Use a Plugin" url="#use-a-plugin" /%}
{% title-card title="Create a Local Plugin" url="#create-a-local-plugin" /%} {% link-card title="Create a Plugin" url="#create-a-local-plugin" /%}
{% title-card title="Maintain a Published Plugin" url="#maintain-a-published-plugin" /%} {% link-card title="Maintain a Published Plugin" url="#maintain-a-published-plugin" /%}
{% title-card title="Advanced Plugins" url="#advanced-plugins" /%} {% link-card title="Advanced Plugins" url="#advanced-plugins" /%}
{% /cards %} {% /cards %}

View File

@ -2,11 +2,11 @@
The code for this example is available on GitHub: The code for this example is available on GitHub:
{% github-repository url="https://github.com/nrwl/nx-recipes/tree/main/solidjs" %} {% github-repository url="https://github.com/nrwl/nx-recipes/tree/main/solidjs" /%}
**Supported Features** **Supported Features**
Because we are not using an Nx plugin for Solid, there are few items we'll have to configure manually. We'll have to Because we are not using an Nx plugin for Solid, there are a few items we'll have to configure manually. We'll have to
configure our own build system. There are no pre-created Solid-specific code generators. And we'll have to take care of configure our own build system. There are no pre-created Solid-specific code generators. And we'll have to take care of
updating any framework dependencies as needed. updating any framework dependencies as needed.

View File

@ -4,7 +4,7 @@
- [Intro to Nx](/getting-started/intro) - [Intro to Nx](/getting-started/intro)
- [Installation](/getting-started/installation) - [Installation](/getting-started/installation)
- [Why Nx?](/getting-started/why-nx) - [Why Nx?](/getting-started/why-nx)
- [5 min Tutorials](/getting-started/tutorials) - [Tutorials](/getting-started/tutorials)
- [Package-Based Monorepo](/getting-started/tutorials/package-based-repo-tutorial) - [Package-Based Monorepo](/getting-started/tutorials/package-based-repo-tutorial)
- [Integrated Monorepo](/getting-started/tutorials/integrated-repo-tutorial) - [Integrated Monorepo](/getting-started/tutorials/integrated-repo-tutorial)
- [React Standalone](/getting-started/tutorials/react-standalone-tutorial) - [React Standalone](/getting-started/tutorials/react-standalone-tutorial)

View File

@ -116,3 +116,24 @@ iframe[src*='youtube'] {
opacity: 1; opacity: 1;
visibility: visible; visibility: visible;
} }
/* Dark mode */
html.dark .adaptive-icon {
/* fill: white; */
filter: invert(1);
}
.adaptive-icon {
fill: black;
}
/* [data-theme='light'] .adaptive-icon {
fill: white;
} */
/* Light mode */
/* @media (prefers-color-scheme: light) {
.adaptive-icon {
fill: #000000;
}
} */

View File

@ -17,8 +17,8 @@ import { CustomLink } from './lib/nodes/link.component';
import { link } from './lib/nodes/link.schema'; import { link } from './lib/nodes/link.schema';
import { Callout } from './lib/tags/callout.component'; import { Callout } from './lib/tags/callout.component';
import { callout } from './lib/tags/callout.schema'; import { callout } from './lib/tags/callout.schema';
import { Card, Cards, TitleCard } from './lib/tags/cards.component'; import { Card, Cards, LinkCard } from './lib/tags/cards.component';
import { card, cards, titleCard } from './lib/tags/cards.schema'; import { card, cards, linkCard } from './lib/tags/cards.schema';
import { GithubRepository } from './lib/tags/github-repository.component'; import { GithubRepository } from './lib/tags/github-repository.component';
import { githubRepository } from './lib/tags/github-repository.schema'; import { githubRepository } from './lib/tags/github-repository.schema';
import { StackblitzButton } from './lib/tags/stackblitz-button.component'; import { StackblitzButton } from './lib/tags/stackblitz-button.component';
@ -43,6 +43,7 @@ import {
terminalVideo, terminalVideo,
} from './lib/tags/terminal-video.component'; } from './lib/tags/terminal-video.component';
import { VideoLink, videoLink } from './lib/tags/video-link.component'; import { VideoLink, videoLink } from './lib/tags/video-link.component';
// import { SvgAnimation, svgAnimation } from './lib/tags/svg-animation.component';
import { Pill } from './lib/tags/pill.component'; import { Pill } from './lib/tags/pill.component';
import { pill } from './lib/tags/pill.schema'; import { pill } from './lib/tags/pill.schema';
@ -63,6 +64,7 @@ export const getMarkdocCustomConfig = (
callout, callout,
card, card,
cards, cards,
'link-card': linkCard,
'github-repository': githubRepository, 'github-repository': githubRepository,
'stackblitz-button': stackblitzButton, 'stackblitz-button': stackblitzButton,
graph, graph,
@ -75,16 +77,17 @@ export const getMarkdocCustomConfig = (
'side-by-side': sideBySide, 'side-by-side': sideBySide,
tab, tab,
tabs, tabs,
'title-card': titleCard,
youtube, youtube,
'terminal-video': terminalVideo, 'terminal-video': terminalVideo,
'video-link': videoLink, 'video-link': videoLink,
// 'svg-animation': svgAnimation,
}, },
}, },
components: { components: {
Callout, Callout,
Card, Card,
Cards, Cards,
LinkCard,
CustomLink, CustomLink,
Fence, Fence,
GithubRepository, GithubRepository,
@ -100,10 +103,10 @@ export const getMarkdocCustomConfig = (
SideBySide, SideBySide,
Tab, Tab,
Tabs, Tabs,
TitleCard,
YouTube, YouTube,
TerminalVideo, TerminalVideo,
VideoLink, VideoLink,
// SvgAnimation,
}, },
}); });

File diff suppressed because one or more lines are too long

View File

@ -4,29 +4,110 @@ import {
DocumentIcon, DocumentIcon,
PlayCircleIcon, PlayCircleIcon,
} from '@heroicons/react/24/outline'; } from '@heroicons/react/24/outline';
import { frameworkIcons } from '../icons';
import { cx } from '@nx/nx-dev/ui-primitives';
import { ReactNode } from 'react'; import { ReactNode } from 'react';
export function Cards({ export function Cards({
cols = 2, cols = 2,
smCols = 3,
mdCols = 4,
lgCols = 4,
children, children,
moreLink,
}: { }: {
cols: number; cols: number;
smCols: number;
mdCols: number;
lgCols: number;
children: ReactNode; children: ReactNode;
moreLink?: string;
}): JSX.Element { }): JSX.Element {
const gridColums: { [key: number]: string } = { const calcCols = (cols: number, size: '' | 'lg' | 'md' | 'sm') => {
1: 'lg:grid-cols-1', if (size === '') return `grid-cols-${cols}`;
2: 'lg:grid-cols-2', return `${size}:grid-cols-${cols}`;
3: 'lg:grid-cols-3',
4: 'lg:grid-cols-4',
}; };
// <div className="mt-8 grid grid-cols-2 lg:grid-cols-5 md:grid-cols-3 sm:grid-cols-2 gap-4">
return ( return (
<div className={`mt-8 grid grid-cols-1 gap-4 ${gridColums[cols]}`}> <div
className={`mt-8 grid gap-4 ${calcCols(cols, '')} ${calcCols(
smCols,
'sm'
)} ${calcCols(mdCols, 'md')} ${calcCols(lgCols, 'lg')}`}
>
{children} {children}
{moreLink && (
<div className="flex justify-end mt-2 col-span-full">
<a
className="transition-all duration-200 ease-in-out flex items-center no-underline text-sm px-4 py-0 border-transparent hover:text-slate-900 dark:hover:text-sky-400 whitespace-nowrap font-semibold group"
href={moreLink}
>
Browse more
<span
className="pl-1 transition-all duration-200 ease-in-out group-hover:translate-x-1"
aria-hidden="true"
>
</span>
</a>
</div>
)}
</div> </div>
); );
} }
export function LinkCard({
title,
type,
icon,
url,
appearance = 'default',
}: {
title: string;
type: string;
icon: string; // `icon` is the link to the SVG file
url: string;
appearance?: 'default' | 'small';
}): JSX.Element {
return (
<a
key={title}
href={url}
className="no-prose relative col-span-1 flex flex-col items-center rounded-md border border-slate-200 bg-slate-50/40 p-4 text-center font-semibold shadow-sm transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-slate-100 dark:border-slate-800/40 dark:bg-slate-800/60 dark:hover:bg-slate-800"
style={{ textDecorationLine: 'none' }}
>
{icon && (
<div
className={cx(
'flex items-center justify-center w-24 h-24 rounded-lg mb-2',
{
'h-12 w-12': appearance === 'small',
}
)}
>
{icon && frameworkIcons[icon]?.image}
</div>
)}
<div className={cx('pt-4', { 'pt-2': appearance === 'small' })}>
{appearance === 'small' && type ? null : (
<div className="text-xs font-medium text-slate-600 dark:text-slate-300 uppercase mb-1">
{type}
</div>
)}
<h3
className={cx(
'text-lg font-semibold text-slate-900 dark:text-white m-0',
{ 'text-sm font-normal': appearance === 'small' }
)}
>
{title}
</h3>
</div>
</a>
);
}
export function Card({ export function Card({
description, description,
title, title,
@ -79,23 +160,3 @@ export function Card({
</div> </div>
); );
} }
export function TitleCard({
title,
url,
}: {
title: string;
url: string;
}): JSX.Element {
return (
<a
key={title}
href={url}
className="relative col-span-1 flex items-center rounded-md border border-slate-200 bg-slate-50/40 p-4 text-left text-lg font-semibold shadow-sm transition focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2 hover:bg-slate-50 dark:border-slate-800/40 dark:bg-slate-800/60 dark:hover:bg-slate-800 lg:justify-center lg:text-center"
style={{ textDecorationLine: 'none' }}
>
<span className="absolute inset-0" />
{title}
</a>
);
}

View File

@ -5,7 +5,49 @@ export const cards: Schema = {
attributes: { attributes: {
cols: { cols: {
type: 'Number', type: 'Number',
description: 'The number of colums per row', required: true,
},
smCols: {
type: 'Number',
required: true,
},
mdCols: {
type: 'Number',
required: true,
},
lgCols: {
type: 'Number',
required: true,
},
moreLink: {
type: 'String',
required: false,
},
},
};
export const linkCard: Schema = {
render: 'LinkCard',
attributes: {
title: {
type: 'String',
required: true,
},
type: {
type: 'String',
required: true,
},
icon: {
type: 'String',
required: false,
},
url: {
type: 'String',
default: '',
},
appearance: {
type: 'String',
default: 'default',
}, },
}, },
}; };
@ -31,16 +73,3 @@ export const card: Schema = {
}, },
}, },
}; };
export const titleCard: Schema = {
render: 'TitleCard',
attributes: {
title: {
type: 'String',
required: true,
},
url: {
type: 'String',
required: true,
},
},
};

View File

@ -23,6 +23,29 @@ export const youtube: Schema = {
}, },
}; };
function computeEmbedURL(youtubeURL: string) {
let match;
if (youtubeURL.indexOf('embed') > -1) {
// we already have the embed URL, so just ignore
return youtubeURL;
}
// Check for 'https://www.youtube.com/watch?v=' format
match = youtubeURL.match(/youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)/);
if (match && match[1]) {
return 'https://www.youtube.com/embed/' + match[1];
}
// Check for 'https://youtu.be/' format
match = youtubeURL.match(/youtu\.be\/([a-zA-Z0-9_-]+)/);
if (match && match[1]) {
return 'https://www.youtube.com/embed/' + match[1];
}
throw new Error(`Could not properly compute the embed URL for ${youtubeURL}`);
}
export function YouTube(props: { export function YouTube(props: {
title: string; title: string;
caption: string; caption: string;
@ -34,7 +57,7 @@ export function YouTube(props: {
{' '} {' '}
{/* Center alignment applied to the container */} {/* Center alignment applied to the container */}
<iframe <iframe
src={props.src} src={computeEmbedURL(props.src)}
title={props.title} title={props.title}
width={props.width || '100%'} width={props.width || '100%'}
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; fullscreen" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; fullscreen"

View File

@ -37,7 +37,7 @@ function removeAnchors(linkPath: string): string {
function extractAllLinks(basePath: string): Record<string, string[]> { function extractAllLinks(basePath: string): Record<string, string[]> {
return glob.sync(`${basePath}/**/*.md`).reduce((acc, path) => { return glob.sync(`${basePath}/**/*.md`).reduce((acc, path) => {
const fileContents = readFileContents(path); const fileContents = readFileContents(path);
const cardLinks = (fileContents.match(/url="(.*)"/g) || []).map((v) => const cardLinks = (fileContents.match(/url="(.*?)"/g) || []).map((v) =>
v.slice(5, -1) v.slice(5, -1)
); );
const links = parseLinks(fileContents) const links = parseLinks(fileContents)