Skip to content

Commit e75a30e

Browse files
authored
Allow for title and description for entire panel (#33)
1 parent cff7cc9 commit e75a30e

File tree

12 files changed

+76
-6
lines changed

12 files changed

+76
-6
lines changed

.github/workflows/pr-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ jobs:
2424
run: |
2525
cd packages/trpc-ui
2626
yarn install
27-
yarn pkg-pr-new publish
27+
yarn pkg-pr-new publish --packageManager=yarn

CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ The repo is configured to work with yarn v1 workspaces. To install dependencies
1515
yarn
1616
```
1717

18+
When adding new dependencies, be sure to add them in the correct package, and not the top level `package.json`.
19+
1820
### Development App
1921

2022
Included in this repo there is a development app that makes it easy to work on `trpc-ui` locally. It is a `next.js` app that will render the router included in the dev app. To run it, do:

README.MD

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,18 @@ import { renderTrpcPanel } from "trpc-ui";
5151
// ...
5252
app.use("/panel", (_, res) => {
5353
return res.send(
54-
renderTrpcPanel(myTrpcRouter, { url: "http://localhost:4000/trpc" })
54+
renderTrpcPanel(myTrpcRouter, { url: "http://localhost:4000/trpc", meta: {
55+
title: "My Backend Title",
56+
description: "This is a description of my API, which supports [markdown](https://en.wikipedia.org/wiki/Markdown).",
57+
}})
5558
);
5659
});
5760
```
5861

5962
`trpc-ui` just renders as a string, so it can be used with any backend.
6063

64+
To document your entire backend, you can pass in a metadata object with a title and description. To document individual procedures, see the [documenting procedures](#documenting-procedures).
65+
6166
## NextJS / create-t3-app example
6267

6368
In Nextjs you'd want to create an api route somewhere like `src/pages/api/panel.ts` and send a text response:

packages/dev-app/src/pages/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ const App = dynamic(
1313
options={{
1414
url: "http://localhost:3000/api/trpc",
1515
transformer: "superjson",
16+
meta: {
17+
title: "Dev App Title",
18+
description:
19+
"Dev App Description is longer and should support [markdown](https://github.com/aidansunbury/trpc-ui) \n## Heading 2\n### Heading 3 \n - list item 1\n - list item 2\n",
20+
},
1621
}}
1722
trpc={trpc}
1823
/>

packages/trpc-ui/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"description": "UI for testing tRPC backends",
55
"main": "lib/index.js",
66
"module": "lib/index.mjs",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/aidansunbury/trpc-ui/"
10+
},
711
"typings": "lib/src/index.d.ts",
812
"scripts": {
913
"test": "jest",
@@ -92,13 +96,15 @@
9296
},
9397
"dependencies": {
9498
"@textea/json-viewer": "^3.0.0",
99+
"clsx": "^2.1.1",
95100
"fuzzysort": "^2.0.4",
96101
"nuqs": "^2.2.1",
97102
"path": "^0.12.7",
98103
"pretty-bytes": "^6.1.0",
99104
"pretty-ms": "^8.0.0",
100105
"react-markdown": "^9.0.1",
101106
"string-byte-length": "^1.6.0",
107+
"tailwind-merge": "^2.5.5",
102108
"url": "^0.11.0",
103109
"zod-to-json-schema": "^3.20.0"
104110
}

packages/trpc-ui/src/react-app/Root.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import React, { type ReactNode, useEffect, useState } from "react";
2020
import { Toaster } from "react-hot-toast";
2121
import superjson from "superjson";
2222
import type { ParsedRouter } from "../parse/parseRouter";
23+
import { MetaHeader } from "./components/MetaHeader";
2324
import { RouterContainer } from "./components/RouterContainer";
2425
import { SideNav } from "./components/SideNav";
2526
import { TopBar } from "./components/TopBar";
@@ -122,6 +123,7 @@ function AppInnards({
122123
}}
123124
>
124125
<div className="container max-w-6xl p-4 pt-8">
126+
<MetaHeader meta={options.meta} />
125127
<RouterContainer router={rootRouter} options={options} />
126128
</div>
127129
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { Info } from "@src/render";
2+
import React from "react";
3+
import Markdown from "react-markdown";
4+
5+
export function MetaHeader({ meta }: { meta?: Info }) {
6+
if (!meta) {
7+
return null;
8+
}
9+
const { title, description } = meta;
10+
return (
11+
<header>
12+
{title && <h1 className="pb-2 font-bold text-5xl">{title}</h1>}
13+
{description && (
14+
<article className="prose">
15+
<Markdown className={"prose"}>{description}</Markdown>
16+
</article>
17+
)}
18+
</header>
19+
);
20+
}

packages/trpc-ui/src/react-app/components/RouterContainer.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ProcedureForm } from "@src/react-app/components/form/ProcedureForm";
33
import type { RenderOptions } from "@src/render";
44
import React from "react";
55
import type { ParsedRouter } from "../../parse/parseRouter";
6+
import { cn } from "../utils/utils";
67

78
export function RouterContainer({
89
router,
@@ -28,7 +29,9 @@ export function RouterContainer({
2829
isRoot={isRoot}
2930
>
3031
<div
31-
className={`space-y-3${!isRoot ? "space-y-1 border-l-grey-400 p-1" : ""}`}
32+
className={cn("space-y-3", {
33+
"space-y-1 border-l-grey-400 p-1": !isRoot,
34+
})}
3235
>
3336
{Object.entries(router.children).map(
3437
([childName, routerOrProcedure]) => {

packages/trpc-ui/src/react-app/components/TopBar.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,21 @@ export function TopBar({
3030
<Chevron className="h-4 w-4" direction="right" />
3131
)}
3232
</button>
33-
<span className="flex flex-row items-center font-bold font-mono text-lg">
33+
<a
34+
href="https://github.com/aidansunbury/trpc-ui"
35+
target="_blank"
36+
className="flex flex-row items-center font-bold font-mono text-lg"
37+
rel="noreferrer"
38+
>
3439
<LogoSvg className="mr-2 h-10 w-10 rounded-lg" />
35-
tRPC.panel()
36-
</span>
40+
tRPC.ui()
41+
</a>
3742
</div>
3843
<RouterSearchTooltip />
3944
<button
4045
onClick={() => setHeadersPopupShown(true)}
4146
className="rounded-sm border border-neutralSolidTransparent px-4 py-2 font-bold text-neutralText shadow-sm"
47+
type="button"
4248
>
4349
Headers
4450
<MailLockIcon className="ml-1 h-6 w-6" />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { type ClassValue, clsx } from "clsx";
2+
import { twMerge } from "tailwind-merge";
3+
4+
export function cn(...inputs: ClassValue[]) {
5+
return twMerge(clsx(inputs));
6+
}

0 commit comments

Comments
 (0)