mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-02-09 02:49:29 +08:00
feat: refactor component preview
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
|
||||
export function ComponentPreviewTabs({
|
||||
className,
|
||||
@@ -13,6 +13,7 @@ export function ComponentPreviewTabs({
|
||||
chromeLessOnMobile = false,
|
||||
component,
|
||||
source,
|
||||
sourcePreview,
|
||||
...props
|
||||
}: React.ComponentProps<"div"> & {
|
||||
previewClassName?: string
|
||||
@@ -21,11 +22,13 @@ export function ComponentPreviewTabs({
|
||||
chromeLessOnMobile?: boolean
|
||||
component: React.ReactNode
|
||||
source: React.ReactNode
|
||||
sourcePreview?: React.ReactNode
|
||||
}) {
|
||||
const [isMobileCodeVisible, setIsMobileCodeVisible] = React.useState(false)
|
||||
|
||||
return (
|
||||
<div
|
||||
data-slot="component-preview"
|
||||
className={cn(
|
||||
"group relative mt-4 mb-12 flex flex-col gap-2 overflow-hidden rounded-xl border",
|
||||
className
|
||||
@@ -47,33 +50,33 @@ export function ComponentPreviewTabs({
|
||||
<div
|
||||
data-slot="code"
|
||||
data-mobile-code-visible={isMobileCodeVisible}
|
||||
className="relative overflow-hidden data-[mobile-code-visible=false]:max-h-24 [&_[data-rehype-pretty-code-figure]]:!m-0 [&_[data-rehype-pretty-code-figure]]:rounded-t-none [&_[data-rehype-pretty-code-figure]]:border-t [&_pre]:max-h-72"
|
||||
style={{
|
||||
contentVisibility: "auto",
|
||||
containIntrinsicSize: "auto 96px",
|
||||
}}
|
||||
className="relative overflow-hidden [&_[data-rehype-pretty-code-figure]]:!m-0 [&_[data-rehype-pretty-code-figure]]:rounded-t-none [&_[data-rehype-pretty-code-figure]]:border-t [&_pre]:max-h-72"
|
||||
>
|
||||
{source}
|
||||
{!isMobileCodeVisible && (
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(to top, var(--color-code), color-mix(in oklab, var(--color-code) 60%, transparent), transparent)",
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="bg-background text-foreground dark:bg-background dark:text-foreground relative z-10"
|
||||
onClick={() => {
|
||||
setIsMobileCodeVisible(true)
|
||||
}}
|
||||
>
|
||||
View Code
|
||||
</Button>
|
||||
{isMobileCodeVisible ? (
|
||||
source
|
||||
) : (
|
||||
<div className="relative">
|
||||
{sourcePreview}
|
||||
<div className="absolute inset-0 flex items-center justify-center pb-4">
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(to top, var(--color-code), color-mix(in oklab, var(--color-code) 60%, transparent), transparent)",
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="bg-background text-foreground dark:bg-background dark:text-foreground hover:bg-muted dark:hover:bg-muted relative z-10"
|
||||
onClick={() => {
|
||||
setIsMobileCodeVisible(true)
|
||||
}}
|
||||
>
|
||||
View Code
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -77,6 +77,14 @@ export function ComponentPreview({
|
||||
styleName={styleName}
|
||||
/>
|
||||
}
|
||||
sourcePreview={
|
||||
<ComponentSource
|
||||
name={name}
|
||||
collapsible={false}
|
||||
styleName={styleName}
|
||||
maxLines={3}
|
||||
/>
|
||||
}
|
||||
chromeLessOnMobile={chromeLessOnMobile}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@@ -18,6 +18,7 @@ export async function ComponentSource({
|
||||
collapsible = true,
|
||||
className,
|
||||
styleName = "new-york-v4",
|
||||
maxLines,
|
||||
}: React.ComponentProps<"div"> & {
|
||||
name?: string
|
||||
src?: string
|
||||
@@ -25,6 +26,7 @@ export async function ComponentSource({
|
||||
language?: string
|
||||
collapsible?: boolean
|
||||
styleName?: string
|
||||
maxLines?: number
|
||||
}) {
|
||||
if (!name && !src) {
|
||||
return null
|
||||
@@ -51,6 +53,11 @@ export async function ComponentSource({
|
||||
code = await formatCode(code, styleName)
|
||||
code = code.replaceAll("/* eslint-disable react/no-children-prop */\n", "")
|
||||
|
||||
// Truncate code if maxLines is set.
|
||||
if (maxLines) {
|
||||
code = code.split("\n").slice(0, maxLines).join("\n")
|
||||
}
|
||||
|
||||
const lang = language ?? title?.split(".").pop() ?? "tsx"
|
||||
const highlightedCode = await highlightCode(code, lang)
|
||||
|
||||
|
||||
@@ -34,21 +34,21 @@ Here's what it looks like:
|
||||
|
||||
<ComponentPreview
|
||||
name="spinner-basic"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
|
||||
/>
|
||||
|
||||
Here's what it looks like in a button:
|
||||
|
||||
<ComponentPreview
|
||||
name="spinner-button"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
|
||||
/>
|
||||
|
||||
You can edit the code and replace it with your own spinner.
|
||||
|
||||
<ComponentPreview
|
||||
name="spinner-custom"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
|
||||
/>
|
||||
|
||||
### Kbd
|
||||
@@ -74,7 +74,7 @@ Use `KbdGroup` to group keyboard keys together.
|
||||
|
||||
<ComponentPreview
|
||||
name="kbd-demo"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
|
||||
/>
|
||||
|
||||
You can add it to buttons, tooltips, input groups, and more.
|
||||
@@ -85,7 +85,7 @@ I got a lot of requests for this one: Button Group. It's a container that groups
|
||||
|
||||
<ComponentPreview
|
||||
name="button-group-demo"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
|
||||
/>
|
||||
|
||||
Here's the code:
|
||||
@@ -120,14 +120,14 @@ Use `ButtonGroupSeparator` to create split buttons. Classic dropdown pattern.
|
||||
|
||||
<ComponentPreview
|
||||
name="button-group-dropdown"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
|
||||
/>
|
||||
|
||||
You can also use it to add prefix or suffix buttons and text to inputs.
|
||||
|
||||
<ComponentPreview
|
||||
name="button-group-select"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/examples/base/ui/avatar"
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
||||
Reference in New Issue
Block a user