mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-29 23:55:02 +00:00
fix
This commit is contained in:
@@ -13,11 +13,12 @@ import z from "zod"
|
||||
import { source } from "@/lib/source"
|
||||
import { absoluteUrl } from "@/lib/utils"
|
||||
import { DocsBaseSwitcher } from "@/components/docs-base-switcher"
|
||||
import { DocsCopyPage } from "@/components/docs-copy-page"
|
||||
import { DocsPageLinks } from "@/components/docs-page-links"
|
||||
import { DocsTableOfContents } from "@/components/docs-toc"
|
||||
import { OpenInV0Cta } from "@/components/open-in-v0-cta"
|
||||
import { Badge } from "@/registry/new-york-v4/ui/badge"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Separator } from "@/registry/new-york-v4/ui/separator"
|
||||
|
||||
export const revalidate = false
|
||||
export const dynamic = "force-static"
|
||||
@@ -102,18 +103,26 @@ export default async function Page(props: {
|
||||
.parse(attributes)
|
||||
|
||||
return (
|
||||
<div className="flex items-stretch text-[1.05rem] sm:text-[15px] xl:w-full">
|
||||
<div className="flex scroll-mt-24 items-stretch text-[1.05rem] sm:text-[15px] xl:w-full">
|
||||
<div className="flex min-w-0 flex-1 flex-col">
|
||||
<div className="h-(--top-spacing) shrink-0" />
|
||||
<div className="h-(--top-spacing) shrink-0"></div>
|
||||
<div className="mx-auto flex w-full max-w-2xl min-w-0 flex-1 flex-col gap-8 px-4 py-6 text-neutral-800 md:px-0 lg:py-8 dark:text-neutral-300">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-start justify-between">
|
||||
<h1 className="scroll-m-20 text-4xl font-semibold tracking-tight sm:text-3xl xl:text-4xl">
|
||||
<h1 className="scroll-m-24 text-4xl font-semibold tracking-tight sm:text-3xl xl:text-4xl">
|
||||
{doc.title}
|
||||
</h1>
|
||||
<div className="docs-nav bg-background/80 border-border/50 fixed inset-x-0 bottom-0 isolate z-50 flex items-center gap-2 border-t px-6 py-4 backdrop-blur-sm sm:static sm:z-0 sm:border-t-0 sm:bg-transparent sm:px-0 sm:pt-1.5 sm:backdrop-blur-none">
|
||||
<DocsCopyPage page={raw} url={absoluteUrl(page.url)} />
|
||||
{params.slug &&
|
||||
params.slug[0] === "components" &&
|
||||
params.slug[1] &&
|
||||
params.slug[2] && (
|
||||
<DocsBaseSwitcher
|
||||
base={params.slug[1]}
|
||||
component={params.slug[2]}
|
||||
/>
|
||||
)}
|
||||
{neighbours.previous && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
@@ -168,10 +177,6 @@ export default async function Page(props: {
|
||||
) : null}
|
||||
</div>
|
||||
<div className="w-full flex-1 *:data-[slot=alert]:first:mt-0">
|
||||
<DocsBaseSwitcher
|
||||
base={params.slug[1]}
|
||||
component={params.slug[2]}
|
||||
/>
|
||||
<MDX components={mdxComponents} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,14 +208,17 @@ export default async function Page(props: {
|
||||
</div>
|
||||
</div>
|
||||
<div className="sticky top-[calc(var(--header-height)+1px)] z-30 ml-auto hidden h-[calc(100svh-var(--footer-height)+2rem)] w-72 flex-col gap-4 overflow-hidden overscroll-none pb-8 xl:flex">
|
||||
<div className="h-(--top-spacing) shrink-0" />
|
||||
<div className="h-(--top-spacing) shrink-0"></div>
|
||||
{doc.toc?.length ? (
|
||||
<div className="no-scrollbar overflow-y-auto px-8">
|
||||
<div className="no-scrollbar flex flex-1 flex-col gap-8 overflow-y-auto px-8">
|
||||
<DocsTableOfContents toc={doc.toc} />
|
||||
<div className="h-12" />
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex flex-1 flex-col gap-12 px-6">
|
||||
<div className="flex flex-1 flex-col gap-6 px-6">
|
||||
<div className="px-6">
|
||||
<Separator />
|
||||
</div>
|
||||
<DocsPageLinks page={raw} url={absoluteUrl(page.url)} />
|
||||
<OpenInV0Cta />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
import { type DialogProps } from "@radix-ui/react-dialog"
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||
import { IconArrowRight } from "@tabler/icons-react"
|
||||
import { useDocsSearch } from "fumadocs-core/search/client"
|
||||
import { CornerDownLeftIcon, SquareDashedIcon } from "lucide-react"
|
||||
import { CornerDownLeftIcon, SquareDashedIcon, XIcon } from "lucide-react"
|
||||
|
||||
import { type Color, type ColorPalette } from "@/lib/colors"
|
||||
import { trackEvent } from "@/lib/events"
|
||||
import { showMcpDocs } from "@/lib/flags"
|
||||
import { getCurrentBase, getPagesFromFolder } from "@/lib/page-tree"
|
||||
import { type source } from "@/lib/source"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
@@ -26,13 +28,13 @@ import {
|
||||
} from "@/registry/new-york-v4/ui/command"
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogPortal,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/registry/new-york-v4/ui/dialog"
|
||||
import { Kbd, KbdGroup } from "@/registry/new-york-v4/ui/kbd"
|
||||
import { Kbd } from "@/registry/new-york-v4/ui/kbd"
|
||||
import { Separator } from "@/registry/new-york-v4/ui/separator"
|
||||
import { Spinner } from "@/registry/new-york-v4/ui/spinner"
|
||||
|
||||
@@ -49,7 +51,9 @@ export function CommandMenu({
|
||||
navItems?: { href: string; label: string }[]
|
||||
}) {
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
const [config] = useConfig()
|
||||
const currentBase = getCurrentBase(pathname)
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const [selectedType, setSelectedType] = React.useState<
|
||||
"color" | "page" | "component" | "block" | null
|
||||
@@ -138,10 +142,13 @@ export function CommandMenu({
|
||||
[setSelectedType, setCopyPayload, packageManager]
|
||||
)
|
||||
|
||||
const runCommand = React.useCallback((command: () => unknown) => {
|
||||
setOpen(false)
|
||||
command()
|
||||
}, [])
|
||||
const runCommand = React.useCallback(
|
||||
(command: () => unknown) => {
|
||||
setOpen(false)
|
||||
command()
|
||||
},
|
||||
[setOpen]
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
@@ -207,10 +214,7 @@ export function CommandMenu({
|
||||
</div>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent
|
||||
showCloseButton={false}
|
||||
className="rounded-xl border-none bg-clip-padding p-2 pb-11 shadow-2xl ring-4 ring-neutral-200/80 dark:bg-neutral-900 dark:ring-neutral-800"
|
||||
>
|
||||
<DialogContent className="rounded-xl border-none bg-clip-padding p-2 pb-11 shadow-2xl ring-4 ring-neutral-200/80 dark:bg-neutral-900 dark:ring-neutral-800">
|
||||
<DialogHeader className="sr-only">
|
||||
<DialogTitle>Search documentation...</DialogTitle>
|
||||
<DialogDescription>Search for a command to run...</DialogDescription>
|
||||
@@ -269,40 +273,37 @@ export function CommandMenu({
|
||||
className="!p-0 [&_[cmdk-group-heading]]:scroll-mt-16 [&_[cmdk-group-heading]]:!p-3 [&_[cmdk-group-heading]]:!pb-1"
|
||||
>
|
||||
{group.type === "folder" &&
|
||||
group.children.map((item) => {
|
||||
if (item.type === "page") {
|
||||
const isComponent = item.url.includes("/components/")
|
||||
getPagesFromFolder(group, currentBase).map((item) => {
|
||||
const isComponent = item.url.includes("/components/")
|
||||
|
||||
if (!showMcpDocs && item.url.includes("/mcp")) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<CommandMenuItem
|
||||
key={item.url}
|
||||
value={
|
||||
item.name?.toString()
|
||||
? `${group.name} ${item.name}`
|
||||
: ""
|
||||
}
|
||||
keywords={isComponent ? ["component"] : undefined}
|
||||
onHighlight={() =>
|
||||
handlePageHighlight(isComponent, item)
|
||||
}
|
||||
onSelect={() => {
|
||||
runCommand(() => router.push(item.url))
|
||||
}}
|
||||
>
|
||||
{isComponent ? (
|
||||
<div className="border-muted-foreground aspect-square size-4 rounded-full border border-dashed" />
|
||||
) : (
|
||||
<IconArrowRight />
|
||||
)}
|
||||
{item.name}
|
||||
</CommandMenuItem>
|
||||
)
|
||||
if (!showMcpDocs && item.url.includes("/mcp")) {
|
||||
return null
|
||||
}
|
||||
return null
|
||||
|
||||
return (
|
||||
<CommandMenuItem
|
||||
key={item.url}
|
||||
value={
|
||||
item.name?.toString()
|
||||
? `${group.name} ${item.name}`
|
||||
: ""
|
||||
}
|
||||
keywords={isComponent ? ["component"] : undefined}
|
||||
onHighlight={() =>
|
||||
handlePageHighlight(isComponent, item)
|
||||
}
|
||||
onSelect={() => {
|
||||
runCommand(() => router.push(item.url))
|
||||
}}
|
||||
>
|
||||
{isComponent ? (
|
||||
<div className="border-muted-foreground aspect-square size-4 rounded-full border border-dashed" />
|
||||
) : (
|
||||
<IconArrowRight />
|
||||
)}
|
||||
{item.name}
|
||||
</CommandMenuItem>
|
||||
)
|
||||
})}
|
||||
</CommandGroup>
|
||||
))}
|
||||
@@ -523,3 +524,30 @@ function SearchResults({
|
||||
</CommandGroup>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogContent({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
||||
showCloseButton?: boolean
|
||||
}) {
|
||||
return (
|
||||
<DialogPortal data-slot="dialog-portal">
|
||||
<DialogPrimitive.Overlay
|
||||
data-slot="dialog-overlay"
|
||||
className="fixed inset-0 z-50 bg-black/50"
|
||||
/>
|
||||
<DialogPrimitive.Content
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,29 @@
|
||||
import * as React from "react"
|
||||
import Image from "next/image"
|
||||
|
||||
import { getRegistryComponent } from "@/lib/registry"
|
||||
import { ComponentPreviewTabs } from "@/components/component-preview-tabs"
|
||||
import { ComponentSource } from "@/components/component-source"
|
||||
|
||||
function DynamicComponent({
|
||||
name,
|
||||
styleName,
|
||||
}: {
|
||||
name: string
|
||||
styleName: string
|
||||
}) {
|
||||
const Component = React.useMemo(
|
||||
() => getRegistryComponent(name, styleName),
|
||||
[name, styleName]
|
||||
)
|
||||
|
||||
if (!Component) {
|
||||
return null
|
||||
}
|
||||
|
||||
return React.createElement(Component)
|
||||
}
|
||||
|
||||
export function ComponentPreview({
|
||||
name,
|
||||
styleName = "new-york-v4",
|
||||
@@ -65,7 +85,7 @@ export function ComponentPreview({
|
||||
className={className}
|
||||
align={align}
|
||||
hideCode={hideCode}
|
||||
component={<Component />}
|
||||
component={<DynamicComponent name={name} styleName={styleName} />}
|
||||
source={
|
||||
<ComponentSource
|
||||
name={name}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import Link from "next/link"
|
||||
|
||||
import { PAGES_NEW } from "@/lib/docs"
|
||||
import { source } from "@/lib/source"
|
||||
import { getPagesFromFolder, type PageTreeFolder } from "@/lib/page-tree"
|
||||
|
||||
export function ComponentsList() {
|
||||
const components = source.pageTree.children.find(
|
||||
(page) => page.$id === "components"
|
||||
)
|
||||
|
||||
if (components?.type !== "folder") {
|
||||
return
|
||||
}
|
||||
|
||||
const list = components.children.filter(
|
||||
(component) => component.type === "page"
|
||||
)
|
||||
export function ComponentsList({
|
||||
componentsFolder,
|
||||
currentBase,
|
||||
}: {
|
||||
componentsFolder: PageTreeFolder
|
||||
currentBase: string
|
||||
}) {
|
||||
const list = getPagesFromFolder(componentsFolder, currentBase)
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 md:gap-x-8 lg:gap-x-16 lg:gap-y-6 xl:gap-x-20">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Link from "next/link"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { BASES } from "@/registry/bases"
|
||||
|
||||
export function DocsBaseSwitcher({
|
||||
@@ -11,16 +10,20 @@ export function DocsBaseSwitcher({
|
||||
component: string
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="bg-muted inline-flex h-7 items-center gap-0.5 rounded-md p-0.5">
|
||||
{BASES.map((baseItem) => (
|
||||
<Link
|
||||
key={baseItem.name}
|
||||
href={`/docs/components/${baseItem.name}/${component}`}
|
||||
data-active={base === baseItem.name}
|
||||
className={cn(
|
||||
"text-muted-foreground data-[active=true]:text-foreground data-[active=true]:border-primary dark:data-[active=true]:border-primary hover:text-primary rounded-none border-0 border-b-2 border-transparent bg-transparent px-0 pb-1 text-base font-medium transition-colors data-[active=true]:bg-transparent data-[active=true]:shadow-none dark:data-[active=true]:bg-transparent"
|
||||
)}
|
||||
className="text-muted-foreground hover:text-foreground data-[active=true]:bg-background data-[active=true]:text-foreground inline-flex h-[--spacing(6.25)] items-center justify-center gap-1 rounded-sm pr-2.5 pl-2 text-sm font-medium data-[active=true]:shadow-sm"
|
||||
>
|
||||
{baseItem.meta?.logo && (
|
||||
<span
|
||||
className="size-3.5 shrink-0 [&>svg]:size-full"
|
||||
dangerouslySetInnerHTML={{ __html: baseItem.meta.logo }}
|
||||
/>
|
||||
)}
|
||||
{baseItem.title}
|
||||
</Link>
|
||||
))}
|
||||
|
||||
@@ -168,7 +168,7 @@ export function DocsCopyPage({ page, url }: { page: string; url: string }) {
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<div className="bg-secondary group/buttons relative flex rounded-lg *:[[data-slot=button]]:focus-visible:relative *:[[data-slot=button]]:focus-visible:z-10">
|
||||
<div className="bg-secondary group/buttons relative flex hidden rounded-lg *:[[data-slot=button]]:focus-visible:relative *:[[data-slot=button]]:focus-visible:z-10">
|
||||
<PopoverAnchor />
|
||||
<Button
|
||||
variant="secondary"
|
||||
|
||||
179
apps/v4/components/docs-page-links.tsx
Normal file
179
apps/v4/components/docs-page-links.tsx
Normal file
@@ -0,0 +1,179 @@
|
||||
"use client"
|
||||
|
||||
import { IconCheck, IconCopy } from "@tabler/icons-react"
|
||||
|
||||
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard"
|
||||
|
||||
function getPromptUrl(baseURL: string, url: string) {
|
||||
return `${baseURL}?q=${encodeURIComponent(
|
||||
`I'm looking at this shadcn/ui documentation: ${url}.
|
||||
Help me understand how to use it. Be ready to explain concepts, give examples, or help debug based on it.
|
||||
`
|
||||
)}`
|
||||
}
|
||||
|
||||
export function DocsPageLinks({ page, url }: { page: string; url: string }) {
|
||||
const { copyToClipboard, isCopied } = useCopyToClipboard()
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3 px-6">
|
||||
<ul className="text-muted-foreground flex flex-col gap-2 text-[0.8rem]">
|
||||
<li>
|
||||
<button
|
||||
onClick={() => copyToClipboard(page)}
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
{isCopied ? (
|
||||
<IconCheck className="size-4" />
|
||||
) : (
|
||||
<IconCopy className="size-4" />
|
||||
)}
|
||||
Copy page
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={`${url}.md`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg strokeLinejoin="round" viewBox="0 0 22 16" className="size-4">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M19.5 2.25H2.5C1.80964 2.25 1.25 2.80964 1.25 3.5V12.5C1.25 13.1904 1.80964 13.75 2.5 13.75H19.5C20.1904 13.75 20.75 13.1904 20.75 12.5V3.5C20.75 2.80964 20.1904 2.25 19.5 2.25ZM2.5 1C1.11929 1 0 2.11929 0 3.5V12.5C0 13.8807 1.11929 15 2.5 15H19.5C20.8807 15 22 13.8807 22 12.5V3.5C22 2.11929 20.8807 1 19.5 1H2.5ZM3 4.5H4H4.25H4.6899L4.98715 4.82428L7 7.02011L9.01285 4.82428L9.3101 4.5H9.75H10H11V5.5V11.5H9V7.79807L7.73715 9.17572L7 9.97989L6.26285 9.17572L5 7.79807V11.5H3V5.5V4.5ZM15 8V4.5H17V8H19.5L17 10.5L16 11.5L15 10.5L12.5 8H15Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
View as Markdown
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://v0.dev", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 147 70"
|
||||
className="size-4"
|
||||
>
|
||||
<path d="M56 50.203V14h14v46.156C70 65.593 65.593 70 60.156 70c-2.596 0-5.158-1-7-2.843L0 14h19.797L56 50.203ZM147 56h-14V23.953L100.953 56H133v14H96.687C85.814 70 77 61.186 77 50.312V14h14v32.156L123.156 14H91V0h36.312C138.186 0 147 8.814 147 19.688V56Z" />
|
||||
</svg>
|
||||
Open in v0
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://chatgpt.com", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
className="size-4"
|
||||
>
|
||||
<path
|
||||
d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681zm1.097-2.365 2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
Open in ChatGPT
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://claude.ai/new", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
className="size-4"
|
||||
>
|
||||
<path
|
||||
d="m4.714 15.956 4.718-2.648.079-.23-.08-.128h-.23l-.79-.048-2.695-.073-2.337-.097-2.265-.122-.57-.121-.535-.704.055-.353.48-.321.685.06 1.518.104 2.277.157 1.651.098 2.447.255h.389l.054-.158-.133-.097-.103-.098-2.356-1.596-2.55-1.688-1.336-.972-.722-.491L2 6.223l-.158-1.008.655-.722.88.06.225.061.893.686 1.906 1.476 2.49 1.833.364.304.146-.104.018-.072-.164-.274-1.354-2.446-1.445-2.49-.644-1.032-.17-.619a2.972 2.972 0 0 1-.103-.729L6.287.133 6.7 0l.995.134.42.364.619 1.415L9.735 4.14l1.555 3.03.455.898.243.832.09.255h.159V9.01l.127-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.583.28.48.685-.067.444-.286 1.851-.558 2.903-.365 1.942h.213l.243-.242.983-1.306 1.652-2.064.728-.82.85-.904.547-.431h1.032l.759 1.129-.34 1.166-1.063 1.347-.88 1.142-1.263 1.7-.79 1.36.074.11.188-.02 2.853-.606 1.542-.28 1.84-.315.832.388.09.395-.327.807-1.967.486-2.307.462-3.436.813-.043.03.049.061 1.548.146.662.036h1.62l3.018.225.79.522.473.638-.08.485-1.213.62-1.64-.389-3.825-.91-1.31-.329h-.183v.11l1.093 1.068 2.003 1.81 2.508 2.33.127.578-.321.455-.34-.049-2.204-1.657-.85-.747-1.925-1.62h-.127v.17l.443.649 2.343 3.521.122 1.08-.17.353-.607.213-.668-.122-1.372-1.924-1.415-2.168-1.141-1.943-.14.08-.674 7.254-.316.37-.728.28-.607-.461-.322-.747.322-1.476.388-1.924.316-1.53.285-1.9.17-.632-.012-.042-.14.018-1.432 1.967-2.18 2.945-1.724 1.845-.413.164-.716-.37.066-.662.401-.589 2.386-3.036 1.439-1.882.929-1.086-.006-.158h-.055L4.138 18.56l-1.13.146-.485-.456.06-.746.231-.243 1.907-1.312Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
Open in Claude
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://scira.ai/", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
width="910"
|
||||
height="934"
|
||||
viewBox="0 0 910 934"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="size-4"
|
||||
>
|
||||
<path
|
||||
d="M647.664 197.775C569.13 189.049 525.5 145.419 516.774 66.8849C508.048 145.419 464.418 189.049 385.884 197.775C464.418 206.501 508.048 250.131 516.774 328.665C525.5 250.131 569.13 206.501 647.664 197.775Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M516.774 304.217C510.299 275.491 498.208 252.087 480.335 234.214C462.462 216.341 439.058 204.251 410.333 197.775C439.059 191.3 462.462 179.209 480.335 161.336C498.208 143.463 510.299 120.06 516.774 91.334C523.25 120.059 535.34 143.463 553.213 161.336C571.086 179.209 594.49 191.3 623.216 197.775C594.49 204.251 571.086 216.341 553.213 234.214C535.34 252.087 523.25 275.491 516.774 304.217Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M857.5 508.116C763.259 497.644 710.903 445.288 700.432 351.047C689.961 445.288 637.605 497.644 543.364 508.116C637.605 518.587 689.961 570.943 700.432 665.184C710.903 570.943 763.259 518.587 857.5 508.116Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="20"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M700.432 615.957C691.848 589.05 678.575 566.357 660.383 548.165C642.191 529.973 619.499 516.7 592.593 508.116C619.499 499.533 642.191 486.258 660.383 468.066C678.575 449.874 691.848 427.181 700.432 400.274C709.015 427.181 722.289 449.874 740.481 468.066C758.673 486.258 781.365 499.533 808.271 508.116C781.365 516.7 758.673 529.973 740.481 548.165C722.289 566.357 709.015 589.05 700.432 615.957Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="20"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M889.949 121.237C831.049 114.692 798.326 81.9698 791.782 23.0692C785.237 81.9698 752.515 114.692 693.614 121.237C752.515 127.781 785.237 160.504 791.782 219.404C798.326 160.504 831.049 127.781 889.949 121.237Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M791.782 196.795C786.697 176.937 777.869 160.567 765.16 147.858C752.452 135.15 736.082 126.322 716.226 121.237C736.082 116.152 752.452 107.324 765.16 94.6152C777.869 81.9065 786.697 65.5368 791.782 45.6797C796.867 65.5367 805.695 81.9066 818.403 94.6152C831.112 107.324 847.481 116.152 867.338 121.237C847.481 126.322 831.112 135.15 818.403 147.858C805.694 160.567 796.867 176.937 791.782 196.795Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M760.632 764.337C720.719 814.616 669.835 855.1 611.872 882.692C553.91 910.285 490.404 924.255 426.213 923.533C362.022 922.812 298.846 907.419 241.518 878.531C184.19 849.643 134.228 808.026 95.4548 756.863C56.6815 705.7 30.1238 646.346 17.8129 583.343C5.50207 520.339 7.76433 455.354 24.4266 393.359C41.089 331.364 71.7099 274.001 113.947 225.658C156.184 177.315 208.919 139.273 268.117 114.442"
|
||||
stroke="currentColor"
|
||||
strokeWidth="30"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
Open in Scira
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { usePathname } from "next/navigation"
|
||||
|
||||
import { PAGES_NEW } from "@/lib/docs"
|
||||
import { showMcpDocs } from "@/lib/flags"
|
||||
import { getCurrentBase, getPagesFromFolder } from "@/lib/page-tree"
|
||||
import type { source } from "@/lib/source"
|
||||
import {
|
||||
Sidebar,
|
||||
@@ -17,10 +18,6 @@ import {
|
||||
SidebarMenuItem,
|
||||
} from "@/registry/new-york-v4/ui/sidebar"
|
||||
|
||||
type PageTreeNode = (typeof source.pageTree)["children"][number]
|
||||
type PageTreeFolder = Extract<PageTreeNode, { type: "folder" }>
|
||||
type PageTreePage = Extract<PageTreeNode, { type: "page" }>
|
||||
|
||||
const TOP_LEVEL_SECTIONS = [
|
||||
{ name: "Get Started", href: "/docs" },
|
||||
{
|
||||
@@ -47,66 +44,12 @@ const TOP_LEVEL_SECTIONS = [
|
||||
const EXCLUDED_SECTIONS = ["installation", "dark-mode"]
|
||||
const EXCLUDED_PAGES = ["/docs", "/docs/changelog"]
|
||||
|
||||
// Recursively find all pages in a folder tree.
|
||||
function getAllPagesFromFolder(folder: PageTreeFolder): PageTreePage[] {
|
||||
const pages: PageTreePage[] = []
|
||||
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "page") {
|
||||
pages.push(child)
|
||||
} else if (child.type === "folder") {
|
||||
pages.push(...getAllPagesFromFolder(child))
|
||||
}
|
||||
}
|
||||
|
||||
return pages
|
||||
}
|
||||
|
||||
// Get the pages from a folder, handling nested base folders (radix/base).
|
||||
function getPagesFromFolder(
|
||||
folder: PageTreeFolder,
|
||||
currentBase: string
|
||||
): PageTreePage[] {
|
||||
// For the components folder, find the base subfolder.
|
||||
if (folder.$id === "components" || folder.name === "Components") {
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "folder") {
|
||||
// Match by $id or by name.
|
||||
const isRadix = child.$id === "radix" || child.name === "Radix UI"
|
||||
const isBase = child.$id === "base" || child.name === "Base UI"
|
||||
|
||||
if (
|
||||
(currentBase === "radix" && isRadix) ||
|
||||
(currentBase === "base" && isBase)
|
||||
) {
|
||||
return child.children.filter(
|
||||
(c): c is PageTreePage => c.type === "page"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: return all pages from nested folders.
|
||||
return getAllPagesFromFolder(folder).filter(
|
||||
(page) => !page.url.endsWith("/components")
|
||||
)
|
||||
}
|
||||
|
||||
// For other folders, return direct page children.
|
||||
return folder.children.filter(
|
||||
(child): child is PageTreePage => child.type === "page"
|
||||
)
|
||||
}
|
||||
|
||||
export function DocsSidebar({
|
||||
tree,
|
||||
...props
|
||||
}: React.ComponentProps<typeof Sidebar> & { tree: typeof source.pageTree }) {
|
||||
const pathname = usePathname()
|
||||
|
||||
// Detect current base from URL (radix or base).
|
||||
const baseMatch = pathname.match(/\/docs\/components\/(radix|base)\//)
|
||||
const currentBase = baseMatch ? baseMatch[1] : "radix" // Default to radix.
|
||||
const currentBase = getCurrentBase(pathname)
|
||||
|
||||
return (
|
||||
<Sidebar
|
||||
|
||||
@@ -6,6 +6,7 @@ import { usePathname, useRouter } from "next/navigation"
|
||||
|
||||
import { PAGES_NEW } from "@/lib/docs"
|
||||
import { showMcpDocs } from "@/lib/flags"
|
||||
import { getCurrentBase, getPagesFromFolder } from "@/lib/page-tree"
|
||||
import { type source } from "@/lib/source"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
@@ -39,61 +40,6 @@ const TOP_LEVEL_SECTIONS = [
|
||||
},
|
||||
]
|
||||
|
||||
type PageTreeNode = (typeof source.pageTree)["children"][number]
|
||||
type PageTreeFolder = Extract<PageTreeNode, { type: "folder" }>
|
||||
type PageTreePage = Extract<PageTreeNode, { type: "page" }>
|
||||
|
||||
// Recursively find all pages in a folder tree.
|
||||
function getAllPagesFromFolder(folder: PageTreeFolder): PageTreePage[] {
|
||||
const pages: PageTreePage[] = []
|
||||
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "page") {
|
||||
pages.push(child)
|
||||
} else if (child.type === "folder") {
|
||||
pages.push(...getAllPagesFromFolder(child))
|
||||
}
|
||||
}
|
||||
|
||||
return pages
|
||||
}
|
||||
|
||||
// Get the pages from a folder, handling nested base folders (radix/base).
|
||||
function getPagesFromFolder(
|
||||
folder: PageTreeFolder,
|
||||
currentBase: string
|
||||
): PageTreePage[] {
|
||||
// For the components folder, find the base subfolder.
|
||||
if (folder.$id === "components" || folder.name === "Components") {
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "folder") {
|
||||
// Match by $id or by name.
|
||||
const isRadix = child.$id === "radix" || child.name === "Radix UI"
|
||||
const isBase = child.$id === "base" || child.name === "Base UI"
|
||||
|
||||
if (
|
||||
(currentBase === "radix" && isRadix) ||
|
||||
(currentBase === "base" && isBase)
|
||||
) {
|
||||
return child.children.filter(
|
||||
(c): c is PageTreePage => c.type === "page"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: return all pages from nested folders.
|
||||
return getAllPagesFromFolder(folder).filter(
|
||||
(page) => !page.url.endsWith("/components")
|
||||
)
|
||||
}
|
||||
|
||||
// For other folders, return direct page children.
|
||||
return folder.children.filter(
|
||||
(child): child is PageTreePage => child.type === "page"
|
||||
)
|
||||
}
|
||||
|
||||
export function MobileNav({
|
||||
tree,
|
||||
items,
|
||||
@@ -105,11 +51,7 @@ export function MobileNav({
|
||||
}) {
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const pathname = usePathname()
|
||||
|
||||
// Determine current base from pathname.
|
||||
const currentBase = pathname.includes("/docs/components/base/")
|
||||
? "base"
|
||||
: "radix"
|
||||
const currentBase = getCurrentBase(pathname)
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
|
||||
@@ -23,7 +23,7 @@ function PageHeaderHeading({
|
||||
return (
|
||||
<h1
|
||||
className={cn(
|
||||
"text-primary leading-tighter max-w-2xl text-4xl font-semibold tracking-tight text-balance lg:leading-[1.1] lg:font-semibold xl:text-5xl xl:tracking-tight",
|
||||
"text-primary leading-tighter max-w-2xl text-4xl font-semibold tracking-tighter text-balance lg:leading-[1.1] lg:font-semibold xl:text-5xl xl:tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
62
apps/v4/lib/page-tree.ts
Normal file
62
apps/v4/lib/page-tree.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import type { source } from "@/lib/source"
|
||||
|
||||
export type PageTreeNode = (typeof source.pageTree)["children"][number]
|
||||
export type PageTreeFolder = Extract<PageTreeNode, { type: "folder" }>
|
||||
export type PageTreePage = Extract<PageTreeNode, { type: "page" }>
|
||||
|
||||
// Recursively find all pages in a folder tree.
|
||||
export function getAllPagesFromFolder(folder: PageTreeFolder): PageTreePage[] {
|
||||
const pages: PageTreePage[] = []
|
||||
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "page") {
|
||||
pages.push(child)
|
||||
} else if (child.type === "folder") {
|
||||
pages.push(...getAllPagesFromFolder(child))
|
||||
}
|
||||
}
|
||||
|
||||
return pages
|
||||
}
|
||||
|
||||
// Get the pages from a folder, handling nested base folders (radix/base).
|
||||
export function getPagesFromFolder(
|
||||
folder: PageTreeFolder,
|
||||
currentBase: string
|
||||
): PageTreePage[] {
|
||||
// For the components folder, find the base subfolder.
|
||||
if (folder.$id === "components" || folder.name === "Components") {
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "folder") {
|
||||
// Match by $id or by name.
|
||||
const isRadix = child.$id === "radix" || child.name === "Radix UI"
|
||||
const isBase = child.$id === "base" || child.name === "Base UI"
|
||||
|
||||
if (
|
||||
(currentBase === "radix" && isRadix) ||
|
||||
(currentBase === "base" && isBase)
|
||||
) {
|
||||
return child.children.filter(
|
||||
(c): c is PageTreePage => c.type === "page"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: return all pages from nested folders.
|
||||
return getAllPagesFromFolder(folder).filter(
|
||||
(page) => !page.url.endsWith("/components")
|
||||
)
|
||||
}
|
||||
|
||||
// For other folders, return direct page children.
|
||||
return folder.children.filter(
|
||||
(child): child is PageTreePage => child.type === "page"
|
||||
)
|
||||
}
|
||||
|
||||
// Get current base (radix or base) from pathname.
|
||||
export function getCurrentBase(pathname: string): string {
|
||||
const baseMatch = pathname.match(/\/docs\/components\/(radix|base)\//)
|
||||
return baseMatch ? baseMatch[1] : "radix" // Default to radix.
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { Project, ScriptKind } from "ts-morph"
|
||||
import { u } from "unist-builder"
|
||||
import { visit } from "unist-util-visit"
|
||||
import { z } from "zod"
|
||||
import { type z } from "zod"
|
||||
|
||||
import { Index as StylesIndex } from "@/registry/__index__"
|
||||
import { getActiveStyle } from "@/registry/_legacy-styles"
|
||||
@@ -98,7 +98,7 @@ export async function transformForDisplay(content: string, styleName: string) {
|
||||
try {
|
||||
// 1. Apply style transformation (cn-* → Tailwind classes).
|
||||
const styleMap = await getStyleMap(styleName)
|
||||
let transformed = await transformStyle(content, { styleMap })
|
||||
const transformed = await transformStyle(content, { styleMap })
|
||||
|
||||
// 2. Apply icon/menu/render transforms.
|
||||
const config = buildDisplayConfig(styleName)
|
||||
|
||||
@@ -2,6 +2,8 @@ import * as React from "react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
|
||||
import { type PageTreeFolder } from "@/lib/page-tree"
|
||||
import { source } from "@/lib/source"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Callout } from "@/components/callout"
|
||||
import { CodeBlockCommand } from "@/components/code-block-command"
|
||||
@@ -34,6 +36,25 @@ import {
|
||||
TabsTrigger,
|
||||
} from "@/registry/new-york-v4/ui/tabs"
|
||||
|
||||
// Wrapper component that passes the components folder from the server.
|
||||
// This is only used on /docs/components/ index page, so default to radix.
|
||||
function ComponentsListWrapper() {
|
||||
const componentsFolder = source.pageTree.children.find(
|
||||
(page) => page.$id === "components"
|
||||
)
|
||||
|
||||
if (componentsFolder?.type !== "folder") {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<ComponentsList
|
||||
componentsFolder={componentsFolder as PageTreeFolder}
|
||||
currentBase="radix"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export const mdxComponents = {
|
||||
h1: ({ className, ...props }: React.ComponentProps<"h1">) => (
|
||||
<h1
|
||||
@@ -343,7 +364,7 @@ export const mdxComponents = {
|
||||
ComponentPreview,
|
||||
ComponentSource,
|
||||
CodeCollapsibleWrapper,
|
||||
ComponentsList,
|
||||
ComponentsList: ComponentsListWrapper,
|
||||
DirectoryList,
|
||||
Link: ({ className, ...props }: React.ComponentProps<typeof Link>) => (
|
||||
<Link
|
||||
|
||||
@@ -1,67 +1,5 @@
|
||||
import { createMDX } from "fumadocs-mdx/next"
|
||||
|
||||
// List of all component names for redirects.
|
||||
const COMPONENT_NAMES = [
|
||||
"accordion",
|
||||
"alert",
|
||||
"alert-dialog",
|
||||
"aspect-ratio",
|
||||
"avatar",
|
||||
"badge",
|
||||
"breadcrumb",
|
||||
"button",
|
||||
"button-group",
|
||||
"calendar",
|
||||
"card",
|
||||
"carousel",
|
||||
"chart",
|
||||
"checkbox",
|
||||
"collapsible",
|
||||
"combobox",
|
||||
"command",
|
||||
"context-menu",
|
||||
"data-table",
|
||||
"date-picker",
|
||||
"dialog",
|
||||
"drawer",
|
||||
"dropdown-menu",
|
||||
"empty",
|
||||
"field",
|
||||
"hover-card",
|
||||
"input",
|
||||
"input-group",
|
||||
"input-otp",
|
||||
"item",
|
||||
"kbd",
|
||||
"label",
|
||||
"menubar",
|
||||
"native-select",
|
||||
"navigation-menu",
|
||||
"pagination",
|
||||
"popover",
|
||||
"progress",
|
||||
"radio-group",
|
||||
"resizable",
|
||||
"scroll-area",
|
||||
"select",
|
||||
"separator",
|
||||
"sheet",
|
||||
"sidebar",
|
||||
"skeleton",
|
||||
"slider",
|
||||
"sonner",
|
||||
"spinner",
|
||||
"switch",
|
||||
"table",
|
||||
"tabs",
|
||||
"textarea",
|
||||
"toast",
|
||||
"toggle",
|
||||
"toggle-group",
|
||||
"tooltip",
|
||||
"typography",
|
||||
]
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
devIndicators: false,
|
||||
@@ -91,13 +29,6 @@ const nextConfig = {
|
||||
turbopackFileSystemCacheForDev: true,
|
||||
},
|
||||
redirects() {
|
||||
// Generate redirects for all components: /docs/components/:name → /docs/components/radix/:name.
|
||||
const componentRedirects = COMPONENT_NAMES.map((name) => ({
|
||||
source: `/docs/components/${name}`,
|
||||
destination: `/docs/components/radix/${name}`,
|
||||
permanent: true,
|
||||
}))
|
||||
|
||||
return [
|
||||
// Form redirects to /docs/forms.
|
||||
{
|
||||
@@ -116,7 +47,16 @@ const nextConfig = {
|
||||
permanent: true,
|
||||
},
|
||||
// Component redirects (default to radix).
|
||||
...componentRedirects,
|
||||
{
|
||||
source: "/docs/components/:name((?!radix|base|form)[^/]+)",
|
||||
destination: "/docs/components/radix/:name",
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: "/docs/components/:name((?!radix|base|form)[^/]+).md",
|
||||
destination: "/docs/components/radix/:name.md",
|
||||
permanent: false,
|
||||
},
|
||||
// Other redirects.
|
||||
{
|
||||
source: "/components",
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/accordion-demo.tsx",
|
||||
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/base-lyra/ui/accordion\"\n\nexport default function AccordionDemo() {\n return (\n <Accordion className=\"w-full\" defaultValue={[\"item-1\"]}>\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>Is Base it accessible?</AccordionTrigger>\n <AccordionContent>\n Yes. It adheres to the WAI-ARIA design pattern.\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-2\">\n <AccordionTrigger>Is it styled?</AccordionTrigger>\n <AccordionContent>\n Yes. It comes with default styles that matches the other\n components' aesthetic.\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-3\">\n <AccordionTrigger>Is it animated?</AccordionTrigger>\n <AccordionContent>\n Yes. It's animated by default, but you can disable it if you\n prefer.\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/accordion-disabled.tsx",
|
||||
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/base-lyra/ui/accordion\"\n\nexport default function AccordionDisabled() {\n return (\n <Accordion className=\"w-full\">\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>Can I access my account history?</AccordionTrigger>\n <AccordionContent>\n Yes, you can view your complete account history including all\n transactions, plan changes, and support tickets in the Account History\n section of your dashboard.\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-2\" disabled>\n <AccordionTrigger>Premium feature information</AccordionTrigger>\n <AccordionContent>\n This section contains information about premium features. Upgrade your\n plan to access this content.\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-3\">\n <AccordionTrigger>How do I update my email address?</AccordionTrigger>\n <AccordionContent>\n You can update your email address in your account settings.\n You'll receive a verification email at your new address to\n confirm the change.\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/accordion-multiple.tsx",
|
||||
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/base-lyra/ui/accordion\"\n\nexport default function AccordionMultiple() {\n return (\n <Accordion multiple className=\"w-full\">\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>\n What are the key considerations when implementing a comprehensive\n enterprise-level authentication system?\n </AccordionTrigger>\n <AccordionContent>\n Implementing a robust enterprise authentication system requires\n careful consideration of multiple factors. This includes secure\n password hashing and storage, multi-factor authentication (MFA)\n implementation, session management, OAuth2 and SSO integration,\n regular security audits, rate limiting to prevent brute force attacks,\n and maintaining detailed audit logs. Additionally, you'll need to\n consider scalability, performance impact, and compliance with relevant\n data protection regulations such as GDPR or HIPAA.\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-2\">\n <AccordionTrigger>\n How does modern distributed system architecture handle eventual\n consistency and data synchronization across multiple regions?\n </AccordionTrigger>\n <AccordionContent>\n Modern distributed systems employ various strategies to maintain data\n consistency across regions. This often involves using techniques like\n CRDT (Conflict-Free Replicated Data Types), vector clocks, and gossip\n protocols. Systems might implement event sourcing patterns, utilize\n message queues for asynchronous updates, and employ sophisticated\n conflict resolution strategies. Popular solutions like Amazon's\n DynamoDB and Google's Spanner demonstrate different approaches to\n solving these challenges, balancing between consistency, availability,\n and partition tolerance as described in the CAP theorem.\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/alert-demo.tsx",
|
||||
"content": "import { AlertCircleIcon, CheckCircle2Icon, PopcornIcon } from \"lucide-react\"\n\nimport {\n Alert,\n AlertDescription,\n AlertTitle,\n} from \"@/registry/base-lyra/ui/alert\"\n\nexport default function AlertDemo() {\n return (\n <div className=\"grid w-full max-w-xl items-start gap-4\">\n <Alert>\n <CheckCircle2Icon />\n <AlertTitle>Success! Your changes have been saved</AlertTitle>\n <AlertDescription>\n This is an alert with icon, title and description.\n </AlertDescription>\n </Alert>\n <Alert>\n <PopcornIcon />\n <AlertTitle>\n This Alert has a title and an icon. No description.\n </AlertTitle>\n </Alert>\n <Alert variant=\"destructive\">\n <AlertCircleIcon />\n <AlertTitle>Unable to process your payment.</AlertTitle>\n <AlertDescription>\n <p>Please verify your billing information and try again.</p>\n <ul className=\"list-inside list-disc text-sm\">\n <li>Check your card details</li>\n <li>Ensure sufficient funds</li>\n <li>Verify billing address</li>\n </ul>\n </AlertDescription>\n </Alert>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/alert-destructive.tsx",
|
||||
"content": "import { AlertCircleIcon } from \"lucide-react\"\n\nimport {\n Alert,\n AlertDescription,\n AlertTitle,\n} from \"@/registry/base-lyra/ui/alert\"\n\nexport default function AlertDestructive() {\n return (\n <Alert variant=\"destructive\">\n <AlertCircleIcon />\n <AlertTitle>Error</AlertTitle>\n <AlertDescription>\n Your session has expired. Please log in again.\n </AlertDescription>\n </Alert>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/alert-dialog-demo.tsx",
|
||||
"content": "import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/registry/base-lyra/ui/alert-dialog\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function AlertDialogDemo() {\n return (\n <AlertDialog>\n <AlertDialogTrigger render={<Button variant=\"outline\" />}>\n Show Dialog\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. This will permanently delete your\n account and remove your data from our servers.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction>Continue</AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/aspect-ratio-demo.tsx",
|
||||
"content": "import Image from \"next/image\"\n\nimport { AspectRatio } from \"@/registry/base-lyra/ui/aspect-ratio\"\n\nexport default function AspectRatioDemo() {\n return (\n <AspectRatio ratio={16 / 9} className=\"bg-muted rounded-lg\">\n <Image\n src=\"https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80\"\n alt=\"Photo by Drew Beamer\"\n fill\n className=\"h-full w-full rounded-lg object-cover dark:brightness-[0.2] dark:grayscale\"\n />\n </AspectRatio>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/avatar-demo.tsx",
|
||||
"content": "import {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/registry/base-lyra/ui/avatar\"\n\nexport default function AvatarDemo() {\n return (\n <div className=\"flex flex-row flex-wrap items-center gap-12\">\n <Avatar>\n <AvatarImage src=\"https://github.com/shadcn.png\" alt=\"@shadcn\" />\n <AvatarFallback>CN</AvatarFallback>\n </Avatar>\n <Avatar className=\"rounded-lg\">\n <AvatarImage\n src=\"https://github.com/evilrabbit.png\"\n alt=\"@evilrabbit\"\n />\n <AvatarFallback>ER</AvatarFallback>\n </Avatar>\n <div className=\"*:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:grayscale\">\n <Avatar>\n <AvatarImage src=\"https://github.com/shadcn.png\" alt=\"@shadcn\" />\n <AvatarFallback>CN</AvatarFallback>\n </Avatar>\n <Avatar>\n <AvatarImage\n src=\"https://github.com/maxleiter.png\"\n alt=\"@maxleiter\"\n />\n <AvatarFallback>LR</AvatarFallback>\n </Avatar>\n <Avatar>\n <AvatarImage\n src=\"https://github.com/evilrabbit.png\"\n alt=\"@evilrabbit\"\n />\n <AvatarFallback>ER</AvatarFallback>\n </Avatar>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/badge-demo.tsx",
|
||||
"content": "import { BadgeCheckIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/registry/base-lyra/ui/badge\"\n\nexport default function BadgeDemo() {\n return (\n <div className=\"flex flex-col items-center gap-2\">\n <div className=\"flex w-full flex-wrap gap-2\">\n <Badge>Badge</Badge>\n <Badge variant=\"secondary\">Secondary</Badge>\n <Badge variant=\"destructive\">Destructive</Badge>\n <Badge variant=\"outline\">Outline</Badge>\n </div>\n <div className=\"flex w-full flex-wrap gap-2\">\n <Badge\n variant=\"secondary\"\n className=\"bg-blue-500 text-white dark:bg-blue-600\"\n >\n <BadgeCheckIcon />\n Verified\n </Badge>\n <Badge className=\"h-5 min-w-5 rounded-full px-1 font-mono tabular-nums\">\n 8\n </Badge>\n <Badge\n className=\"h-5 min-w-5 rounded-full px-1 font-mono tabular-nums\"\n variant=\"destructive\"\n >\n 99\n </Badge>\n <Badge\n className=\"h-5 min-w-5 rounded-full px-1 font-mono tabular-nums\"\n variant=\"outline\"\n >\n 20+\n </Badge>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/badge-destructive.tsx",
|
||||
"content": "import { Badge } from \"@/registry/base-lyra/ui/badge\"\n\nexport default function BadgeDestructive() {\n return <Badge variant=\"destructive\">Destructive</Badge>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/badge-outline.tsx",
|
||||
"content": "import { Badge } from \"@/registry/base-lyra/ui/badge\"\n\nexport default function BadgeOutline() {\n return <Badge variant=\"outline\">Outline</Badge>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/badge-secondary.tsx",
|
||||
"content": "import { Badge } from \"@/registry/base-lyra/ui/badge\"\n\nexport default function BadgeSecondary() {\n return <Badge variant=\"secondary\">Secondary</Badge>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/breadcrumb-demo.tsx",
|
||||
"content": "import Link from \"next/link\"\n\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/registry/base-lyra/ui/breadcrumb\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nexport function BreadcrumbDemo() {\n return (\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/\" />}>Home</BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger className=\"flex items-center gap-1\">\n <BreadcrumbEllipsis className=\"size-4\" />\n <span className=\"sr-only\">Toggle menu</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem>Documentation</DropdownMenuItem>\n <DropdownMenuItem>Themes</DropdownMenuItem>\n <DropdownMenuItem>GitHub</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/docs/components\" />}>\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/breadcrumb-dropdown.tsx",
|
||||
"content": "import Link from \"next/link\"\nimport { ChevronDownIcon, SlashIcon } from \"lucide-react\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/registry/base-lyra/ui/breadcrumb\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nexport function BreadcrumbDropdown() {\n return (\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/\" />}>Home</BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger className=\"flex items-center gap-1 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5\">\n Components\n <ChevronDownIcon />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem>Documentation</DropdownMenuItem>\n <DropdownMenuItem>Themes</DropdownMenuItem>\n <DropdownMenuItem>GitHub</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/breadcrumb-ellipsis.tsx",
|
||||
"content": "import Link from \"next/link\"\n\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/registry/base-lyra/ui/breadcrumb\"\n\nexport function BreadcrumbEllipsisDemo() {\n return (\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/\" />}>Home</BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbEllipsis />\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/docs/components\" />}>\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/breadcrumb-link.tsx",
|
||||
"content": "import Link from \"next/link\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/registry/base-lyra/ui/breadcrumb\"\n\nexport function BreadcrumbLinkDemo() {\n return (\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/\" />}>Home</BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/components\" />}>\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/breadcrumb-responsive.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport Link from \"next/link\"\n\nimport { useMediaQuery } from \"@/hooks/use-media-query\"\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/registry/base-lyra/ui/breadcrumb\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/registry/base-lyra/ui/drawer\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nconst items = [\n { href: \"#\", label: \"Home\" },\n { href: \"#\", label: \"Documentation\" },\n { href: \"#\", label: \"Building Your Application\" },\n { href: \"#\", label: \"Data Fetching\" },\n { label: \"Caching and Revalidating\" },\n]\n\nconst ITEMS_TO_DISPLAY = 3\n\nexport function BreadcrumbResponsive() {\n const [open, setOpen] = React.useState(false)\n const isDesktop = useMediaQuery(\"(min-width: 768px)\")\n\n return (\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href={items[0].href ?? \"/\"} />}>\n {items[0].label}\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n {items.length > ITEMS_TO_DISPLAY ? (\n <>\n <BreadcrumbItem>\n {isDesktop ? (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger\n className=\"flex items-center gap-1\"\n aria-label=\"Toggle menu\"\n >\n <BreadcrumbEllipsis className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {items.slice(1, -2).map((item, index) => (\n <DropdownMenuItem key={index}>\n <Link href={item.href ? item.href : \"#\"}>\n {item.label}\n </Link>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger aria-label=\"Toggle Menu\">\n <BreadcrumbEllipsis className=\"h-4 w-4\" />\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader className=\"text-left\">\n <DrawerTitle>Navigate to</DrawerTitle>\n <DrawerDescription>\n Select a page to navigate to.\n </DrawerDescription>\n </DrawerHeader>\n <div className=\"grid gap-1 px-4\">\n {items.slice(1, -2).map((item, index) => (\n <Link\n key={index}\n href={item.href ? item.href : \"#\"}\n className=\"py-1 text-sm\"\n >\n {item.label}\n </Link>\n ))}\n </div>\n <DrawerFooter className=\"pt-4\">\n <DrawerClose asChild>\n <Button variant=\"outline\">Close</Button>\n </DrawerClose>\n </DrawerFooter>\n </DrawerContent>\n </Drawer>\n )}\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n </>\n ) : null}\n {items.slice(-ITEMS_TO_DISPLAY + 1).map((item, index) => (\n <BreadcrumbItem key={index}>\n {item.href ? (\n <>\n <BreadcrumbLink\n render={<Link href={item.href} />}\n className=\"max-w-20 truncate md:max-w-none\"\n >\n {item.label}\n </BreadcrumbLink>\n <BreadcrumbSeparator />\n </>\n ) : (\n <BreadcrumbPage className=\"max-w-20 truncate md:max-w-none\">\n {item.label}\n </BreadcrumbPage>\n )}\n </BreadcrumbItem>\n ))}\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/breadcrumb-separator.tsx",
|
||||
"content": "import Link from \"next/link\"\nimport { SlashIcon } from \"lucide-react\"\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/registry/base-lyra/ui/breadcrumb\"\n\nexport function BreadcrumbSeparatorDemo() {\n return (\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/\" />}>Home</BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbLink render={<Link href=\"/components\" />}>\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-as-child.tsx",
|
||||
"content": "import Link from \"next/link\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonAsChild() {\n return (\n <Button render={<Link href=\"/login\" />}>Login</Button>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-default.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonDefault() {\n return <Button>Button</Button>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-demo.tsx",
|
||||
"content": "import { ArrowUpIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonDemo() {\n return (\n <div className=\"flex flex-wrap items-center gap-2 md:flex-row\">\n <Button variant=\"outline\">Button</Button>\n <Button variant=\"outline\" size=\"icon\" aria-label=\"Submit\">\n <ArrowUpIcon />\n </Button>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-destructive.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonDestructive() {\n return <Button variant=\"destructive\">Destructive</Button>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-ghost.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonGhost() {\n return <Button variant=\"ghost\">Ghost</Button>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArchiveIcon,\n ArrowLeftIcon,\n CalendarPlusIcon,\n ClockIcon,\n ListFilterIcon,\n MailCheckIcon,\n MoreHorizontalIcon,\n TagIcon,\n Trash2Icon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nexport default function ButtonGroupDemo() {\n const [label, setLabel] = React.useState(\"personal\")\n\n return (\n <ButtonGroup>\n <ButtonGroup className=\"hidden sm:flex\">\n <Button variant=\"outline\" size=\"icon\" aria-label=\"Go Back\">\n <ArrowLeftIcon />\n </Button>\n </ButtonGroup>\n <ButtonGroup>\n <Button variant=\"outline\">Archive</Button>\n <Button variant=\"outline\">Report</Button>\n </ButtonGroup>\n <ButtonGroup>\n <Button variant=\"outline\">Snooze</Button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"icon\" aria-label=\"More Options\">\n <MoreHorizontalIcon />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-52\">\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <MailCheckIcon />\n Mark as Read\n </DropdownMenuItem>\n <DropdownMenuItem>\n <ArchiveIcon />\n Archive\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <ClockIcon />\n Snooze\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CalendarPlusIcon />\n Add to Calendar\n </DropdownMenuItem>\n <DropdownMenuItem>\n <ListFilterIcon />\n Add to List\n </DropdownMenuItem>\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>\n <TagIcon />\n Label As...\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent>\n <DropdownMenuRadioGroup\n value={label}\n onValueChange={setLabel}\n >\n <DropdownMenuRadioItem value=\"personal\">\n Personal\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"work\">\n Work\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"other\">\n Other\n </DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem variant=\"destructive\">\n <Trash2Icon />\n Trash\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </ButtonGroup>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-dropdown.tsx",
|
||||
"content": "\"use client\"\n\nimport {\n AlertTriangleIcon,\n CheckIcon,\n ChevronDownIcon,\n CopyIcon,\n ShareIcon,\n TrashIcon,\n UserRoundXIcon,\n VolumeOffIcon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nexport default function ButtonGroupDropdown() {\n return (\n <ButtonGroup>\n <Button variant=\"outline\">Follow</Button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"!pl-2\">\n <ChevronDownIcon />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"[--radius:1rem]\">\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <VolumeOffIcon />\n Mute Conversation\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CheckIcon />\n Mark as Read\n </DropdownMenuItem>\n <DropdownMenuItem>\n <AlertTriangleIcon />\n Report Conversation\n </DropdownMenuItem>\n <DropdownMenuItem>\n <UserRoundXIcon />\n Block User\n </DropdownMenuItem>\n <DropdownMenuItem>\n <ShareIcon />\n Share Conversation\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CopyIcon />\n Copy Conversation\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem variant=\"destructive\">\n <TrashIcon />\n Delete Conversation\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-input-group.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { AudioLinesIcon, PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"@/registry/base-lyra/ui/input-group\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/registry/base-lyra/ui/tooltip\"\n\nexport default function ButtonGroupInputGroup() {\n const [voiceEnabled, setVoiceEnabled] = React.useState(false)\n\n return (\n <ButtonGroup className=\"[--radius:9999rem]\">\n <ButtonGroup>\n <Button variant=\"outline\" size=\"icon\">\n <PlusIcon />\n </Button>\n </ButtonGroup>\n <ButtonGroup>\n <InputGroup>\n <InputGroupInput\n placeholder={\n voiceEnabled ? \"Record and send audio...\" : \"Send a message...\"\n }\n disabled={voiceEnabled}\n />\n <InputGroupAddon align=\"inline-end\">\n <Tooltip>\n <TooltipTrigger asChild>\n <InputGroupButton\n onClick={() => setVoiceEnabled(!voiceEnabled)}\n size=\"icon-xs\"\n data-active={voiceEnabled}\n className=\"data-[active=true]:bg-orange-100 data-[active=true]:text-orange-700 dark:data-[active=true]:bg-orange-800 dark:data-[active=true]:text-orange-100\"\n aria-pressed={voiceEnabled}\n >\n <AudioLinesIcon />\n </InputGroupButton>\n </TooltipTrigger>\n <TooltipContent>Voice Mode</TooltipContent>\n </Tooltip>\n </InputGroupAddon>\n </InputGroup>\n </ButtonGroup>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-input.tsx",
|
||||
"content": "import { SearchIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\nimport { Input } from \"@/registry/base-lyra/ui/input\"\n\nexport default function ButtonGroupInput() {\n return (\n <ButtonGroup>\n <Input placeholder=\"Search...\" />\n <Button variant=\"outline\" aria-label=\"Search\">\n <SearchIcon />\n </Button>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-nested.tsx",
|
||||
"content": "\"use client\"\n\nimport { ArrowLeftIcon, ArrowRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\n\nexport default function ButtonGroupNested() {\n return (\n <ButtonGroup>\n <ButtonGroup>\n <Button variant=\"outline\" size=\"sm\">\n 1\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n 2\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n 3\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n 4\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n 5\n </Button>\n </ButtonGroup>\n <ButtonGroup>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Previous\">\n <ArrowLeftIcon />\n </Button>\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Next\">\n <ArrowRightIcon />\n </Button>\n </ButtonGroup>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-orientation.tsx",
|
||||
"content": "import { MinusIcon, PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\n\nexport default function ButtonGroupOrientation() {\n return (\n <ButtonGroup\n orientation=\"vertical\"\n aria-label=\"Media controls\"\n className=\"h-fit\"\n >\n <Button variant=\"outline\" size=\"icon\">\n <PlusIcon />\n </Button>\n <Button variant=\"outline\" size=\"icon\">\n <MinusIcon />\n </Button>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -13,8 +13,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-popover.tsx",
|
||||
"content": "import { BotIcon, ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/base-lyra/ui/popover\"\nimport { Separator } from \"@/registry/base-lyra/ui/separator\"\nimport { Textarea } from \"@/registry/base-lyra/ui/textarea\"\n\nexport default function ButtonGroupPopover() {\n return (\n <ButtonGroup>\n <Button variant=\"outline\">\n <BotIcon /> Copilot\n </Button>\n <Popover>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" size=\"icon\" aria-label=\"Open Popover\">\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"rounded-xl p-0 text-sm\">\n <div className=\"px-4 py-3\">\n <div className=\"text-sm font-medium\">Agent Tasks</div>\n </div>\n <Separator />\n <div className=\"p-4 text-sm *:[p:not(:last-child)]:mb-2\">\n <Textarea\n placeholder=\"Describe your task in natural language.\"\n className=\"mb-4 resize-none\"\n />\n <p className=\"font-medium\">Start a new task with Copilot</p>\n <p className=\"text-muted-foreground\">\n Describe your task in natural language. Copilot will work in the\n background and open a pull request for your review.\n </p>\n </div>\n </PopoverContent>\n </Popover>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-select.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\nimport { Input } from \"@/registry/base-lyra/ui/input\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n} from \"@/registry/base-lyra/ui/select\"\n\nconst CURRENCIES = [\n {\n value: \"$\",\n label: \"US Dollar\",\n },\n {\n value: \"€\",\n label: \"Euro\",\n },\n {\n value: \"£\",\n label: \"British Pound\",\n },\n]\n\nexport default function ButtonGroupSelect() {\n const [currency, setCurrency] = React.useState(\"$\")\n\n return (\n <ButtonGroup>\n <ButtonGroup>\n <Select value={currency} onValueChange={setCurrency}>\n <SelectTrigger className=\"font-mono\">{currency}</SelectTrigger>\n <SelectContent className=\"min-w-24\">\n {CURRENCIES.map((currency) => (\n <SelectItem key={currency.value} value={currency.value}>\n {currency.value}{\" \"}\n <span className=\"text-muted-foreground\">{currency.label}</span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Input placeholder=\"10.00\" pattern=\"[0-9]*\" />\n </ButtonGroup>\n <ButtonGroup>\n <Button aria-label=\"Send\" size=\"icon\" variant=\"outline\">\n <ArrowRightIcon />\n </Button>\n </ButtonGroup>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-separator.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n ButtonGroup,\n ButtonGroupSeparator,\n} from \"@/registry/base-lyra/ui/button-group\"\n\nexport default function ButtonGroupSeparatorDemo() {\n return (\n <ButtonGroup>\n <Button variant=\"secondary\" size=\"sm\">\n Copy\n </Button>\n <ButtonGroupSeparator />\n <Button variant=\"secondary\" size=\"sm\">\n Paste\n </Button>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-size.tsx",
|
||||
"content": "import { PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { ButtonGroup } from \"@/registry/base-lyra/ui/button-group\"\n\nexport default function ButtonGroupSize() {\n return (\n <div className=\"flex flex-col items-start gap-8\">\n <ButtonGroup>\n <Button variant=\"outline\" size=\"sm\">\n Small\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n Button\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n Group\n </Button>\n <Button variant=\"outline\" size=\"icon-sm\">\n <PlusIcon />\n </Button>\n </ButtonGroup>\n <ButtonGroup>\n <Button variant=\"outline\">Default</Button>\n <Button variant=\"outline\">Button</Button>\n <Button variant=\"outline\">Group</Button>\n <Button variant=\"outline\" size=\"icon\">\n <PlusIcon />\n </Button>\n </ButtonGroup>\n <ButtonGroup>\n <Button variant=\"outline\" size=\"lg\">\n Large\n </Button>\n <Button variant=\"outline\" size=\"lg\">\n Button\n </Button>\n <Button variant=\"outline\" size=\"lg\">\n Group\n </Button>\n <Button variant=\"outline\" size=\"icon-lg\">\n <PlusIcon />\n </Button>\n </ButtonGroup>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-group-split.tsx",
|
||||
"content": "import { IconPlus } from \"@tabler/icons-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n ButtonGroup,\n ButtonGroupSeparator,\n} from \"@/registry/base-lyra/ui/button-group\"\n\nexport default function ButtonGroupSplit() {\n return (\n <ButtonGroup>\n <Button variant=\"secondary\">Button</Button>\n <ButtonGroupSeparator />\n <Button size=\"icon\" variant=\"secondary\">\n <IconPlus />\n </Button>\n </ButtonGroup>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-icon.tsx",
|
||||
"content": "import { CircleFadingArrowUpIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonIcon() {\n return (\n <Button variant=\"outline\" size=\"icon\">\n <CircleFadingArrowUpIcon />\n </Button>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-link.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonLink() {\n return <Button variant=\"link\">Link</Button>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-loading.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\nimport { Spinner } from \"@/registry/base-lyra/ui/spinner\"\n\nexport default function ButtonLoading() {\n return (\n <Button size=\"sm\" variant=\"outline\" disabled>\n <Spinner />\n Submit\n </Button>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-outline.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonOutline() {\n return <Button variant=\"outline\">Outline</Button>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-rounded.tsx",
|
||||
"content": "import { ArrowUpIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonRounded() {\n return (\n <div className=\"flex flex-col gap-8\">\n <Button variant=\"outline\" size=\"icon\" className=\"rounded-full\">\n <ArrowUpIcon />\n </Button>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-secondary.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonSecondary() {\n return <Button variant=\"secondary\">Secondary</Button>\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-size.tsx",
|
||||
"content": "import { ArrowUpRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonSize() {\n return (\n <div className=\"flex flex-col items-start gap-8 sm:flex-row\">\n <div className=\"flex items-start gap-2\">\n <Button size=\"sm\" variant=\"outline\">\n Small\n </Button>\n <Button size=\"icon-sm\" aria-label=\"Submit\" variant=\"outline\">\n <ArrowUpRightIcon />\n </Button>\n </div>\n <div className=\"flex items-start gap-2\">\n <Button variant=\"outline\">Default</Button>\n <Button size=\"icon\" aria-label=\"Submit\" variant=\"outline\">\n <ArrowUpRightIcon />\n </Button>\n </div>\n <div className=\"flex items-start gap-2\">\n <Button variant=\"outline\" size=\"lg\">\n Large\n </Button>\n <Button size=\"icon-lg\" aria-label=\"Submit\" variant=\"outline\">\n <ArrowUpRightIcon />\n </Button>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/button-with-icon.tsx",
|
||||
"content": "import { IconGitBranch } from \"@tabler/icons-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\n\nexport default function ButtonWithIcon() {\n return (\n <Button variant=\"outline\" size=\"sm\">\n <IconGitBranch /> New Branch\n </Button>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/calendar-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/base-lyra/ui/calendar\"\n\nexport default function CalendarDemo() {\n const [date, setDate] = React.useState<Date | undefined>(new Date())\n\n return (\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"rounded-md border shadow-sm\"\n captionLayout=\"dropdown\"\n />\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/card-demo.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"@/registry/base-lyra/ui/card\"\nimport { Input } from \"@/registry/base-lyra/ui/input\"\nimport { Label } from \"@/registry/base-lyra/ui/label\"\n\nexport default function CardDemo() {\n return (\n <Card className=\"w-full max-w-sm\">\n <CardHeader>\n <CardTitle>Login to your account</CardTitle>\n <CardDescription>\n Enter your email below to login to your account\n </CardDescription>\n <CardAction>\n <Button variant=\"link\">Sign Up</Button>\n </CardAction>\n </CardHeader>\n <CardContent>\n <form>\n <div className=\"flex flex-col gap-6\">\n <div className=\"grid gap-2\">\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n required\n />\n </div>\n <div className=\"grid gap-2\">\n <div className=\"flex items-center\">\n <Label htmlFor=\"password\">Password</Label>\n <a\n href=\"#\"\n className=\"ml-auto inline-block text-sm underline-offset-4 hover:underline\"\n >\n Forgot your password?\n </a>\n </div>\n <Input id=\"password\" type=\"password\" required />\n </div>\n </div>\n </form>\n </CardContent>\n <CardFooter className=\"flex-col gap-2\">\n <Button type=\"submit\" className=\"w-full\">\n Login\n </Button>\n <Button variant=\"outline\" className=\"w-full\">\n Login with Google\n </Button>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/carousel-api.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Card, CardContent } from \"@/registry/base-lyra/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n type CarouselApi,\n} from \"@/registry/base-lyra/ui/carousel\"\n\nexport default function CarouselDApiDemo() {\n const [api, setApi] = React.useState<CarouselApi>()\n const [current, setCurrent] = React.useState(0)\n const [count, setCount] = React.useState(0)\n\n React.useEffect(() => {\n if (!api) {\n return\n }\n\n setCount(api.scrollSnapList().length)\n setCurrent(api.selectedScrollSnap() + 1)\n\n api.on(\"select\", () => {\n setCurrent(api.selectedScrollSnap() + 1)\n })\n }, [api])\n\n return (\n <div className=\"mx-auto max-w-xs\">\n <Carousel setApi={setApi} className=\"w-full max-w-xs\">\n <CarouselContent>\n {Array.from({ length: 5 }).map((_, index) => (\n <CarouselItem key={index}>\n <Card>\n <CardContent className=\"flex aspect-square items-center justify-center p-6\">\n <span className=\"text-4xl font-semibold\">{index + 1}</span>\n </CardContent>\n </Card>\n </CarouselItem>\n ))}\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n <div className=\"text-muted-foreground py-2 text-center text-sm\">\n Slide {current} of {count}\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/carousel-demo.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/registry/base-lyra/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/registry/base-lyra/ui/carousel\"\n\nexport default function CarouselDemo() {\n return (\n <Carousel className=\"w-full max-w-xs\">\n <CarouselContent>\n {Array.from({ length: 5 }).map((_, index) => (\n <CarouselItem key={index}>\n <div className=\"p-1\">\n <Card>\n <CardContent className=\"flex aspect-square items-center justify-center p-6\">\n <span className=\"text-4xl font-semibold\">{index + 1}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n ))}\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/carousel-orientation.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/registry/base-lyra/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/registry/base-lyra/ui/carousel\"\n\nexport default function CarouselOrientation() {\n return (\n <Carousel\n opts={{\n align: \"start\",\n }}\n orientation=\"vertical\"\n className=\"w-full max-w-xs\"\n >\n <CarouselContent className=\"-mt-1 h-[200px]\">\n {Array.from({ length: 5 }).map((_, index) => (\n <CarouselItem key={index} className=\"pt-1 md:basis-1/2\">\n <div className=\"p-1\">\n <Card>\n <CardContent className=\"flex items-center justify-center p-6\">\n <span className=\"text-3xl font-semibold\">{index + 1}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n ))}\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/carousel-plugin.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport Autoplay from \"embla-carousel-autoplay\"\n\nimport { Card, CardContent } from \"@/registry/base-lyra/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/registry/base-lyra/ui/carousel\"\n\nexport default function CarouselPlugin() {\n const plugin = React.useRef(\n Autoplay({ delay: 2000, stopOnInteraction: true })\n )\n\n return (\n <Carousel\n plugins={[plugin.current]}\n className=\"w-full max-w-xs\"\n onMouseEnter={plugin.current.stop}\n onMouseLeave={plugin.current.reset}\n >\n <CarouselContent>\n {Array.from({ length: 5 }).map((_, index) => (\n <CarouselItem key={index}>\n <div className=\"p-1\">\n <Card>\n <CardContent className=\"flex aspect-square items-center justify-center p-6\">\n <span className=\"text-4xl font-semibold\">{index + 1}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n ))}\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/carousel-size.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/registry/base-lyra/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/registry/base-lyra/ui/carousel\"\n\nexport default function CarouselSize() {\n return (\n <Carousel\n opts={{\n align: \"start\",\n }}\n className=\"w-full max-w-sm\"\n >\n <CarouselContent>\n {Array.from({ length: 5 }).map((_, index) => (\n <CarouselItem key={index} className=\"md:basis-1/2 lg:basis-1/3\">\n <div className=\"p-1\">\n <Card>\n <CardContent className=\"flex aspect-square items-center justify-center p-6\">\n <span className=\"text-3xl font-semibold\">{index + 1}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n ))}\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/carousel-spacing.tsx",
|
||||
"content": "import * as React from \"react\"\n\nimport { Card, CardContent } from \"@/registry/base-lyra/ui/card\"\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/registry/base-lyra/ui/carousel\"\n\nexport default function CarouselSpacing() {\n return (\n <Carousel className=\"w-full max-w-sm\">\n <CarouselContent className=\"-ml-1\">\n {Array.from({ length: 5 }).map((_, index) => (\n <CarouselItem key={index} className=\"pl-1 md:basis-1/2 lg:basis-1/3\">\n <div className=\"p-1\">\n <Card>\n <CardContent className=\"flex aspect-square items-center justify-center p-6\">\n <span className=\"text-2xl font-semibold\">{index + 1}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n ))}\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/chart-bar-demo-axis.tsx",
|
||||
"content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n ChartContainer,\n type ChartConfig,\n} from \"@/registry/base-lyra/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoAxis() {\n return (\n <ChartContainer config={chartConfig} className=\"min-h-[200px] w-full\">\n <BarChart accessibilityLayer data={chartData}>\n <CartesianGrid vertical={false} />\n <XAxis\n dataKey=\"month\"\n tickLine={false}\n tickMargin={10}\n axisLine={false}\n tickFormatter={(value) => value.slice(0, 3)}\n />\n <Bar dataKey=\"desktop\" fill=\"var(--color-desktop)\" radius={4} />\n <Bar dataKey=\"mobile\" fill=\"var(--color-mobile)\" radius={4} />\n </BarChart>\n </ChartContainer>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/chart-bar-demo-grid.tsx",
|
||||
"content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid } from \"recharts\"\n\nimport {\n ChartContainer,\n type ChartConfig,\n} from \"@/registry/base-lyra/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoGrid() {\n return (\n <ChartContainer config={chartConfig} className=\"min-h-[200px] w-full\">\n <BarChart accessibilityLayer data={chartData}>\n <CartesianGrid vertical={false} />\n <Bar dataKey=\"desktop\" fill=\"var(--color-desktop)\" radius={4} />\n <Bar dataKey=\"mobile\" fill=\"var(--color-mobile)\" radius={4} />\n </BarChart>\n </ChartContainer>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/chart-bar-demo-legend.tsx",
|
||||
"content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig,\n} from \"@/registry/base-lyra/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoLegend() {\n return (\n <ChartContainer config={chartConfig} className=\"min-h-[200px] w-full\">\n <BarChart accessibilityLayer data={chartData}>\n <CartesianGrid vertical={false} />\n <XAxis\n dataKey=\"month\"\n tickLine={false}\n tickMargin={10}\n axisLine={false}\n tickFormatter={(value) => value.slice(0, 3)}\n />\n <ChartTooltip content={<ChartTooltipContent />} />\n <ChartLegend content={<ChartLegendContent />} />\n <Bar dataKey=\"desktop\" fill=\"var(--color-desktop)\" radius={4} />\n <Bar dataKey=\"mobile\" fill=\"var(--color-mobile)\" radius={4} />\n </BarChart>\n </ChartContainer>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/chart-bar-demo-tooltip.tsx",
|
||||
"content": "\"use client\"\n\nimport { Bar, BarChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig,\n} from \"@/registry/base-lyra/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemoTooltip() {\n return (\n <ChartContainer config={chartConfig} className=\"min-h-[200px] w-full\">\n <BarChart accessibilityLayer data={chartData}>\n <CartesianGrid vertical={false} />\n <XAxis\n dataKey=\"month\"\n tickLine={false}\n tickMargin={10}\n axisLine={false}\n tickFormatter={(value) => value.slice(0, 3)}\n />\n <ChartTooltip content={<ChartTooltipContent />} />\n <Bar dataKey=\"desktop\" fill=\"var(--color-desktop)\" radius={4} />\n <Bar dataKey=\"mobile\" fill=\"var(--color-mobile)\" radius={4} />\n </BarChart>\n </ChartContainer>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/chart-bar-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport { Bar, BarChart } from \"recharts\"\n\nimport {\n ChartContainer,\n type ChartConfig,\n} from \"@/registry/base-lyra/ui/chart\"\n\nconst chartData = [\n { month: \"January\", desktop: 186, mobile: 80 },\n { month: \"February\", desktop: 305, mobile: 200 },\n { month: \"March\", desktop: 237, mobile: 120 },\n { month: \"April\", desktop: 73, mobile: 190 },\n { month: \"May\", desktop: 209, mobile: 130 },\n { month: \"June\", desktop: 214, mobile: 140 },\n]\n\nconst chartConfig = {\n desktop: {\n label: \"Desktop\",\n color: \"#2563eb\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"#60a5fa\",\n },\n} satisfies ChartConfig\n\nexport function ChartBarDemo() {\n return (\n <ChartContainer config={chartConfig} className=\"min-h-[200px] w-full\">\n <BarChart accessibilityLayer data={chartData}>\n <Bar dataKey=\"desktop\" fill=\"var(--color-desktop)\" radius={4} />\n <Bar dataKey=\"mobile\" fill=\"var(--color-mobile)\" radius={4} />\n </BarChart>\n </ChartContainer>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/checkbox-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport { Checkbox } from \"@/registry/base-lyra/ui/checkbox\"\nimport { Label } from \"@/registry/base-lyra/ui/label\"\n\nexport default function CheckboxDemo() {\n return (\n <div className=\"flex flex-col gap-6\">\n <div className=\"flex items-center gap-3\">\n <Checkbox id=\"terms\" />\n <Label htmlFor=\"terms\">Accept terms and conditions</Label>\n </div>\n <div className=\"flex items-start gap-3\">\n <Checkbox id=\"terms-2\" defaultChecked />\n <div className=\"grid gap-2\">\n <Label htmlFor=\"terms-2\">Accept terms and conditions</Label>\n <p className=\"text-muted-foreground text-sm\">\n By clicking this checkbox, you agree to the terms and conditions.\n </p>\n </div>\n </div>\n <div className=\"flex items-start gap-3\">\n <Checkbox id=\"toggle\" disabled />\n <Label htmlFor=\"toggle\">Enable notifications</Label>\n </div>\n <Label className=\"hover:bg-accent/50 flex items-start gap-3 rounded-lg border p-3 has-[[aria-checked=true]]:border-blue-600 has-[[aria-checked=true]]:bg-blue-50 dark:has-[[aria-checked=true]]:border-blue-900 dark:has-[[aria-checked=true]]:bg-blue-950\">\n <Checkbox\n id=\"toggle-2\"\n defaultChecked\n className=\"data-[state=checked]:border-blue-600 data-[state=checked]:bg-blue-600 data-[state=checked]:text-white dark:data-[state=checked]:border-blue-700 dark:data-[state=checked]:bg-blue-700\"\n />\n <div className=\"grid gap-1.5 font-normal\">\n <p className=\"text-sm leading-none font-medium\">\n Enable notifications\n </p>\n <p className=\"text-muted-foreground text-sm\">\n You can enable or disable notifications at any time.\n </p>\n </div>\n </Label>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/checkbox-disabled.tsx",
|
||||
"content": "import { Checkbox } from \"@/registry/base-lyra/ui/checkbox\"\n\nexport default function CheckboxDisabled() {\n return (\n <div className=\"flex items-center space-x-2\">\n <Checkbox id=\"terms2\" disabled />\n <label\n htmlFor=\"terms2\"\n className=\"text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/checkbox-with-text.tsx",
|
||||
"content": "\"use client\"\n\nimport { Checkbox } from \"@/registry/base-lyra/ui/checkbox\"\n\nexport default function CheckboxWithText() {\n return (\n <div className=\"items-top flex gap-2\">\n <Checkbox id=\"terms1\" />\n <div className=\"grid gap-1.5 leading-none\">\n <label\n htmlFor=\"terms1\"\n className=\"text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n <p className=\"text-muted-foreground text-sm\">\n You agree to our Terms of Service and Privacy Policy.\n </p>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/collapsible-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronsUpDown } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/registry/base-lyra/ui/collapsible\"\n\nexport default function CollapsibleDemo() {\n const [isOpen, setIsOpen] = React.useState(false)\n\n return (\n <Collapsible\n open={isOpen}\n onOpenChange={setIsOpen}\n className=\"flex w-[350px] flex-col gap-2\"\n >\n <div className=\"flex items-center justify-between gap-4 px-4\">\n <h4 className=\"text-sm font-semibold\">\n @peduarte starred 3 repositories\n </h4>\n <CollapsibleTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"size-8\">\n <ChevronsUpDown />\n <span className=\"sr-only\">Toggle</span>\n </Button>\n </CollapsibleTrigger>\n </div>\n <div className=\"rounded-md border px-4 py-2 font-mono text-sm\">\n @radix-ui/primitives\n </div>\n <CollapsibleContent className=\"flex flex-col gap-2\">\n <div className=\"rounded-md border px-4 py-2 font-mono text-sm\">\n @radix-ui/colors\n </div>\n <div className=\"rounded-md border px-4 py-2 font-mono text-sm\">\n @stitches/react\n </div>\n </CollapsibleContent>\n </Collapsible>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/combobox-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Check, ChevronsUpDown } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/registry/base-lyra/ui/command\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/base-lyra/ui/popover\"\n\nconst frameworks = [\n {\n value: \"next.js\",\n label: \"Next.js\",\n },\n {\n value: \"sveltekit\",\n label: \"SvelteKit\",\n },\n {\n value: \"nuxt.js\",\n label: \"Nuxt.js\",\n },\n {\n value: \"remix\",\n label: \"Remix\",\n },\n {\n value: \"astro\",\n label: \"Astro\",\n },\n]\n\nexport default function ComboboxDemo() {\n const [open, setOpen] = React.useState(false)\n const [value, setValue] = React.useState(\"\")\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-[200px] justify-between\"\n >\n {value\n ? frameworks.find((framework) => framework.value === value)?.label\n : \"Select framework...\"}\n <ChevronsUpDown className=\"opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search framework...\" className=\"h-9\" />\n <CommandList>\n <CommandEmpty>No framework found.</CommandEmpty>\n <CommandGroup>\n {frameworks.map((framework) => (\n <CommandItem\n key={framework.value}\n value={framework.value}\n onSelect={(currentValue) => {\n setValue(currentValue === value ? \"\" : currentValue)\n setOpen(false)\n }}\n >\n {framework.label}\n <Check\n className={cn(\n \"ml-auto\",\n value === framework.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/combobox-dropdown-menu.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { MoreHorizontal } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/registry/base-lyra/ui/command\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nconst labels = [\n \"feature\",\n \"bug\",\n \"enhancement\",\n \"documentation\",\n \"design\",\n \"question\",\n \"maintenance\",\n]\n\nexport default function ComboboxDropdownMenu() {\n const [label, setLabel] = React.useState(\"feature\")\n const [open, setOpen] = React.useState(false)\n\n return (\n <div className=\"flex w-full flex-col items-start justify-between rounded-md border px-4 py-3 sm:flex-row sm:items-center\">\n <p className=\"text-sm leading-none font-medium\">\n <span className=\"bg-primary text-primary-foreground mr-2 rounded-lg px-2 py-1 text-xs\">\n {label}\n </span>\n <span className=\"text-muted-foreground\">Create a new project</span>\n </p>\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"sm\">\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-[200px]\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuGroup>\n <DropdownMenuItem>Assign to...</DropdownMenuItem>\n <DropdownMenuItem>Set due date...</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>Apply label</DropdownMenuSubTrigger>\n <DropdownMenuSubContent className=\"p-0\">\n <Command>\n <CommandInput\n placeholder=\"Filter label...\"\n autoFocus={true}\n className=\"h-9\"\n />\n <CommandList>\n <CommandEmpty>No label found.</CommandEmpty>\n <CommandGroup>\n {labels.map((label) => (\n <CommandItem\n key={label}\n value={label}\n onSelect={(value) => {\n setLabel(value)\n setOpen(false)\n }}\n >\n {label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n <DropdownMenuSeparator />\n <DropdownMenuItem className=\"text-red-600\">\n Delete\n <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/combobox-popover.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/registry/base-lyra/ui/command\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/base-lyra/ui/popover\"\n\ntype Status = {\n value: string\n label: string\n}\n\nconst statuses: Status[] = [\n {\n value: \"backlog\",\n label: \"Backlog\",\n },\n {\n value: \"todo\",\n label: \"Todo\",\n },\n {\n value: \"in progress\",\n label: \"In Progress\",\n },\n {\n value: \"done\",\n label: \"Done\",\n },\n {\n value: \"canceled\",\n label: \"Canceled\",\n },\n]\n\nexport default function ComboboxPopover() {\n const [open, setOpen] = React.useState(false)\n const [selectedStatus, setSelectedStatus] = React.useState<Status | null>(\n null\n )\n\n return (\n <div className=\"flex items-center space-x-4\">\n <p className=\"text-muted-foreground text-sm\">Status</p>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"w-[150px] justify-start\">\n {selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"p-0\" side=\"right\" align=\"start\">\n <Command>\n <CommandInput placeholder=\"Change status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n {statuses.map((status) => (\n <CommandItem\n key={status.value}\n value={status.value}\n onSelect={(value) => {\n setSelectedStatus(\n statuses.find((priority) => priority.value === value) ||\n null\n )\n setOpen(false)\n }}\n >\n {status.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/combobox-responsive.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { useMediaQuery } from \"@/hooks/use-media-query\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/registry/base-lyra/ui/command\"\nimport {\n Drawer,\n DrawerContent,\n DrawerTrigger,\n} from \"@/registry/base-lyra/ui/drawer\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/base-lyra/ui/popover\"\n\ntype Status = {\n value: string\n label: string\n}\n\nconst statuses: Status[] = [\n {\n value: \"backlog\",\n label: \"Backlog\",\n },\n {\n value: \"todo\",\n label: \"Todo\",\n },\n {\n value: \"in progress\",\n label: \"In Progress\",\n },\n {\n value: \"done\",\n label: \"Done\",\n },\n {\n value: \"canceled\",\n label: \"Canceled\",\n },\n]\n\nexport default function ComboBoxResponsive() {\n const [open, setOpen] = React.useState(false)\n const isDesktop = useMediaQuery(\"(min-width: 768px)\")\n const [selectedStatus, setSelectedStatus] = React.useState<Status | null>(\n null\n )\n\n if (isDesktop) {\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"w-[150px] justify-start\">\n {selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[200px] p-0\" align=\"start\">\n <StatusList setOpen={setOpen} setSelectedStatus={setSelectedStatus} />\n </PopoverContent>\n </Popover>\n )\n }\n\n return (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>\n <Button variant=\"outline\" className=\"w-[150px] justify-start\">\n {selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <div className=\"mt-4 border-t\">\n <StatusList setOpen={setOpen} setSelectedStatus={setSelectedStatus} />\n </div>\n </DrawerContent>\n </Drawer>\n )\n}\n\nfunction StatusList({\n setOpen,\n setSelectedStatus,\n}: {\n setOpen: (open: boolean) => void\n setSelectedStatus: (status: Status | null) => void\n}) {\n return (\n <Command>\n <CommandInput placeholder=\"Filter status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n {statuses.map((status) => (\n <CommandItem\n key={status.value}\n value={status.value}\n onSelect={(value) => {\n setSelectedStatus(\n statuses.find((priority) => priority.value === value) || null\n )\n setOpen(false)\n }}\n >\n {status.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/command-demo.tsx",
|
||||
"content": "import {\n Calculator,\n Calendar,\n CreditCard,\n Settings,\n Smile,\n User,\n} from \"lucide-react\"\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n} from \"@/registry/base-lyra/ui/command\"\n\nexport function CommandDemo() {\n return (\n <Command className=\"rounded-lg border shadow-md md:min-w-[450px]\">\n <CommandInput placeholder=\"Type a command or search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Suggestions\">\n <CommandItem>\n <Calendar />\n <span>Calendar</span>\n </CommandItem>\n <CommandItem>\n <Smile />\n <span>Search Emoji</span>\n </CommandItem>\n <CommandItem disabled>\n <Calculator />\n <span>Calculator</span>\n </CommandItem>\n </CommandGroup>\n <CommandSeparator />\n <CommandGroup heading=\"Settings\">\n <CommandItem>\n <User />\n <span>Profile</span>\n <CommandShortcut>⌘P</CommandShortcut>\n </CommandItem>\n <CommandItem>\n <CreditCard />\n <span>Billing</span>\n <CommandShortcut>⌘B</CommandShortcut>\n </CommandItem>\n <CommandItem>\n <Settings />\n <span>Settings</span>\n <CommandShortcut>⌘S</CommandShortcut>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/command-dialog.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n Calculator,\n Calendar,\n CreditCard,\n Settings,\n Smile,\n User,\n} from \"lucide-react\"\n\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n} from \"@/registry/base-lyra/ui/command\"\n\nexport function CommandDialogDemo() {\n const [open, setOpen] = React.useState(false)\n\n React.useEffect(() => {\n const down = (e: KeyboardEvent) => {\n if (e.key === \"j\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n setOpen((open) => !open)\n }\n }\n\n document.addEventListener(\"keydown\", down)\n return () => document.removeEventListener(\"keydown\", down)\n }, [])\n\n return (\n <>\n <p className=\"text-muted-foreground text-sm\">\n Press{\" \"}\n <kbd className=\"bg-muted text-muted-foreground pointer-events-none inline-flex h-5 items-center gap-1 rounded border px-1.5 font-mono text-[10px] font-medium opacity-100 select-none\">\n <span className=\"text-xs\">⌘</span>J\n </kbd>\n </p>\n <CommandDialog open={open} onOpenChange={setOpen}>\n <CommandInput placeholder=\"Type a command or search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Suggestions\">\n <CommandItem>\n <Calendar />\n <span>Calendar</span>\n </CommandItem>\n <CommandItem>\n <Smile />\n <span>Search Emoji</span>\n </CommandItem>\n <CommandItem>\n <Calculator />\n <span>Calculator</span>\n </CommandItem>\n </CommandGroup>\n <CommandSeparator />\n <CommandGroup heading=\"Settings\">\n <CommandItem>\n <User />\n <span>Profile</span>\n <CommandShortcut>⌘P</CommandShortcut>\n </CommandItem>\n <CommandItem>\n <CreditCard />\n <span>Billing</span>\n <CommandShortcut>⌘B</CommandShortcut>\n </CommandItem>\n <CommandItem>\n <Settings />\n <span>Settings</span>\n <CommandShortcut>⌘S</CommandShortcut>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </CommandDialog>\n </>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/context-menu-demo.tsx",
|
||||
"content": "import {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n} from \"@/registry/base-lyra/ui/context-menu\"\n\nexport default function ContextMenuDemo() {\n return (\n <ContextMenu>\n <ContextMenuTrigger className=\"flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm\">\n Right click here\n </ContextMenuTrigger>\n <ContextMenuContent className=\"w-52\">\n <ContextMenuItem inset>\n Back\n <ContextMenuShortcut>⌘[</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem inset disabled>\n Forward\n <ContextMenuShortcut>⌘]</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem inset>\n Reload\n <ContextMenuShortcut>⌘R</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuSub>\n <ContextMenuSubTrigger inset>More Tools</ContextMenuSubTrigger>\n <ContextMenuSubContent className=\"w-44\">\n <ContextMenuItem>Save Page...</ContextMenuItem>\n <ContextMenuItem>Create Shortcut...</ContextMenuItem>\n <ContextMenuItem>Name Window...</ContextMenuItem>\n <ContextMenuSeparator />\n <ContextMenuItem>Developer Tools</ContextMenuItem>\n <ContextMenuSeparator />\n <ContextMenuItem variant=\"destructive\">Delete</ContextMenuItem>\n </ContextMenuSubContent>\n </ContextMenuSub>\n <ContextMenuSeparator />\n <ContextMenuCheckboxItem checked>\n Show Bookmarks\n </ContextMenuCheckboxItem>\n <ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>\n <ContextMenuSeparator />\n <ContextMenuRadioGroup value=\"pedro\">\n <ContextMenuLabel inset>People</ContextMenuLabel>\n <ContextMenuRadioItem value=\"pedro\">\n Pedro Duarte\n </ContextMenuRadioItem>\n <ContextMenuRadioItem value=\"colm\">Colm Tuite</ContextMenuRadioItem>\n </ContextMenuRadioGroup>\n </ContextMenuContent>\n </ContextMenu>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/date-picker-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { Calendar } from \"@/registry/base-lyra/ui/calendar\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/base-lyra/ui/popover\"\n\nexport function DatePickerDemo() {\n const [date, setDate] = React.useState<Date>()\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant={\"outline\"}\n className={cn(\n \"w-[240px] justify-start text-left font-normal\",\n !date && \"text-muted-foreground\"\n )}\n >\n <CalendarIcon />\n {date ? format(date, \"PPP\") : <span>Pick a date</span>}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n initialFocus\n />\n </PopoverContent>\n </Popover>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/date-picker-with-presets.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays, format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { Calendar } from \"@/registry/base-lyra/ui/calendar\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/base-lyra/ui/popover\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/base-lyra/ui/select\"\n\nexport function DatePickerWithPresets() {\n const [date, setDate] = React.useState<Date>()\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant={\"outline\"}\n className={cn(\n \"w-[240px] justify-start text-left font-normal\",\n !date && \"text-muted-foreground\"\n )}\n >\n <CalendarIcon />\n {date ? format(date, \"PPP\") : <span>Pick a date</span>}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"flex w-auto flex-col space-y-2 p-2\"\n >\n <Select\n onValueChange={(value) =>\n setDate(addDays(new Date(), parseInt(value)))\n }\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"0\">Today</SelectItem>\n <SelectItem value=\"1\">Tomorrow</SelectItem>\n <SelectItem value=\"3\">In 3 days</SelectItem>\n <SelectItem value=\"7\">In a week</SelectItem>\n </SelectContent>\n </Select>\n <div className=\"rounded-md border\">\n <Calendar mode=\"single\" selected={date} onSelect={setDate} />\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/date-picker-with-range.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays, format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { Calendar } from \"@/registry/base-lyra/ui/calendar\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/base-lyra/ui/popover\"\n\nexport function DatePickerWithRange({\n className,\n}: React.HTMLAttributes<HTMLDivElement>) {\n const [date, setDate] = React.useState<DateRange | undefined>({\n from: new Date(2022, 0, 20),\n to: addDays(new Date(2022, 0, 20), 20),\n })\n\n return (\n <div className={cn(\"grid gap-2\", className)}>\n <Popover>\n <PopoverTrigger asChild>\n <Button\n id=\"date\"\n variant={\"outline\"}\n className={cn(\n \"w-[300px] justify-start text-left font-normal\",\n !date && \"text-muted-foreground\"\n )}\n >\n <CalendarIcon />\n {date?.from ? (\n date.to ? (\n <>\n {format(date.from, \"LLL dd, y\")} -{\" \"}\n {format(date.to, \"LLL dd, y\")}\n </>\n ) : (\n format(date.from, \"LLL dd, y\")\n )\n ) : (\n <span>Pick a date</span>\n )}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n initialFocus\n mode=\"range\"\n defaultMonth={date?.from}\n selected={date}\n onSelect={setDate}\n numberOfMonths={2}\n />\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/dialog-close-button.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/registry/base-lyra/ui/dialog\"\nimport { Input } from \"@/registry/base-lyra/ui/input\"\nimport { Label } from \"@/registry/base-lyra/ui/label\"\n\nexport function DialogCloseButton() {\n return (\n <Dialog>\n <DialogTrigger asChild>\n <Button variant=\"outline\">Share</Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Share link</DialogTitle>\n <DialogDescription>\n Anyone who has this link will be able to view this.\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex items-center gap-2\">\n <div className=\"grid flex-1 gap-2\">\n <Label htmlFor=\"link\" className=\"sr-only\">\n Link\n </Label>\n <Input\n id=\"link\"\n defaultValue=\"https://ui.shadcn.com/docs/installation\"\n readOnly\n />\n </div>\n </div>\n <DialogFooter className=\"sm:justify-start\">\n <DialogClose asChild>\n <Button type=\"button\" variant=\"secondary\">\n Close\n </Button>\n </DialogClose>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/dialog-demo.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/registry/base-lyra/ui/dialog\"\nimport { Input } from \"@/registry/base-lyra/ui/input\"\nimport { Label } from \"@/registry/base-lyra/ui/label\"\n\nexport function DialogDemo() {\n return (\n <Dialog>\n <form>\n <DialogTrigger asChild>\n <Button variant=\"outline\">Open Dialog</Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're\n done.\n </DialogDescription>\n </DialogHeader>\n <div className=\"grid gap-4\">\n <div className=\"grid gap-3\">\n <Label htmlFor=\"name-1\">Name</Label>\n <Input id=\"name-1\" name=\"name\" defaultValue=\"Pedro Duarte\" />\n </div>\n <div className=\"grid gap-3\">\n <Label htmlFor=\"username-1\">Username</Label>\n <Input id=\"username-1\" name=\"username\" defaultValue=\"@peduarte\" />\n </div>\n </div>\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"outline\">Cancel</Button>\n </DialogClose>\n <Button type=\"submit\">Save changes</Button>\n </DialogFooter>\n </DialogContent>\n </form>\n </Dialog>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/drawer-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Minus, Plus } from \"lucide-react\"\nimport { Bar, BarChart, ResponsiveContainer } from \"recharts\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/registry/base-lyra/ui/drawer\"\n\nconst data = [\n {\n goal: 400,\n },\n {\n goal: 300,\n },\n {\n goal: 200,\n },\n {\n goal: 300,\n },\n {\n goal: 200,\n },\n {\n goal: 278,\n },\n {\n goal: 189,\n },\n {\n goal: 239,\n },\n {\n goal: 300,\n },\n {\n goal: 200,\n },\n {\n goal: 278,\n },\n {\n goal: 189,\n },\n {\n goal: 349,\n },\n]\n\nexport function DrawerDemo() {\n const [goal, setGoal] = React.useState(350)\n\n function onClick(adjustment: number) {\n setGoal(Math.max(200, Math.min(400, goal + adjustment)))\n }\n\n return (\n <Drawer>\n <DrawerTrigger asChild>\n <Button variant=\"outline\">Open Drawer</Button>\n </DrawerTrigger>\n <DrawerContent>\n <div className=\"mx-auto w-full max-w-sm\">\n <DrawerHeader>\n <DrawerTitle>Move Goal</DrawerTitle>\n <DrawerDescription>Set your daily activity goal.</DrawerDescription>\n </DrawerHeader>\n <div className=\"p-4 pb-0\">\n <div className=\"flex items-center justify-center space-x-2\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0 rounded-full\"\n onClick={() => onClick(-10)}\n disabled={goal <= 200}\n >\n <Minus />\n <span className=\"sr-only\">Decrease</span>\n </Button>\n <div className=\"flex-1 text-center\">\n <div className=\"text-7xl font-bold tracking-tighter\">\n {goal}\n </div>\n <div className=\"text-muted-foreground text-[0.70rem] uppercase\">\n Calories/day\n </div>\n </div>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0 rounded-full\"\n onClick={() => onClick(10)}\n disabled={goal >= 400}\n >\n <Plus />\n <span className=\"sr-only\">Increase</span>\n </Button>\n </div>\n <div className=\"mt-3 h-[120px]\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={data}>\n <Bar\n dataKey=\"goal\"\n style={\n {\n fill: \"hsl(var(--foreground))\",\n opacity: 0.9,\n } as React.CSSProperties\n }\n />\n </BarChart>\n </ResponsiveContainer>\n </div>\n </div>\n <DrawerFooter>\n <Button>Submit</Button>\n <DrawerClose asChild>\n <Button variant=\"outline\">Cancel</Button>\n </DrawerClose>\n </DrawerFooter>\n </div>\n </DrawerContent>\n </Drawer>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -13,8 +13,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/drawer-dialog.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { useMediaQuery } from \"@/hooks/use-media-query\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/registry/base-lyra/ui/dialog\"\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/registry/base-lyra/ui/drawer\"\nimport { Input } from \"@/registry/base-lyra/ui/input\"\nimport { Label } from \"@/registry/base-lyra/ui/label\"\n\nexport function DrawerDialogDemo() {\n const [open, setOpen] = React.useState(false)\n const isDesktop = useMediaQuery(\"(min-width: 768px)\")\n\n if (isDesktop) {\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\">Edit Profile</Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're\n done.\n </DialogDescription>\n </DialogHeader>\n <ProfileForm />\n </DialogContent>\n </Dialog>\n )\n }\n\n return (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>\n <Button variant=\"outline\">Edit Profile</Button>\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader className=\"text-left\">\n <DrawerTitle>Edit profile</DrawerTitle>\n <DrawerDescription>\n Make changes to your profile here. Click save when you're done.\n </DrawerDescription>\n </DrawerHeader>\n <ProfileForm className=\"px-4\" />\n <DrawerFooter className=\"pt-2\">\n <DrawerClose asChild>\n <Button variant=\"outline\">Cancel</Button>\n </DrawerClose>\n </DrawerFooter>\n </DrawerContent>\n </Drawer>\n )\n}\n\nfunction ProfileForm({ className }: React.ComponentProps<\"form\">) {\n return (\n <form className={cn(\"grid items-start gap-6\", className)}>\n <div className=\"grid gap-3\">\n <Label htmlFor=\"email\">Email</Label>\n <Input type=\"email\" id=\"email\" defaultValue=\"shadcn@example.com\" />\n </div>\n <div className=\"grid gap-3\">\n <Label htmlFor=\"username\">Username</Label>\n <Input id=\"username\" defaultValue=\"@shadcn\" />\n </div>\n <Button type=\"submit\">Save changes</Button>\n </form>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/dropdown-menu-checkboxes.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DropdownMenuCheckboxItemProps } from \"@radix-ui/react-dropdown-menu\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\ntype Checked = DropdownMenuCheckboxItemProps[\"checked\"]\n\nexport function DropdownMenuCheckboxes() {\n const [showStatusBar, setShowStatusBar] = React.useState<Checked>(true)\n const [showActivityBar, setShowActivityBar] = React.useState<Checked>(false)\n const [showPanel, setShowPanel] = React.useState<Checked>(false)\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\">Open</Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-56\">\n <DropdownMenuLabel>Appearance</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuCheckboxItem\n checked={showStatusBar}\n onCheckedChange={setShowStatusBar}\n >\n Status Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={showActivityBar}\n onCheckedChange={setShowActivityBar}\n disabled\n >\n Activity Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={showPanel}\n onCheckedChange={setShowPanel}\n >\n Panel\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/dropdown-menu-demo.tsx",
|
||||
"content": "import { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nexport function DropdownMenuDemo() {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\">Open</Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-56\" align=\"start\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuGroup>\n <DropdownMenuItem>\n Profile\n <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n Billing\n <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n Settings\n <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n Keyboard shortcuts\n <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>Team</DropdownMenuItem>\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent>\n <DropdownMenuItem>Email</DropdownMenuItem>\n <DropdownMenuItem>Message</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>More...</DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n <DropdownMenuItem>\n New Team\n <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>GitHub</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuItem disabled>API</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n Log out\n <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -15,8 +15,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/dropdown-menu-dialog.tsx",
|
||||
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { MoreHorizontalIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"@/registry/base-lyra/ui/dialog\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\nimport { Field, FieldGroup, FieldLabel } from \"@/registry/base-lyra/ui/field\"\nimport { Input } from \"@/registry/base-lyra/ui/input\"\nimport { Label } from \"@/registry/base-lyra/ui/label\"\nimport { Textarea } from \"@/registry/base-lyra/ui/textarea\"\n\nexport function DropdownMenuDialog() {\n const [showNewDialog, setShowNewDialog] = useState(false)\n const [showShareDialog, setShowShareDialog] = useState(false)\n\n return (\n <>\n <DropdownMenu modal={false}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" aria-label=\"Open menu\" size=\"icon-sm\">\n <MoreHorizontalIcon />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-40\" align=\"end\">\n <DropdownMenuLabel>File Actions</DropdownMenuLabel>\n <DropdownMenuGroup>\n <DropdownMenuItem onSelect={() => setShowNewDialog(true)}>\n New File...\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => setShowShareDialog(true)}>\n Share...\n </DropdownMenuItem>\n <DropdownMenuItem disabled>Download</DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n <Dialog open={showNewDialog} onOpenChange={setShowNewDialog}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Create New File</DialogTitle>\n <DialogDescription>\n Provide a name for your new file. Click create when you're\n done.\n </DialogDescription>\n </DialogHeader>\n <FieldGroup className=\"pb-3\">\n <Field>\n <FieldLabel htmlFor=\"filename\">File Name</FieldLabel>\n <Input id=\"filename\" name=\"filename\" placeholder=\"document.txt\" />\n </Field>\n </FieldGroup>\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"outline\">Cancel</Button>\n </DialogClose>\n <Button type=\"submit\">Create</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <Dialog open={showShareDialog} onOpenChange={setShowShareDialog}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Share File</DialogTitle>\n <DialogDescription>\n Anyone with the link will be able to view this file.\n </DialogDescription>\n </DialogHeader>\n <FieldGroup className=\"py-3\">\n <Field>\n <Label htmlFor=\"email\">Email Address</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n placeholder=\"shadcn@vercel.com\"\n autoComplete=\"off\"\n />\n </Field>\n <Field>\n <FieldLabel htmlFor=\"message\">Message (Optional)</FieldLabel>\n <Textarea\n id=\"message\"\n name=\"message\"\n placeholder=\"Check out this file\"\n />\n </Field>\n </FieldGroup>\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"outline\">Cancel</Button>\n </DialogClose>\n <Button type=\"submit\">Send Invite</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/dropdown-menu-radio-group.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/base-lyra/ui/dropdown-menu\"\n\nexport function DropdownMenuRadioGroupDemo() {\n const [position, setPosition] = React.useState(\"bottom\")\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\">Open</Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-56\">\n <DropdownMenuLabel>Panel Position</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuRadioGroup value={position} onValueChange={setPosition}>\n <DropdownMenuRadioItem value=\"top\">Top</DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"bottom\">Bottom</DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"right\">Right</DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/empty-avatar-group.tsx",
|
||||
"content": "import { PlusIcon } from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/registry/base-lyra/ui/avatar\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/registry/base-lyra/ui/empty\"\n\nexport default function EmptyAvatarGroup() {\n return (\n <Empty>\n <EmptyHeader>\n <EmptyMedia>\n <div className=\"*:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:size-12 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:grayscale\">\n <Avatar>\n <AvatarImage src=\"https://github.com/shadcn.png\" alt=\"@shadcn\" />\n <AvatarFallback>CN</AvatarFallback>\n </Avatar>\n <Avatar>\n <AvatarImage\n src=\"https://github.com/maxleiter.png\"\n alt=\"@maxleiter\"\n />\n <AvatarFallback>LR</AvatarFallback>\n </Avatar>\n <Avatar>\n <AvatarImage\n src=\"https://github.com/evilrabbit.png\"\n alt=\"@evilrabbit\"\n />\n <AvatarFallback>ER</AvatarFallback>\n </Avatar>\n </div>\n </EmptyMedia>\n <EmptyTitle>No Team Members</EmptyTitle>\n <EmptyDescription>\n Invite your team to collaborate on this project.\n </EmptyDescription>\n </EmptyHeader>\n <EmptyContent>\n <Button size=\"sm\">\n <PlusIcon />\n Invite Members\n </Button>\n </EmptyContent>\n </Empty>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/empty-avatar.tsx",
|
||||
"content": "import {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/registry/base-lyra/ui/avatar\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/registry/base-lyra/ui/empty\"\n\nexport default function EmptyAvatar() {\n return (\n <Empty>\n <EmptyHeader>\n <EmptyMedia variant=\"default\">\n <Avatar className=\"size-12\">\n <AvatarImage\n src=\"https://github.com/shadcn.png\"\n className=\"grayscale\"\n />\n <AvatarFallback>LR</AvatarFallback>\n </Avatar>\n </EmptyMedia>\n <EmptyTitle>User Offline</EmptyTitle>\n <EmptyDescription>\n This user is currently offline. You can leave a message to notify them\n or try again later.\n </EmptyDescription>\n </EmptyHeader>\n <EmptyContent>\n <Button size=\"sm\">Leave Message</Button>\n </EmptyContent>\n </Empty>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/empty-background.tsx",
|
||||
"content": "import { IconBell } from \"@tabler/icons-react\"\nimport { RefreshCcwIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/registry/base-lyra/ui/empty\"\n\nexport default function EmptyMuted() {\n return (\n <Empty className=\"from-muted/50 to-background h-full bg-gradient-to-b from-30%\">\n <EmptyHeader>\n <EmptyMedia variant=\"icon\">\n <IconBell />\n </EmptyMedia>\n <EmptyTitle>No Notifications</EmptyTitle>\n <EmptyDescription>\n You're all caught up. New notifications will appear here.\n </EmptyDescription>\n </EmptyHeader>\n <EmptyContent>\n <Button variant=\"outline\" size=\"sm\">\n <RefreshCcwIcon />\n Refresh\n </Button>\n </EmptyContent>\n </Empty>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/empty-demo.tsx",
|
||||
"content": "import { IconFolderCode } from \"@tabler/icons-react\"\nimport { ArrowUpRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/registry/base-lyra/ui/empty\"\n\nexport default function EmptyDemo() {\n return (\n <Empty>\n <EmptyHeader>\n <EmptyMedia variant=\"icon\">\n <IconFolderCode />\n </EmptyMedia>\n <EmptyTitle>No Projects Yet</EmptyTitle>\n <EmptyDescription>\n You haven't created any projects yet. Get started by creating\n your first project.\n </EmptyDescription>\n </EmptyHeader>\n <EmptyContent>\n <div className=\"flex gap-2\">\n <Button>Create Project</Button>\n <Button variant=\"outline\">Import Project</Button>\n </div>\n </EmptyContent>\n <Button\n variant=\"link\"\n asChild\n className=\"text-muted-foreground\"\n size=\"sm\"\n >\n <a href=\"#\">\n Learn More <ArrowUpRightIcon />\n </a>\n </Button>\n </Empty>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/empty-icon.tsx",
|
||||
"content": "import {\n IconBookmark,\n IconHeart,\n IconInbox,\n IconStar,\n} from \"@tabler/icons-react\"\n\nimport {\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/registry/base-lyra/ui/empty\"\n\nexport default function EmptyIcon() {\n return (\n <div className=\"grid gap-8 md:grid-cols-2\">\n <Empty>\n <EmptyHeader>\n <EmptyMedia variant=\"icon\">\n <IconInbox />\n </EmptyMedia>\n <EmptyTitle>No messages</EmptyTitle>\n <EmptyDescription>\n Your inbox is empty. New messages will appear here.\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n\n <Empty>\n <EmptyHeader>\n <EmptyMedia variant=\"icon\">\n <IconStar />\n </EmptyMedia>\n <EmptyTitle>No favorites</EmptyTitle>\n <EmptyDescription>\n Items you mark as favorites will appear here.\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n\n <Empty>\n <EmptyHeader>\n <EmptyMedia variant=\"icon\">\n <IconHeart />\n </EmptyMedia>\n <EmptyTitle>No likes yet</EmptyTitle>\n <EmptyDescription>\n Content you like will be saved here for easy access.\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n\n <Empty>\n <EmptyHeader>\n <EmptyMedia variant=\"icon\">\n <IconBookmark />\n </EmptyMedia>\n <EmptyTitle>No bookmarks</EmptyTitle>\n <EmptyDescription>\n Save interesting content by bookmarking it.\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n </div>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
{
|
||||
"path": "registry/base-lyra/demo/empty-input-group.tsx",
|
||||
"content": "import { SearchIcon } from \"lucide-react\"\n\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyTitle,\n} from \"@/registry/base-lyra/ui/empty\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@/registry/base-lyra/ui/input-group\"\nimport { Kbd } from \"@/registry/base-lyra/ui/kbd\"\n\nexport default function EmptyInputGroup() {\n return (\n <Empty>\n <EmptyHeader>\n <EmptyTitle>404 - Not Found</EmptyTitle>\n <EmptyDescription>\n The page you're looking for doesn't exist. Try searching for\n what you need below.\n </EmptyDescription>\n </EmptyHeader>\n <EmptyContent>\n <InputGroup className=\"sm:w-3/4\">\n <InputGroupInput placeholder=\"Try searching for pages...\" />\n <InputGroupAddon>\n <SearchIcon />\n </InputGroupAddon>\n <InputGroupAddon align=\"inline-end\">\n <Kbd>/</Kbd>\n </InputGroupAddon>\n </InputGroup>\n <EmptyDescription>\n Need help? <a href=\"#\">Contact support</a>\n </EmptyDescription>\n </EmptyContent>\n </Empty>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
],
|
||||
"type": "registry:example"
|
||||
"type": "registry:internal"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user