feat: update preview for mobile

This commit is contained in:
shadcn
2024-10-17 16:28:09 +04:00
parent 9ec433838f
commit 0e6b37e99a
84 changed files with 674 additions and 45 deletions

View File

@@ -43,9 +43,6 @@ export default function BlocksLayout({
</PageActions>
</PageHeader>
<section id="blocks" className="scroll-mt-24">
<div className="px-4 py-8 text-center text-sm text-red-600 md:hidden">
Note: The blocks preview does not work on mobile yet.
</div>
{children}
</section>
</div>

View File

@@ -17,7 +17,7 @@ export default async function BlocksPage() {
return (
<div className="gap-3 md:flex md:flex-row-reverse md:items-start">
<div className="grid flex-1 gap-24 lg:gap-48">
<div className="grid flex-1 gap-12 md:gap-24 lg:gap-48">
{blocks.map((name, index) => (
<React.Suspense key={`${name}-${index}`}>
<BlockDisplay name={name} />

View File

@@ -1,6 +1,7 @@
"use client"
import * as React from "react"
import Image from "next/image"
import { ImperativePanelHandle } from "react-resizable-panels"
import { BlockToolbar } from "@/components/block-toolbar"
@@ -32,14 +33,29 @@ export function BlockPreview({
<ResizablePanelGroup direction="horizontal" className="relative z-10">
<ResizablePanel
ref={ref}
className="relative rounded-lg border bg-background"
className="relative aspect-[4/2.5] md:aspect-auto rounded-lg border bg-background"
defaultSize={100}
minSize={30}
>
<Image
src={`/images/blocks/${block.name}.png`}
alt={block.name}
data-block={block.name}
width={1440}
height={900}
className="bg-background absolute top-0 left-0 w-[970px] sm:w-[1280px] z-20 max-w-none dark:hidden md:dark:hidden md:hidden data-[block=sidebar-10]:right-0 data-[block=sidebar-10]:left-auto data-[block=sidebar-11]:-top-1/2 data-[block=sidebar-13]:max-w-full data-[block=sidebar-14]:right-0 data-[block=sidebar-14]:left-auto data-[block=sidebar-15]:max-w-full data-[block=login-01]:max-w-full"
/>
<Image
src={`/images/blocks/${block.name}-dark.png`}
alt={block.name}
width={1440}
height={900}
className="bg-background z-20 hidden dark:block md:dark:hidden md:hidden"
/>
<iframe
src={`/blocks/${block.style}/${block.name}`}
height={block.container?.height ?? 450}
className="chunk-mode relative z-20 w-full bg-background"
className="chunk-mode relative hidden md:block z-20 w-full bg-background"
/>
</ResizablePanel>
<ResizableHandle className="relative hidden w-3 bg-transparent p-0 after:absolute after:right-0 after:top-1/2 after:h-8 after:w-[6px] after:-translate-y-1/2 after:translate-x-[-1px] after:rounded-full after:bg-border after:transition-all after:hover:h-10 sm:block" />

View File

@@ -32,11 +32,11 @@ export function BlockToolbar({
const { copyToClipboard, isCopied } = useCopyToClipboard()
return (
<div className="flex items-center gap-4">
<Button asChild variant="link">
<div className="flex items-center gap-2 md:gap-4">
<Button asChild variant="link" className="px-1 whitespace-normal md:px-2">
<a href={`#${block.name}`}>{block.description}</a>
</Button>
<div className="ml-auto flex items-center gap-2 md:pr-[14px]">
<div className="ml-auto hidden md:flex items-center gap-2 md:pr-[14px]">
<Button
variant="ghost"
className="h-7 rounded-md border bg-muted shadow-none"

View File

@@ -1,6 +1,7 @@
"use client"
import * as React from "react"
import Image from "next/image"
import { Index } from "@/__registry__"
import { cn } from "@/lib/utils"
@@ -78,7 +79,21 @@ export function ComponentPreview({
if (type === "block") {
return (
<div className="relative aspect-[4/2.5] w-full overflow-hidden rounded-md border">
<div className="absolute inset-0 w-[1600px] bg-background">
<Image
src={`/images/blocks/${name}.png`}
alt={name}
width={1440}
height={900}
className="absolute top-0 left-0 w-[970px] sm:w-[1280px] bg-background z-20 max-w-none md:hidden dark:hidden md:dark:hidden"
/>
<Image
src={`/images/blocks/${name}-dark.png`}
alt={name}
width={1440}
height={900}
className="absolute top-0 hidden dark:block left-0 w-[970px] sm:w-[1280px] bg-background z-20 max-w-none md:hidden md:dark:hidden"
/>
<div className="absolute hidden md:block inset-0 w-[1600px] bg-background">
<iframe
src={`/blocks/${config.style}/${name}`}
className="size-full"

View File

@@ -2,7 +2,10 @@ export function TailwindIndicator() {
if (process.env.NODE_ENV === "production") return null
return (
<div className="fixed bottom-1 left-1 z-50 flex h-6 w-6 items-center justify-center rounded-full bg-gray-800 p-3 font-mono text-xs text-white">
<div
data-tailwind-indicator=""
className="fixed bottom-1 left-1 z-50 flex h-6 w-6 items-center justify-center rounded-full bg-gray-800 p-3 font-mono text-xs text-white"
>
<div className="block sm:hidden">xs</div>
<div className="hidden sm:block md:hidden">sm</div>
<div className="hidden md:block lg:hidden">md</div>

View File

@@ -108,8 +108,8 @@ We'll go over the colors later in the [theming section](/docs/components/sidebar
.dark {
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 0 0% 98%;
--sidebar-primary-foreground: 240 5.9% 10%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
@@ -152,8 +152,8 @@ We'll go over the colors later in the [theming section](/docs/components/sidebar
.dark {
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 0 0% 98%;
--sidebar-primary-foreground: 240 5.9% 10%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;

View File

@@ -7,6 +7,7 @@
"dev": "next dev -p 3333",
"build": "contentlayer2 build && pnpm build:registry && next build",
"build:registry": "tsx --tsconfig ./tsconfig.scripts.json ./scripts/build-registry.mts && prettier --loglevel silent --write \"registry/**/*.{ts,tsx,mdx}\" --cache",
"registry:capture": "tsx --tsconfig ./tsconfig.scripts.json ./scripts/capture-screenshots.mts",
"build:docs": "contentlayer2 build",
"seed:tasks": "tsx --tsconfig ./tsconfig.scripts.json ./app/(app)/examples/tasks/data/seed.ts",
"start": "next start -p 3333",

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

View File

@@ -555,8 +555,8 @@
"dark": {
"sidebar-background": "240 5.9% 10%",
"sidebar-foreground": "240 4.8% 95.9%",
"sidebar-primary": "0 0% 98%",
"sidebar-primary-foreground": "240 5.9% 10%",
"sidebar-primary": "224.3 76.3% 48%",
"sidebar-primary-foreground": "0 0% 100%",
"sidebar-accent": "240 3.7% 15.9%",
"sidebar-accent-foreground": "240 4.8% 95.9%",
"sidebar-border": "240 3.7% 15.9%",

View File

@@ -7,7 +7,7 @@
"files": [
{
"path": "ui/breadcrumb.tsx",
"content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<\"nav\"> & {\n separator?: React.ReactNode\n }\n>(({ ...props }, ref) => <nav ref={ref} aria-label=\"breadcrumb\" {...props} />)\nBreadcrumb.displayName = \"Breadcrumb\"\n\nconst BreadcrumbList = React.forwardRef<\n HTMLOListElement,\n React.ComponentPropsWithoutRef<\"ol\">\n>(({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5\",\n className\n )}\n {...props}\n />\n))\nBreadcrumbList.displayName = \"BreadcrumbList\"\n\nconst BreadcrumbItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<\"li\">\n>(({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn(\"inline-flex items-center gap-1.5\", className)}\n {...props}\n />\n))\nBreadcrumbItem.displayName = \"BreadcrumbItem\"\n\nconst BreadcrumbLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentPropsWithoutRef<\"a\"> & {\n asChild?: boolean\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n ref={ref}\n className={cn(\"transition-colors hover:text-foreground\", className)}\n {...props}\n />\n )\n})\nBreadcrumbLink.displayName = \"BreadcrumbLink\"\n\nconst BreadcrumbPage = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<\"span\">\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"font-normal text-foreground\", className)}\n {...props}\n />\n))\nBreadcrumbPage.displayName = \"BreadcrumbPage\"\n\nconst BreadcrumbSeparator = ({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:w-3.5 h-3.5\", className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n)\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\"\n\nconst BreadcrumbEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n)\nBreadcrumbEllipsis.displayName = \"BreadcrumbElipssis\"\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n}\n",
"content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<\"nav\"> & {\n separator?: React.ReactNode\n }\n>(({ ...props }, ref) => <nav ref={ref} aria-label=\"breadcrumb\" {...props} />)\nBreadcrumb.displayName = \"Breadcrumb\"\n\nconst BreadcrumbList = React.forwardRef<\n HTMLOListElement,\n React.ComponentPropsWithoutRef<\"ol\">\n>(({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5\",\n className\n )}\n {...props}\n />\n))\nBreadcrumbList.displayName = \"BreadcrumbList\"\n\nconst BreadcrumbItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<\"li\">\n>(({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn(\"inline-flex items-center gap-1.5\", className)}\n {...props}\n />\n))\nBreadcrumbItem.displayName = \"BreadcrumbItem\"\n\nconst BreadcrumbLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentPropsWithoutRef<\"a\"> & {\n asChild?: boolean\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n ref={ref}\n className={cn(\"transition-colors hover:text-foreground\", className)}\n {...props}\n />\n )\n})\nBreadcrumbLink.displayName = \"BreadcrumbLink\"\n\nconst BreadcrumbPage = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<\"span\">\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"font-normal text-foreground\", className)}\n {...props}\n />\n))\nBreadcrumbPage.displayName = \"BreadcrumbPage\"\n\nconst BreadcrumbSeparator = ({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:w-3.5 [&>svg]:h-3.5\", className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n)\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\"\n\nconst BreadcrumbEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n)\nBreadcrumbEllipsis.displayName = \"BreadcrumbElipssis\"\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n}\n",
"type": "registry:ui",
"target": "components/ui/breadcrumb.tsx"
}

View File

@@ -68,7 +68,7 @@
},
{
"path": "block/sidebar-15/components/sidebar-right.tsx",
"content": "import * as React from \"react\"\nimport { Plus } from \"lucide-react\"\n\nimport { Calendars } from \"@/components/calendars\"\nimport { DatePicker } from \"@/components/date-picker\"\nimport { NavUser } from \"@/components/nav-user\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarRail,\n SidebarSeparator,\n} from \"@/components/ui/sidebar\"\n\n// This is sample data.\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"/avatars/shadcn.jpg\",\n },\n calendars: [\n {\n name: \"My Calendars\",\n items: [\"Personal\", \"Work\", \"Family\"],\n },\n {\n name: \"Favorites\",\n items: [\"Holidays\", \"Birthdays\"],\n },\n {\n name: \"Other\",\n items: [\"Travel\", \"Reminders\", \"Deadlines\"],\n },\n ],\n}\n\nexport function SidebarRight({\n ...props\n}: React.ComponentProps<typeof Sidebar>) {\n return (\n <Sidebar\n collapsible=\"none\"\n className=\"sticky hidden lg:flex top-0 h-svh border-l\"\n {...props}\n >\n <SidebarHeader className=\"h-16 border-b border-sidebar-border\">\n <NavUser user={data.user} />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator className=\"mx-0\" />\n <Calendars calendars={data.calendars} />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n )\n}\n",
"content": "import * as React from \"react\"\nimport { Plus } from \"lucide-react\"\n\nimport { Calendars } from \"@/components/calendars\"\nimport { DatePicker } from \"@/components/date-picker\"\nimport { NavUser } from \"@/components/nav-user\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarRail,\n SidebarSeparator,\n} from \"@/components/ui/sidebar\"\n\n// This is sample data.\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"/avatars/shadcn.jpg\",\n },\n calendars: [\n {\n name: \"My Calendars\",\n items: [\"Personal\", \"Work\", \"Family\"],\n },\n {\n name: \"Favorites\",\n items: [\"Holidays\", \"Birthdays\"],\n },\n {\n name: \"Other\",\n items: [\"Travel\", \"Reminders\", \"Deadlines\"],\n },\n ],\n}\n\nexport function SidebarRight({\n ...props\n}: React.ComponentProps<typeof Sidebar>) {\n return (\n <Sidebar\n collapsible=\"none\"\n className=\"sticky hidden lg:flex top-0 h-svh border-l\"\n {...props}\n >\n <SidebarHeader className=\"h-16 border-b border-sidebar-border\">\n <NavUser user={data.user} />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator className=\"mx-0\" />\n <Calendars calendars={data.calendars} />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </Sidebar>\n )\n}\n",
"type": "registry:component",
"target": "components/sidebar-right.tsx"
},

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@
"files": [
{
"path": "ui/breadcrumb.tsx",
"content": "import * as React from \"react\"\nimport { ChevronRightIcon, DotsHorizontalIcon } from \"@radix-ui/react-icons\"\nimport { Slot } from \"@radix-ui/react-slot\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<\"nav\"> & {\n separator?: React.ReactNode\n }\n>(({ ...props }, ref) => <nav ref={ref} aria-label=\"breadcrumb\" {...props} />)\nBreadcrumb.displayName = \"Breadcrumb\"\n\nconst BreadcrumbList = React.forwardRef<\n HTMLOListElement,\n React.ComponentPropsWithoutRef<\"ol\">\n>(({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5\",\n className\n )}\n {...props}\n />\n))\nBreadcrumbList.displayName = \"BreadcrumbList\"\n\nconst BreadcrumbItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<\"li\">\n>(({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn(\"inline-flex items-center gap-1.5\", className)}\n {...props}\n />\n))\nBreadcrumbItem.displayName = \"BreadcrumbItem\"\n\nconst BreadcrumbLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentPropsWithoutRef<\"a\"> & {\n asChild?: boolean\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n ref={ref}\n className={cn(\"transition-colors hover:text-foreground\", className)}\n {...props}\n />\n )\n})\nBreadcrumbLink.displayName = \"BreadcrumbLink\"\n\nconst BreadcrumbPage = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<\"span\">\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"font-normal text-foreground\", className)}\n {...props}\n />\n))\nBreadcrumbPage.displayName = \"BreadcrumbPage\"\n\nconst BreadcrumbSeparator = ({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:w-3.5 h-3.5\", className)}\n {...props}\n >\n {children ?? <ChevronRightIcon />}\n </li>\n)\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\"\n\nconst BreadcrumbEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <DotsHorizontalIcon className=\"h-4 w-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n)\nBreadcrumbEllipsis.displayName = \"BreadcrumbElipssis\"\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n}\n",
"content": "import * as React from \"react\"\nimport { ChevronRightIcon, DotsHorizontalIcon } from \"@radix-ui/react-icons\"\nimport { Slot } from \"@radix-ui/react-slot\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<\"nav\"> & {\n separator?: React.ReactNode\n }\n>(({ ...props }, ref) => <nav ref={ref} aria-label=\"breadcrumb\" {...props} />)\nBreadcrumb.displayName = \"Breadcrumb\"\n\nconst BreadcrumbList = React.forwardRef<\n HTMLOListElement,\n React.ComponentPropsWithoutRef<\"ol\">\n>(({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5\",\n className\n )}\n {...props}\n />\n))\nBreadcrumbList.displayName = \"BreadcrumbList\"\n\nconst BreadcrumbItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<\"li\">\n>(({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn(\"inline-flex items-center gap-1.5\", className)}\n {...props}\n />\n))\nBreadcrumbItem.displayName = \"BreadcrumbItem\"\n\nconst BreadcrumbLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentPropsWithoutRef<\"a\"> & {\n asChild?: boolean\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n ref={ref}\n className={cn(\"transition-colors hover:text-foreground\", className)}\n {...props}\n />\n )\n})\nBreadcrumbLink.displayName = \"BreadcrumbLink\"\n\nconst BreadcrumbPage = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<\"span\">\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"font-normal text-foreground\", className)}\n {...props}\n />\n))\nBreadcrumbPage.displayName = \"BreadcrumbPage\"\n\nconst BreadcrumbSeparator = ({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:w-3.5 [&>svg]:h-3.5\", className)}\n {...props}\n >\n {children ?? <ChevronRightIcon />}\n </li>\n)\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\"\n\nconst BreadcrumbEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <DotsHorizontalIcon className=\"h-4 w-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n)\nBreadcrumbEllipsis.displayName = \"BreadcrumbElipssis\"\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n}\n",
"type": "registry:ui",
"target": "components/ui/breadcrumb.tsx"
}

View File

@@ -68,7 +68,7 @@
},
{
"path": "block/sidebar-15/components/sidebar-right.tsx",
"content": "import * as React from \"react\"\nimport { Plus } from \"lucide-react\"\n\nimport { Calendars } from \"@/components/calendars\"\nimport { DatePicker } from \"@/components/date-picker\"\nimport { NavUser } from \"@/components/nav-user\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarRail,\n SidebarSeparator,\n} from \"@/components/ui/sidebar\"\n\n// This is sample data.\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"/avatars/shadcn.jpg\",\n },\n calendars: [\n {\n name: \"My Calendars\",\n items: [\"Personal\", \"Work\", \"Family\"],\n },\n {\n name: \"Favorites\",\n items: [\"Holidays\", \"Birthdays\"],\n },\n {\n name: \"Other\",\n items: [\"Travel\", \"Reminders\", \"Deadlines\"],\n },\n ],\n}\n\nexport function SidebarRight({\n ...props\n}: React.ComponentProps<typeof Sidebar>) {\n return (\n <Sidebar\n collapsible=\"none\"\n className=\"sticky hidden lg:flex top-0 h-svh border-l\"\n {...props}\n >\n <SidebarHeader className=\"h-16 border-b border-sidebar-border\">\n <NavUser user={data.user} />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator className=\"mx-0\" />\n <Calendars calendars={data.calendars} />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n )\n}\n",
"content": "import * as React from \"react\"\nimport { Plus } from \"lucide-react\"\n\nimport { Calendars } from \"@/components/calendars\"\nimport { DatePicker } from \"@/components/date-picker\"\nimport { NavUser } from \"@/components/nav-user\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarRail,\n SidebarSeparator,\n} from \"@/components/ui/sidebar\"\n\n// This is sample data.\nconst data = {\n user: {\n name: \"shadcn\",\n email: \"m@example.com\",\n avatar: \"/avatars/shadcn.jpg\",\n },\n calendars: [\n {\n name: \"My Calendars\",\n items: [\"Personal\", \"Work\", \"Family\"],\n },\n {\n name: \"Favorites\",\n items: [\"Holidays\", \"Birthdays\"],\n },\n {\n name: \"Other\",\n items: [\"Travel\", \"Reminders\", \"Deadlines\"],\n },\n ],\n}\n\nexport function SidebarRight({\n ...props\n}: React.ComponentProps<typeof Sidebar>) {\n return (\n <Sidebar\n collapsible=\"none\"\n className=\"sticky hidden lg:flex top-0 h-svh border-l\"\n {...props}\n >\n <SidebarHeader className=\"h-16 border-b border-sidebar-border\">\n <NavUser user={data.user} />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator className=\"mx-0\" />\n <Calendars calendars={data.calendars} />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </Sidebar>\n )\n}\n",
"type": "registry:component",
"target": "components/sidebar-right.tsx"
},

File diff suppressed because one or more lines are too long

View File

@@ -66,7 +66,6 @@ export function SidebarRight({
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
<SidebarRail />
</Sidebar>
)
}

View File

@@ -80,7 +80,7 @@ const BreadcrumbSeparator = ({
<li
role="presentation"
aria-hidden="true"
className={cn("[&>svg]:w-3.5 h-3.5", className)}
className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5", className)}
{...props}
>
{children ?? <ChevronRight />}

View File

@@ -581,9 +581,12 @@ const SidebarMenuButton = React.forwardRef<
return (
<Tooltip>
<TooltipTrigger asChild>{button}</TooltipTrigger>
{state !== "collapsed" || isMobile ? null : (
<TooltipContent side="right" align="center" {...tooltip} />
)}
<TooltipContent
side="right"
align="center"
hidden={state !== "collapsed" || isMobile}
{...tooltip}
/>
</Tooltip>
)
}
@@ -754,8 +757,8 @@ export {
SidebarMenuSubButton,
SidebarMenuSubItem,
SidebarProvider,
SidebarRail,
SidebarSeparator,
SidebarTrigger,
SidebarRail,
useSidebar,
}

View File

@@ -66,7 +66,6 @@ export function SidebarRight({
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
<SidebarRail />
</Sidebar>
)
}

View File

@@ -80,7 +80,7 @@ const BreadcrumbSeparator = ({
<li
role="presentation"
aria-hidden="true"
className={cn("[&>svg]:w-3.5 h-3.5", className)}
className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5", className)}
{...props}
>
{children ?? <ChevronRightIcon />}

View File

@@ -581,9 +581,12 @@ const SidebarMenuButton = React.forwardRef<
return (
<Tooltip>
<TooltipTrigger asChild>{button}</TooltipTrigger>
{state !== "collapsed" || isMobile ? null : (
<TooltipContent side="right" align="center" {...tooltip} />
)}
<TooltipContent
side="right"
align="center"
hidden={state !== "collapsed" || isMobile}
{...tooltip}
/>
</Tooltip>
)
}
@@ -754,8 +757,8 @@ export {
SidebarMenuSubButton,
SidebarMenuSubItem,
SidebarProvider,
SidebarRail,
SidebarSeparator,
SidebarTrigger,
SidebarRail,
useSidebar,
}

View File

@@ -293,8 +293,8 @@ export const ui: Registry = [
dark: {
"sidebar-background": "240 5.9% 10%",
"sidebar-foreground": "240 4.8% 95.9%",
"sidebar-primary": "0 0% 98%",
"sidebar-primary-foreground": "240 5.9% 10%",
"sidebar-primary": "224.3 76.3% 48%",
"sidebar-primary-foreground": "0 0% 100%",
"sidebar-accent": "240 3.7% 15.9%",
"sidebar-accent-foreground": "240 4.8% 95.9%",
"sidebar-border": "240 3.7% 15.9%",

View File

@@ -0,0 +1,100 @@
import puppeteer from "puppeteer"
const BLOCKS = [
"login-01",
"sidebar-01",
"sidebar-02",
"sidebar-03",
"sidebar-04",
"sidebar-05",
"sidebar-06",
"sidebar-07",
"sidebar-08",
"sidebar-09",
"sidebar-10",
"sidebar-11",
"sidebar-12",
"sidebar-13",
"sidebar-14",
"sidebar-15",
"demo-sidebar",
"demo-sidebar-header",
"demo-sidebar-footer",
"demo-sidebar-group",
"demo-sidebar-group-collapsible",
"demo-sidebar-group-action",
"demo-sidebar-menu",
"demo-sidebar-menu-action",
"demo-sidebar-menu-sub",
"demo-sidebar-menu-collapsible",
"demo-sidebar-menu-badge",
"demo-sidebar-rsc",
"demo-sidebar-controlled",
]
try {
const browser = await puppeteer.launch({
defaultViewport: {
width: 1440,
height: 900,
deviceScaleFactor: 2,
},
})
console.log("☀️ Capturing screenshots for light theme")
for (const block of BLOCKS) {
const pageUrl = `http://localhost:3333/blocks/new-york/${block}`
console.log(`- ${block}`)
const page = await browser.newPage()
await page.goto(pageUrl, {
waitUntil: "networkidle2",
})
// Hide Tailwind indicator
await page.evaluate(() => {
const indicator = document.querySelector("[data-tailwind-indicator]")
if (indicator) {
indicator.remove()
}
})
await page.screenshot({
path: `./public/images/blocks/${block}.png`,
})
}
console.log("🌙 Capturing screenshots for dark theme")
for (const block of BLOCKS) {
const pageUrl = `http://localhost:3333/blocks/new-york/${block}`
console.log(`- ${block}`)
const page = await browser.newPage()
await page.goto(pageUrl, {
waitUntil: "networkidle2",
})
// Hide Tailwind indicator
await page.evaluate(() => {
const indicator = document.querySelector("[data-tailwind-indicator]")
if (indicator) {
indicator.remove()
}
})
// Set theme to dark
await page.evaluate(() => {
localStorage.setItem("theme", "dark")
})
await page.screenshot({
path: `./public/images/blocks/${block}-dark.png`,
})
}
await browser.close()
console.log("✅ Done!")
} catch (error) {
console.error(error)
process.exit(1)
}

View File

@@ -70,8 +70,8 @@
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 0 0% 98%;
--sidebar-primary-foreground: 240 5.9% 10%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;

View File

@@ -18,6 +18,7 @@
"build:cli": "turbo --filter=shadcn build",
"build:registry": "pnpm --filter=www build:registry && pnpm format:write -- --loglevel silent",
"registry:build": "pnpm --filter=www build:registry && pnpm format:write -- --loglevel silent",
"registry:capture": "pnpm --filter=www registry:capture",
"dev": "turbo run dev --parallel",
"cli:dev": "turbo --filter=shadcn-ui dev",
"cli:start": "pnpm --filter=shadcn-ui start:dev",
@@ -64,6 +65,7 @@
"postcss": "^8.4.24",
"prettier": "^2.8.8",
"pretty-quick": "^3.1.3",
"puppeteer": "^23.6.0",
"tailwindcss": "3.4.6",
"tailwindcss-animate": "^1.0.5",
"tsx": "^4.1.4",

495
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff