Skip to content
Closed
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
9 changes: 9 additions & 0 deletions .changeset/keypoints-block.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@pmndrs/docs': minor
---

`Keypoints` is now a shadcn registry block, installable into any app with `npx shadcn@latest add pmndrs/docs/keypoints`. It is the first pmndrs block to be distributed this way, and the first to depend on the shared colour layer across registries — `pmndrs/design-system/md3`, for the one MD3 role it uses that shadcn has no equivalent for.

Being distributable is what drove the three changes to it. It reached into this app's MDX component map for the list wrappers, so those are inlined; it imported `cn` through a path `components.json` does not alias, so the whole app is standardized on `@/lib/utils` and the duplicate `src/lib/cn.ts` is gone; and it painted its border with `border-outline-variant`, which is `border-border` by another name, so it now uses the stock token and keeps `bg-surface-dim` as the single deliberate MD3 reach.

Nothing changes for authors: the same `<Keypoints>` / `<KeypointsItem>` in the same MDX, rendering the same. The source moved from `src/components/mdx/Keypoints/` to `registry/keypoints/`, alongside `registry.json` at the root.
6 changes: 5 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { StorybookConfig } from '@storybook/nextjs-vite'

const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)', '../src/**/*.mdx'],
stories: [
'../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
'../src/**/*.mdx',
'../registry/**/*.stories.@(js|jsx|mjs|ts|tsx)',
],
addons: ['@storybook/addon-docs', '@storybook/addon-themes'],
framework: '@storybook/nextjs-vite',
staticDirs: ['../public'],
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"prettier-plugin-tailwindcss": "^0.7.2",
"rehype-parse": "^9.0.1",
"rehype-stringify": "^10.0.1",
"shadcn": "^4.18.0",
"storybook": "^10.2.0",
"tailwindcss": "^4.1.18",
"tailwindcss-animate": "^1.0.7",
Expand Down Expand Up @@ -89,8 +90,9 @@
"dev": "NODE_OPTIONS='--inspect' next",
"start": "next start",
"build": "./next-build.sh",
"format": "prettier -w src/",
"lint": "eslint src/**/*.{ts,tsx} && prettier . --check",
"format": "prettier -w src/ registry/",
"lint": "eslint src/**/*.{ts,tsx} registry/ && prettier . --check",
"check-registry": "shadcn registry validate ./registry.json",
"prepare": "husky && (test -f scripts/copy-fonts.sh && sh scripts/copy-fonts.sh || true)",
"release": "changeset publish",
"changeset": "changeset",
Expand Down
966 changes: 966 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions registry.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "pmndrs-docs",
"homepage": "https://github.com/pmndrs/docs",
"items": [
{
"name": "keypoints",
"type": "registry:block",
"title": "Keypoints",
"description": "A titled panel listing the main points an article covers — one bullet per `KeypointsItem`. Usually sits right after the intro.",
"author": "pmndrs",
"registryDependencies": ["pmndrs/design-system/md3#v0.3.0"],
"files": [
{
"path": "registry/keypoints/keypoints.tsx",
"type": "registry:block"
}
],
"docs": "Renders on stock shadcn tokens apart from `bg-surface-dim`, which is why it depends on `pmndrs/design-system/md3` — MD3 has a surface role shadcn has no equivalent for. Installing it without that dependency resolved leaves the panel with no background at all, and Tailwind reports nothing."
}
]
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Meta, StoryObj } from '@storybook/nextjs-vite'

import { Keypoints, KeypointsItem } from './Keypoints'
import { allModes } from '../../../../.storybook/modes'
import { allModes } from '../../.storybook/modes'
import { Keypoints, KeypointsItem } from './keypoints'

const meta = {
component: Keypoints,
Expand Down
26 changes: 26 additions & 0 deletions registry/keypoints/keypoints.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { cn } from '@/lib/utils'
import { ComponentProps } from 'react'

export function Keypoints({
title = 'Keypoints',
children,
className,
...props
}: { title?: string } & ComponentProps<'section'>) {
return (
<section
{...props}
className={cn('bg-surface-dim my-8 rounded-xl border border-border p-6', className)}
>
<h2 className="mb-6 text-2xl font-bold">{title}</h2>

<div className="mt-4 mb-0 text-sm">
<ul className="ms-6 list-disc">{children}</ul>
</div>
</section>
)
}

export function KeypointsItem(props: ComponentProps<'li'>) {
return <li className="my-1" {...props} />
}
2 changes: 1 addition & 1 deletion src/app/[...slug]/Burger.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import Icon from '@/components/Icon'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ComponentProps } from 'react'

export function Burger({ opened, className }: { opened: boolean } & ComponentProps<'span'>) {
Expand Down
2 changes: 1 addition & 1 deletion src/app/[...slug]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Layout, LayoutAside, LayoutContent, LayoutHeader, LayoutNav } from '@/c
import { Nav } from '@/components/Nav'
import Search from '@/components/Search'
import { Toc } from '@/components/mdx/Toc'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { getData } from '@/utils/docs'
import Link from 'next/link'
import { PiDiscordLogoLight } from 'react-icons/pi'
Expand Down
2 changes: 1 addition & 1 deletion src/app/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { getData, getDocs } from '@/utils/docs'

export type Props = {
Expand Down
2 changes: 1 addition & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { docsMtb } from '@/lib/mtb'
import { svg } from '@/utils/icon'
import resolveMdxUrl from '@/utils/resolveMdxUrl'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import * as React from 'react'

type SVGProps = Partial<React.SVGProps<SVGSVGElement>>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ComponentProps } from 'react'

//
Expand Down
2 changes: 1 addition & 1 deletion src/components/Nav/Nav.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Doc } from '@/app/[...slug]/DocsContext'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import * as React from 'react'
import { NavCategory } from './NavCategory'
import { NavCategoryCollapsible } from './NavCategoryCollapsible'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Nav/NavCategory.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Doc } from '@/app/[...slug]/DocsContext'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import Link from 'next/link'
import { ComponentProps } from 'react'

Expand Down
2 changes: 1 addition & 1 deletion src/components/Nav/NavCategoryCollapsible.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { Doc } from '@/app/[...slug]/DocsContext'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import * as Collapsible from '@radix-ui/react-collapsible'
import { ComponentProps, useEffect, useState } from 'react'
import { IoIosArrowDown } from 'react-icons/io'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search/SearchItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Icon from '@/components/Icon'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { highlight } from '@/utils/text'
import Link from 'next/link'
import { ComponentProps } from 'react'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search/SearchModalContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react'

import { useDocs } from '@/app/[...slug]/DocsContext'

import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { escape } from '@/utils/text'
import { Command } from 'cmdk'
import { useRouter } from 'next/navigation'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import Icon from '@/components/Icon'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import * as Dialog from '@radix-ui/react-dialog'
import * as VisuallyHidden from '@radix-ui/react-visually-hidden'
import { ComponentProps, useEffect, useState } from 'react'
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Code/Code.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ComponentProps, isValidElement, ReactNode, useEffect, useState } from 'react'
import { TbClipboard, TbClipboardCheck } from 'react-icons/tb'

Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Codesandbox/Codesandbox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Img } from '@/components/mdx/Img'

import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ComponentProps } from 'react'

export type CSB = {
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Details/Details.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { type ComponentProps } from 'react'

export function Details({ className, ...props }: ComponentProps<'details'>) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Gha/Gha.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ReactNode } from 'react'
import { BiCommentError } from 'react-icons/bi'
import { CgInfo } from 'react-icons/cg'
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'

/**
* @deprecated
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Img/Img.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ComponentProps } from 'react'

import sizeOf from 'image-size'
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Intro/Intro.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { VisuallyHidden } from '@radix-ui/react-visually-hidden'
import { ComponentProps } from 'react'

Expand Down
26 changes: 0 additions & 26 deletions src/components/mdx/Keypoints/Keypoints.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/components/mdx/Keypoints/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/mdx/People/People.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { initials } from '@/utils/text'
import { Octokit } from '@octokit/core'
import Image from 'next/image'
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Sandpack/Sandpack.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { crawl } from '@/utils/docs'
import {
SandpackCodeEditor,
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Summary/Summary.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { type ComponentProps } from 'react'

export function Summary({ className, ...props }: ComponentProps<'summary'>) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/Toc/Toc.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import type { DocToC } from '@/app/[...slug]/DocsContext'
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ComponentProps, useCallback, useEffect, useState } from 'react'

export function Toc({ className, toc }: ComponentProps<'div'> & { toc: DocToC[] }) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/mdx/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cn from '@/lib/cn'
import { cn } from '@/lib/utils'
import { ComponentProps } from 'react'

const MARKDOWN_REGEX = /\.mdx?/
Expand Down
13 changes: 0 additions & 13 deletions src/lib/cn.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/utils/compileMdxContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { Img } from '@/components/mdx/Img'
import { rehypeImg } from '@/components/mdx/Img/rehypeImg'
import { Intro } from '@/components/mdx/Intro'
import { rehypeLink } from '@/components/mdx/Link/rehypeLink'
import { Keypoints, KeypointsItem } from '@/components/mdx/Keypoints'
import { Keypoints, KeypointsItem } from '@/registry/keypoints/keypoints'
import { Mermaid } from '@/components/mdx/Mermaid'
import { rehypeMermaid } from '@/components/mdx/Mermaid/rehypeMermaid'
import { Backers, Contributors } from '@/components/mdx/People'
Expand Down
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
],
"paths": {
"@/*": ["./*"],
"@/package.json": ["../package.json"]
"@/package.json": ["../package.json"],
// Registry items sit at the repo root, outside `src`, where `shadcn` looks for them.
"@/registry/*": ["../registry/*"]
}
},
"include": [
Expand Down
1 change: 1 addition & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default defineConfig({
// Mirrors the tsconfig `paths`. Must come before the `@` prefix alias, which
// would otherwise resolve this to src/package.json and fail to import ./route.
'@/package.json': path.resolve(__dirname, './package.json'),
'@/registry': path.resolve(__dirname, './registry'),
'@': path.resolve(__dirname, './src'),
},
},
Expand Down
Loading