docs(core): maintain ts monorepos feature (#30256)
Adds the Maintain TypeScript Monorepos feature page
This commit is contained in:
parent
8e6c00719b
commit
c698b1ef9c
@ -235,6 +235,14 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Automate Updating Dependencies",
|
||||
"path": "/features/automate-updating-dependencies",
|
||||
@ -359,6 +367,14 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Automate Updating Dependencies",
|
||||
"path": "/features/automate-updating-dependencies",
|
||||
|
||||
@ -317,6 +317,17 @@
|
||||
"path": "/features/generate-code",
|
||||
"tags": ["generate-code"]
|
||||
},
|
||||
{
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"tags": ["inferred-tasks", "project-linking", "sync"]
|
||||
},
|
||||
{
|
||||
"id": "automate-updating-dependencies",
|
||||
"name": "Automate Updating Dependencies",
|
||||
@ -488,6 +499,17 @@
|
||||
"path": "/features/generate-code",
|
||||
"tags": ["generate-code"]
|
||||
},
|
||||
"/features/maintain-ts-monorepos": {
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"description": "",
|
||||
"mediaImage": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/features/maintain-ts-monorepos",
|
||||
"tags": ["inferred-tasks", "project-linking", "sync"]
|
||||
},
|
||||
"/features/automate-updating-dependencies": {
|
||||
"id": "automate-updating-dependencies",
|
||||
"name": "Automate Updating Dependencies",
|
||||
|
||||
@ -382,6 +382,110 @@
|
||||
"path": "/nx-api/nx/documents/generate"
|
||||
}
|
||||
],
|
||||
"inferred-tasks": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/mental-model",
|
||||
"id": "mental-model",
|
||||
"name": "Mental Model",
|
||||
"path": "/concepts/mental-model"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/nx-plugins",
|
||||
"id": "nx-plugins",
|
||||
"name": "What Are Nx Plugins",
|
||||
"path": "/concepts/nx-plugins"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/inferred-tasks",
|
||||
"id": "inferred-tasks",
|
||||
"name": "Inferred Tasks",
|
||||
"path": "/concepts/inferred-tasks"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/running-tasks/convert-to-inferred",
|
||||
"id": "convert-to-inferred",
|
||||
"name": "Migrate to Inferred Tasks (Project Crystal)",
|
||||
"path": "/recipes/running-tasks/convert-to-inferred"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/plugins/project-graph-plugins",
|
||||
"id": "project-graph-plugins",
|
||||
"name": "Infer Tasks or Projects",
|
||||
"path": "/extending-nx/recipes/project-graph-plugins"
|
||||
}
|
||||
],
|
||||
"project-linking": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/typescript-project-linking",
|
||||
"id": "typescript-project-linking",
|
||||
"name": "TypeScript Project Linking",
|
||||
"path": "/concepts/typescript-project-linking"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/tips-n-tricks/switch-to-workspaces-project-references",
|
||||
"id": "switch-to-workspaces-project-references",
|
||||
"name": "Switch to Workspaces and TS Project References",
|
||||
"path": "/recipes/tips-n-tricks/switch-to-workspaces-project-references"
|
||||
}
|
||||
],
|
||||
"sync": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/features/maintain-typescript-monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"path": "/features/maintain-ts-monorepos"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/sync-generators",
|
||||
"id": "sync-generators",
|
||||
"name": "Sync Generators",
|
||||
"path": "/concepts/sync-generators"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/generators/create-sync-generator",
|
||||
"id": "create-sync-generator",
|
||||
"name": "Create a Sync Generator",
|
||||
"path": "/extending-nx/recipes/create-sync-generator"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync",
|
||||
"id": "sync",
|
||||
"name": "sync",
|
||||
"path": "/nx-api/nx/documents/sync"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync-check",
|
||||
"id": "sync-check",
|
||||
"name": "sync:check",
|
||||
"path": "/nx-api/nx/documents/sync-check"
|
||||
}
|
||||
],
|
||||
"automate-updating-dependencies": [
|
||||
{
|
||||
"description": "Learn how Nx provides automated update scripts to help you keep your workspace, tooling and framework dependencies up to date.",
|
||||
@ -621,43 +725,6 @@
|
||||
"path": "/concepts/mental-model"
|
||||
}
|
||||
],
|
||||
"inferred-tasks": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/mental-model",
|
||||
"id": "mental-model",
|
||||
"name": "Mental Model",
|
||||
"path": "/concepts/mental-model"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/nx-plugins",
|
||||
"id": "nx-plugins",
|
||||
"name": "What Are Nx Plugins",
|
||||
"path": "/concepts/nx-plugins"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/inferred-tasks",
|
||||
"id": "inferred-tasks",
|
||||
"name": "Inferred Tasks",
|
||||
"path": "/concepts/inferred-tasks"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/running-tasks/convert-to-inferred",
|
||||
"id": "convert-to-inferred",
|
||||
"name": "Migrate to Inferred Tasks (Project Crystal)",
|
||||
"path": "/recipes/running-tasks/convert-to-inferred"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/plugins/project-graph-plugins",
|
||||
"id": "project-graph-plugins",
|
||||
"name": "Infer Tasks or Projects",
|
||||
"path": "/extending-nx/recipes/project-graph-plugins"
|
||||
}
|
||||
],
|
||||
"add": [
|
||||
{
|
||||
"description": "",
|
||||
@ -748,52 +815,6 @@
|
||||
"path": "/nx-api/nx/documents/daemon"
|
||||
}
|
||||
],
|
||||
"sync": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/sync-generators",
|
||||
"id": "sync-generators",
|
||||
"name": "Sync Generators",
|
||||
"path": "/concepts/sync-generators"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/generators/create-sync-generator",
|
||||
"id": "create-sync-generator",
|
||||
"name": "Create a Sync Generator",
|
||||
"path": "/extending-nx/recipes/create-sync-generator"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync",
|
||||
"id": "sync",
|
||||
"name": "sync",
|
||||
"path": "/nx-api/nx/documents/sync"
|
||||
},
|
||||
{
|
||||
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
||||
"file": "generated/packages/nx/documents/sync-check",
|
||||
"id": "sync-check",
|
||||
"name": "sync:check",
|
||||
"path": "/nx-api/nx/documents/sync-check"
|
||||
}
|
||||
],
|
||||
"project-linking": [
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/concepts/typescript-project-linking",
|
||||
"id": "typescript-project-linking",
|
||||
"name": "TypeScript Project Linking",
|
||||
"path": "/concepts/typescript-project-linking"
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"file": "shared/recipes/tips-n-tricks/switch-to-workspaces-project-references",
|
||||
"id": "switch-to-workspaces-project-references",
|
||||
"name": "Switch to Workspaces and TS Project References",
|
||||
"path": "/recipes/tips-n-tricks/switch-to-workspaces-project-references"
|
||||
}
|
||||
],
|
||||
"module-federation": [
|
||||
{
|
||||
"description": "",
|
||||
|
||||
@ -101,6 +101,12 @@
|
||||
"tags": ["generate-code"],
|
||||
"file": "shared/features/generate-code"
|
||||
},
|
||||
{
|
||||
"name": "Maintain TypeScript Monorepos",
|
||||
"id": "maintain-ts-monorepos",
|
||||
"tags": ["inferred-tasks", "project-linking", "sync"],
|
||||
"file": "shared/features/maintain-typescript-monorepos"
|
||||
},
|
||||
{
|
||||
"name": "Automate Updating Dependencies",
|
||||
"description": "Learn how Nx provides automated update scripts to help you keep your workspace, tooling and framework dependencies up to date.",
|
||||
|
||||
284
docs/shared/features/maintain-typescript-monorepos.md
Normal file
284
docs/shared/features/maintain-typescript-monorepos.md
Normal file
@ -0,0 +1,284 @@
|
||||
# Maintain TypeScript Monorepos
|
||||
|
||||
Keeping all the industry-standard tools involved in a large TypeScript monorepo correctly configured and working well together is a difficult task. And the more tools you add, the more opportunity there is for tools to conflict with each other in some way.
|
||||
|
||||
In addition to [generating default configuration files](/features/generate-code) and [automatically updating dependencies](/features/automate-updating-dependencies) to versions that we know work together, Nx makes managing all the tools in your monorepo easier in two ways:
|
||||
|
||||
- Rather than adding another tool that you have to configure, Nx configures itself to match the existing configuration of other tools.
|
||||
- Nx also enhances certain tools to be more usable in a monorepo context.
|
||||
|
||||
## Auto-Configuration
|
||||
|
||||
Whenever possible, Nx will detect the existing configuration settings of other tools and update itself to match.
|
||||
|
||||
### Project Detection with Workspaces
|
||||
|
||||
If your repository is using package manager workspaces, Nx will use those settings to find all the [projects](/reference/project-configuration) in your repository. So you don't need to define a project for your package manager and separately identify the project for Nx. The `workspaces` configuration on the left allows Nx to detect the project graph on the right.
|
||||
|
||||
{% side-by-side align="top" %}
|
||||
|
||||
```json {% fileName="/package.json" %}
|
||||
{
|
||||
"workspaces": ["apps/*", "packages/*"]
|
||||
}
|
||||
```
|
||||
|
||||
{% graph height="200px" title="Project View" %}
|
||||
|
||||
```json
|
||||
{
|
||||
"composite": false,
|
||||
"projects": [
|
||||
{
|
||||
"name": "product-state",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"root": "packages/cart/product-state",
|
||||
"tags": ["scope:cart", "type:state"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ui-buttons",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"root": "packages/ui/buttons",
|
||||
"tags": ["scope:shared", "type:ui"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "cart",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"root": "apps/cart",
|
||||
"tags": ["type:app", "scope:cart"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"product-state": [],
|
||||
"ui-buttons": [],
|
||||
"cart": [
|
||||
{ "source": "cart", "target": "product-state", "type": "static" },
|
||||
{ "source": "cart", "target": "ui-buttons", "type": "static" }
|
||||
]
|
||||
},
|
||||
"workspaceLayout": {
|
||||
"appsDir": "apps",
|
||||
"libsDir": "libs"
|
||||
},
|
||||
"affectedProjectIds": [],
|
||||
"focus": null,
|
||||
"groupByFolder": false,
|
||||
"exclude": [],
|
||||
"enableTooltips": false
|
||||
}
|
||||
```
|
||||
|
||||
{% /graph %}
|
||||
|
||||
{% /side-by-side %}
|
||||
|
||||
### Inferred Tasks with Tooling Plugins
|
||||
|
||||
Nx provides [plugins](/concepts/nx-plugins) for tools that run tasks, like Vite, TypeScript, Playwright or Jest. These plugins can automatically [infer the Nx-specific task configuration](/concepts/inferred-tasks) based on the tooling configuration files that already exist.
|
||||
|
||||
In the example below, because the `/apps/cart/vite.config.ts` file exists, Nx knows that the `cart` project can run a `build` task using Vite. If you expand the `build` task on the right, you can also see that Nx configured the output directory for the [cache](/features/cache-task-results) to match the `build.outDir` provided in the Vite configuration file.
|
||||
|
||||
With inferred tasks, you can keep your tooling configuration file as the one source of truth for that tool's configuration, instead of adding an extra layer of configuration on top.
|
||||
|
||||
{% side-by-side align="top" %}
|
||||
|
||||
```ts {% fileName="/apps/cart/vite.config.ts" %}
|
||||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
root: __dirname,
|
||||
cacheDir: '../../node_modules/.vite/apps/cart',
|
||||
plugins: [react()],
|
||||
build: {
|
||||
outDir: './dist',
|
||||
emptyOutDir: true,
|
||||
reportCompressedSize: true,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
{% project-details %}
|
||||
|
||||
```json
|
||||
{
|
||||
"project": {
|
||||
"name": "cart",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"root": "apps/cart",
|
||||
"targets": {
|
||||
"build": {
|
||||
"options": {
|
||||
"cwd": "apps/cart",
|
||||
"command": "vite build"
|
||||
},
|
||||
"cache": true,
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": [
|
||||
"production",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": ["vite"]
|
||||
}
|
||||
],
|
||||
"outputs": ["{projectRoot}/dist"],
|
||||
"executor": "nx:run-commands",
|
||||
"configurations": {},
|
||||
"metadata": {
|
||||
"technologies": ["vite"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "cart",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/cart/src",
|
||||
"projectType": "application",
|
||||
"tags": [],
|
||||
"implicitDependencies": [],
|
||||
"metadata": {
|
||||
"technologies": ["react"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceMap": {
|
||||
"root": ["apps/cart/project.json", "nx/core/project-json"],
|
||||
"targets": ["apps/cart/project.json", "nx/core/project-json"],
|
||||
"targets.build": ["apps/cart/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.command": ["apps/cart/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.options": ["apps/cart/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.cache": ["apps/cart/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.dependsOn": ["apps/cart/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.inputs": ["apps/cart/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.outputs": ["apps/cart/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.options.cwd": [
|
||||
"apps/cart/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"name": ["apps/cart/project.json", "nx/core/project-json"],
|
||||
"$schema": ["apps/cart/project.json", "nx/core/project-json"],
|
||||
"sourceRoot": ["apps/cart/project.json", "nx/core/project-json"],
|
||||
"projectType": ["apps/cart/project.json", "nx/core/project-json"],
|
||||
"tags": ["apps/cart/project.json", "nx/core/project-json"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{% /project-details %}
|
||||
|
||||
{% /side-by-side %}
|
||||
|
||||
## Enhance Tools for Monorepos
|
||||
|
||||
Nx does not just reduce its own configuration burden, it also improves the functionality of your existing tools so that they work better in a monorepo context.
|
||||
|
||||
### Keep TypeScript Project References in Sync
|
||||
|
||||
TypeScript provides a feature called [Project References](https://www.typescriptlang.org/docs/handbook/project-references.html) that allows the TypeScript compiler to build and typecheck each project independently. When each project is typechecked, the TypeScript compiler will output an intermediate `*.tsbuildinfo` file that can be used by other projects instead of re-typechecking all dependencies. This feature can provide [significant performance improvements](/concepts/typescript-project-linking#typescript-project-references-performance-benefits), particularly in a large monorepo.
|
||||
|
||||
The main downside of this feature is that you have to manually define each project's references (dependencies) in the appropriate `tsconfig.*.json` file. This process is tedious to set up and very difficult to maintain as the repository changes over time. Nx can help by using a [sync generator](/concepts/sync-generators) to automatically update the references defined in the `tsconfig.json` files based on the project graph it already knows about.
|
||||
|
||||
{% side-by-side align="top" %}
|
||||
|
||||
{% graph height="200px" title="Project View" %}
|
||||
|
||||
```json
|
||||
{
|
||||
"composite": false,
|
||||
"projects": [
|
||||
{
|
||||
"name": "product-state",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"root": "packages/cart/product-state",
|
||||
"tags": ["scope:cart", "type:state"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ui-buttons",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"root": "packages/ui/buttons",
|
||||
"tags": ["scope:shared", "type:ui"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "cart",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"root": "apps/cart",
|
||||
"tags": ["type:app", "scope:cart"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"product-state": [],
|
||||
"ui-buttons": [],
|
||||
"cart": [
|
||||
{ "source": "cart", "target": "product-state", "type": "static" },
|
||||
{ "source": "cart", "target": "ui-buttons", "type": "static" }
|
||||
]
|
||||
},
|
||||
"workspaceLayout": {
|
||||
"appsDir": "apps",
|
||||
"libsDir": "libs"
|
||||
},
|
||||
"affectedProjectIds": [],
|
||||
"focus": null,
|
||||
"groupByFolder": false,
|
||||
"exclude": [],
|
||||
"enableTooltips": false
|
||||
}
|
||||
```
|
||||
|
||||
{% /graph %}
|
||||
|
||||
```jsonc {% fileName="apps/cart/tsconfig.json" %}
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [], // intentionally empty
|
||||
"references": [
|
||||
// UPDATED BY NX SYNC
|
||||
// All project dependencies
|
||||
{
|
||||
"path": "../../packages/product-state"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/ui/buttons"
|
||||
},
|
||||
// This project's other tsconfig.*.json files
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{% /side-by-side %}
|
||||
|
||||
Later, if someone adds another dependency to the `cart` app and then runs the `build` task, Nx will detect that the project references are out of sync and ask if the references should be updated.
|
||||
|
||||
```text {% command="nx build cart" path="~/myorg" %}
|
||||
NX The workspace is out of sync
|
||||
|
||||
[@nx/js:typescript-sync]: Some TypeScript configuration files are missing project references to the projects they depend on or contain outdated project references.
|
||||
|
||||
This will result in an error in CI.
|
||||
|
||||
? Would you like to sync the identified changes to get your workspace up to date? …
|
||||
❯ Yes, sync the changes and run the tasks
|
||||
No, run the tasks without syncing the changes
|
||||
```
|
||||
@ -16,6 +16,7 @@
|
||||
- [Enhance Your LLM](/features/enhance-AI)
|
||||
- [Explore Your Workspace](/features/explore-graph)
|
||||
- [Generate Code](/features/generate-code)
|
||||
- [Maintain TypeScript Monorepos](/features/maintain-ts-monorepos)
|
||||
- [Automate Updating Dependencies](/features/automate-updating-dependencies)
|
||||
- [Enforce Module Boundaries](/features/enforce-module-boundaries)
|
||||
- [Manage Releases](/features/manage-releases)
|
||||
|
||||
@ -69,7 +69,7 @@ export function Graph({
|
||||
if (!jsonFile && !parsedProps) {
|
||||
if (!children || !children.hasOwnProperty('props')) {
|
||||
return (
|
||||
<div className="no-prose my-6 block rounded-md bg-red-50 p-4 text-red-700 ring-1 ring-red-100 dark:bg-red-900/30 dark:text-red-600 dark:ring-red-900">
|
||||
<div className="no-prose block rounded-md bg-red-50 p-4 text-red-700 ring-1 ring-red-100 dark:bg-red-900/30 dark:text-red-600 dark:ring-red-900">
|
||||
<p className="mb-4">
|
||||
No JSON provided for graph, use JSON code fence to embed data for
|
||||
the graph.
|
||||
@ -82,7 +82,7 @@ export function Graph({
|
||||
setParsedProps(JSON.parse(children?.props.children as any));
|
||||
} catch {
|
||||
return (
|
||||
<div className="not-prose my-6 block rounded-md bg-red-50 p-4 text-red-700 ring-1 ring-red-100 dark:bg-red-900/30 dark:text-red-600 dark:ring-red-900">
|
||||
<div className="not-prose block rounded-md bg-red-50 p-4 text-red-700 ring-1 ring-red-100 dark:bg-red-900/30 dark:text-red-600 dark:ring-red-900">
|
||||
<p className="mb-4">Could not parse JSON for graph:</p>
|
||||
<pre className="p-4 text-sm">{children?.props.children as any}</pre>
|
||||
</div>
|
||||
@ -94,7 +94,7 @@ export function Graph({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="my-6 w-full place-content-center overflow-hidden rounded-md ring-1 ring-slate-200 dark:ring-slate-700">
|
||||
<div className="w-full place-content-center overflow-hidden rounded-md ring-1 ring-slate-200 dark:ring-slate-700">
|
||||
<div className="relative flex justify-center border-b border-slate-200 bg-slate-100/50 p-2 font-bold dark:border-slate-700 dark:bg-slate-700/50">
|
||||
{title}
|
||||
</div>
|
||||
|
||||
@ -1,9 +1,21 @@
|
||||
import { cx } from '@nx/nx-dev/ui-primitives';
|
||||
import { Children, ReactNode } from 'react';
|
||||
|
||||
export function SideBySide({ children }: { children: ReactNode }) {
|
||||
export function SideBySide({
|
||||
align,
|
||||
children,
|
||||
}: {
|
||||
align: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const [first, ...rest] = Children.toArray(children);
|
||||
return (
|
||||
<div className="not-prose grid items-center divide-x divide-solid divide-slate-50 md:grid-cols-2 dark:divide-slate-800">
|
||||
<div
|
||||
className={cx(
|
||||
'not-prose grid divide-x divide-solid divide-slate-50 md:grid-cols-2 dark:divide-slate-800',
|
||||
align === 'top' ? 'items-start' : 'items-center'
|
||||
)}
|
||||
>
|
||||
<div className="md:pr-6">{first}</div>
|
||||
<div className="md:pl-6">{rest}</div>
|
||||
</div>
|
||||
|
||||
@ -2,5 +2,9 @@ import { Schema } from '@markdoc/markdoc';
|
||||
|
||||
export const sideBySide: Schema = {
|
||||
render: 'SideBySide',
|
||||
attributes: {},
|
||||
attributes: {
|
||||
align: {
|
||||
type: 'String',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user