diff --git a/apps/v4/content/docs/components/base/combobox.mdx b/apps/v4/content/docs/components/base/combobox.mdx
index 65dd991c54a..1048f4eefdd 100644
--- a/apps/v4/content/docs/components/base/combobox.mdx
+++ b/apps/v4/content/docs/components/base/combobox.mdx
@@ -306,6 +306,8 @@ You can trigger the combobox from a button or any other component by using the `
+> If you render the Combobox inside a Dialog, set `modal={false}` on the `Popover` to ensure the search input remains editable.
+
### Input Group
You can add an addon to the combobox by using the `InputGroupAddon` component inside the `ComboboxInput`.
diff --git a/apps/v4/registry/radix-lyra/examples/accordion-example.tsx b/apps/v4/registry/radix-lyra/examples/accordion-example.tsx
new file mode 100644
index 00000000000..37881a5acc6
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/accordion-example.tsx
@@ -0,0 +1,345 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Accordion,
+ AccordionContent,
+ AccordionItem,
+ AccordionTrigger,
+} from "@/registry/radix-lyra/ui/accordion"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function AccordionExample() {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function AccordionBasic() {
+ const items = [
+ {
+ value: "item-1",
+ trigger: "Is it accessible?",
+ content: "Yes. It adheres to the WAI-ARIA design pattern.",
+ },
+ {
+ value: "item-2",
+ trigger: "Is it styled?",
+ content:
+ "Yes. It comes with default styles that matches the other components' aesthetic.",
+ },
+ {
+ value: "item-3",
+ trigger: "Is it animated?",
+ content:
+ "Yes. It's animated by default, but you can disable it if you prefer.",
+ },
+ ]
+
+ return (
+
+
+ {items.map((item) => (
+
+ {item.trigger}
+ {item.content}
+
+ ))}
+
+
+ )
+}
+
+function AccordionMultiple() {
+ const items = [
+ {
+ value: "item-1",
+ trigger:
+ "What are the key considerations when implementing a comprehensive enterprise-level authentication system?",
+ content:
+ "Implementing a robust enterprise authentication system requires careful consideration of multiple factors. This includes secure password hashing and storage, multi-factor authentication (MFA) implementation, session management, OAuth2 and SSO integration, regular security audits, rate limiting to prevent brute force attacks, and maintaining detailed audit logs. Additionally, you'll need to consider scalability, performance impact, and compliance with relevant data protection regulations such as GDPR or HIPAA.",
+ },
+ {
+ value: "item-2",
+ trigger:
+ "How does modern distributed system architecture handle eventual consistency and data synchronization across multiple regions?",
+ content:
+ "Modern distributed systems employ various strategies to maintain data consistency across regions. This often involves using techniques like CRDT (Conflict-Free Replicated Data Types), vector clocks, and gossip protocols. Systems might implement event sourcing patterns, utilize message queues for asynchronous updates, and employ sophisticated conflict resolution strategies. Popular solutions like Amazon's DynamoDB and Google's Spanner demonstrate different approaches to solving these challenges, balancing between consistency, availability, and partition tolerance as described in the CAP theorem.",
+ },
+ ]
+
+ return (
+
+
+ {items.map((item) => (
+
+ {item.trigger}
+ {item.content}
+
+ ))}
+
+
+ )
+}
+
+function AccordionWithBorders() {
+ const items = [
+ {
+ value: "billing",
+ trigger: "How does billing work?",
+ content:
+ "We offer monthly and annual subscription plans. Billing is charged at the beginning of each cycle, and you can cancel anytime. All plans include automatic backups, 24/7 support, and unlimited team members. There are no hidden fees or setup costs.",
+ },
+ {
+ value: "security",
+ trigger: "Is my data secure?",
+ content:
+ "Yes. We use end-to-end encryption, SOC 2 Type II compliance, and regular third-party security audits. All data is encrypted at rest and in transit using industry-standard protocols. We also offer optional two-factor authentication and single sign-on for enterprise customers.",
+ },
+ {
+ value: "integration",
+ trigger: "What integrations do you support?",
+ content: (
+ <>
+
+ We integrate with 500+ popular tools including Slack, Zapier,
+ Salesforce, HubSpot, and more. You can also build custom
+ integrations using our REST API and webhooks.{" "}
+
+
+ Our API documentation includes code examples in 10+ programming
+ languages.
+
+ >
+ ),
+ },
+ ]
+
+ return (
+
+
+ {items.map((item) => (
+
+
+ {item.trigger}
+
+
+ {item.content}
+
+
+ ))}
+
+
+ )
+}
+
+function AccordionInCard() {
+ const items = [
+ {
+ value: "plans",
+ trigger: "What subscription plans do you offer?",
+ content: (
+ <>
+
+ We offer three subscription tiers: Starter ($9/month), Professional
+ ($29/month), and Enterprise ($99/month). Each plan includes
+ increasing storage limits, API access, priority support, and team
+ collaboration features.
+
+
+ Annual billing is available with a 20% discount. All
+ plans include a 14-day free trial with no credit card required.
+
+
+ View plans
+
+
+ >
+ ),
+ },
+ {
+ value: "billing",
+ trigger: "How does billing work?",
+ content: (
+ <>
+
+ Billing occurs automatically at the start of each billing cycle. We
+ accept all major credit cards, PayPal, and ACH transfers for
+ enterprise customers.
+
+
+ You'll receive an invoice via email after each payment. You can
+ update your payment method or billing information anytime in your
+ account settings. Failed payments will trigger automated retry
+ attempts and email notifications.
+
+ >
+ ),
+ },
+ {
+ value: "upgrade",
+ trigger: "Can I upgrade or downgrade my plan?",
+ content: (
+ <>
+
+ Yes, you can change your plan at any time. When upgrading,
+ you'll be charged a prorated amount for the remainder of your
+ billing cycle and immediately gain access to new features.
+
+
+ When downgrading, the change takes effect at the end of your current
+ billing period, and you'll retain access to premium features
+ until then. No refunds are provided for downgrades.
+
+ >
+ ),
+ },
+ {
+ value: "cancel",
+ trigger: "How do I cancel my subscription?",
+ content: (
+ <>
+
+ You can cancel your subscription anytime from your account settings.
+ There are no cancellation fees or penalties. Your access will
+ continue until the end of your current billing period.
+
+
+ After cancellation, your data is retained for 30 days in case you
+ want to reactivate. You can export all your data before or after
+ canceling. We'd love to hear your feedback about why
+ you're leaving.
+
+ >
+ ),
+ },
+ {
+ value: "refund",
+ trigger: "What is your refund policy?",
+ content: (
+ <>
+
+ We offer a 30-day money-back guarantee for new subscriptions. If
+ you're not satisfied within the first 30 days, contact our
+ support team for a full refund.
+
+
+ After 30 days, we don't provide refunds for partial billing
+ periods, but you can cancel anytime to avoid future charges.
+ Enterprise customers have custom refund terms outlined in their
+ contracts.
+
+ >
+ ),
+ },
+ ]
+
+ return (
+
+
+
+ Subscription & Billing
+
+ Common questions about your account, plans, and payments
+
+
+
+
+ {items.map((item) => (
+
+ {item.trigger}
+ {item.content}
+
+ ))}
+
+
+
+
+ )
+}
+
+function AccordionWithDisabled() {
+ const items = [
+ {
+ value: "item-1",
+ trigger: "Can I access my account history?",
+ content:
+ "Yes, you can view your complete account history including all transactions, plan changes, and support tickets in the Account History section of your dashboard.",
+ disabled: false,
+ },
+ {
+ value: "item-2",
+ trigger: "Premium feature information",
+ content:
+ "This section contains information about premium features. Upgrade your plan to access this content.",
+ disabled: true,
+ },
+ {
+ value: "item-3",
+ trigger: "How do I update my email address?",
+ content:
+ "You can update your email address in your account settings. You'll receive a verification email at your new address to confirm the change.",
+ disabled: false,
+ },
+ ]
+
+ return (
+
+
+ {items.map((item) => (
+
+
+ {item.trigger}
+
+
+ {item.content}
+
+
+ ))}
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/alert-dialog-example.tsx b/apps/v4/registry/radix-lyra/examples/alert-dialog-example.tsx
new file mode 100644
index 00000000000..3f4e324b8b2
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/alert-dialog-example.tsx
@@ -0,0 +1,231 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogMedia,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@/registry/radix-lyra/ui/alert-dialog"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function AlertDialogExample() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+function AlertDialogBasic() {
+ return (
+
+
+
+ Default
+
+
+
+ Are you absolutely sure?
+
+ This action cannot be undone. This will permanently delete your
+ account and remove your data from our servers.
+
+
+
+ Cancel
+ Continue
+
+
+
+
+ )
+}
+
+function AlertDialogSmall() {
+ return (
+
+
+
+ Small
+
+
+
+ Allow accessory to connect?
+
+ Do you want to allow the USB accessory to connect to this device?
+
+
+
+ Don't allow
+ Allow
+
+
+
+
+ )
+}
+
+function AlertDialogWithMedia() {
+ return (
+
+
+
+ Default (Media)
+
+
+
+
+
+
+ Are you absolutely sure?
+
+ This will permanently delete your account and remove your data
+ from our servers.
+
+
+
+ Cancel
+ Continue
+
+
+
+
+ )
+}
+
+function AlertDialogSmallWithMedia() {
+ return (
+
+
+
+ Small (Media)
+
+
+
+
+
+
+ Allow accessory to connect?
+
+ Do you want to allow the USB accessory to connect to this device?
+
+
+
+ Don't allow
+ Allow
+
+
+
+
+ )
+}
+
+function AlertDialogDestructive() {
+ return (
+
+
+
+ Delete Chat
+
+
+
+
+
+
+ Delete chat?
+
+ This will permanently delete this chat conversation. View{" "}
+ Settings delete any memories saved during this
+ chat.
+
+
+
+ Cancel
+ Delete
+
+
+
+
+ )
+}
+
+function AlertDialogInDialog() {
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Alert Dialog Example
+
+ Click the button below to open an alert dialog.
+
+
+
+
+
+ Open Alert Dialog
+
+
+
+ Are you absolutely sure?
+
+ This action cannot be undone. This will permanently delete
+ your account and remove your data from our servers.
+
+
+
+ Cancel
+ Continue
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/alert-example.tsx b/apps/v4/registry/radix-lyra/examples/alert-example.tsx
new file mode 100644
index 00000000000..9ea34fcea5d
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/alert-example.tsx
@@ -0,0 +1,325 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Alert,
+ AlertAction,
+ AlertDescription,
+ AlertTitle,
+} from "@/registry/radix-lyra/ui/alert"
+import { Badge } from "@/registry/radix-lyra/ui/badge"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import { Field, FieldGroup, FieldLabel } from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ Item,
+ ItemContent,
+ ItemDescription,
+ ItemMedia,
+ ItemTitle,
+} from "@/registry/radix-lyra/ui/item"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function AlertExample() {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function AlertExample1() {
+ return (
+
+
+
+ Success! Your changes have been saved.
+
+
+ Success! Your changes have been saved.
+
+ This is an alert with title and description.
+
+
+
+
+ This one has a description only. No title. No icon.
+
+
+
+
+ )
+}
+
+function AlertExample2() {
+ return (
+
+
+
+
+
+ Let's try one with icon, title and a link .
+
+
+
+
+
+ This one has an icon and a description only. No title.{" "}
+ But it has a link and a second link .
+
+
+
+
+
+ Success! Your changes have been saved
+
+ This is an alert with icon, title and description.
+
+
+
+
+
+ This is a very long alert title that demonstrates how the component
+ handles extended text content and potentially wraps across multiple
+ lines
+
+
+
+
+
+ This is a very long alert description that demonstrates how the
+ component handles extended text content and potentially wraps across
+ multiple lines
+
+
+
+
+
+ This is an extremely long alert title that spans multiple lines to
+ demonstrate how the component handles very lengthy headings while
+ maintaining readability and proper text wrapping behavior
+
+
+ This is an equally long description that contains detailed
+ information about the alert. It shows how the component can
+ accommodate extensive content while preserving proper spacing,
+ alignment, and readability across different screen sizes and
+ viewport widths. This helps ensure the user experience remains
+ consistent regardless of the content length.
+
+
+
+
+ )
+}
+
+function AlertExample3() {
+ return (
+
+
+
+
+ Something went wrong!
+
+ Your session has expired. Please log in again.
+
+
+
+
+ Unable to process your payment.
+
+
+ Please verify your billing information and try
+ again.
+
+
+ Check your card details
+ Ensure sufficient funds
+ Verify billing address
+
+
+
+
+
+ )
+}
+
+function AlertExample4() {
+ return (
+
+
+
+
+ The selected emails have been marked as spam.
+
+ Undo
+
+
+
+
+ The selected emails have been marked as spam.
+
+ This is a very long alert title that demonstrates how the component
+ handles extended text content.
+
+
+ Badge
+
+
+
+
+ )
+}
+
+function AlertExample5() {
+ return (
+
+
+
+ Create project
+
+ Fill in the form below to create a new project.
+
+
+
+
+
+
+ You have reached the limit of 3 free projects.
+
+
+ Upgrade to Pro to create unlimited projects.
+
+
+
+
+ Name
+
+
+
+ Framework
+
+
+
+
+
+
+ Next.js
+ Remix
+ Astro
+ Nuxt
+
+
+
+
+
+ -
+
+
+
+
+ Project Alpha
+ Created 2 days ago
+
+
+
+
+ Create project
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/aspect-ratio-example.tsx b/apps/v4/registry/radix-lyra/examples/aspect-ratio-example.tsx
new file mode 100644
index 00000000000..7addd69cd1e
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/aspect-ratio-example.tsx
@@ -0,0 +1,90 @@
+import Image from "next/image"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { AspectRatio } from "@/registry/radix-lyra/ui/aspect-ratio"
+
+export default function AspectRatioExample() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+function AspectRatio16x9() {
+ return (
+
+
+
+
+
+ )
+}
+
+function AspectRatio1x1() {
+ return (
+
+
+
+
+
+ )
+}
+
+function AspectRatio9x16() {
+ return (
+
+
+
+
+
+ )
+}
+
+function AspectRatio21x9() {
+ return (
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/avatar-example.tsx b/apps/v4/registry/radix-lyra/examples/avatar-example.tsx
new file mode 100644
index 00000000000..e40eaaf60e3
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/avatar-example.tsx
@@ -0,0 +1,511 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Avatar,
+ AvatarBadge,
+ AvatarFallback,
+ AvatarGroup,
+ AvatarGroupCount,
+ AvatarImage,
+} from "@/registry/radix-lyra/ui/avatar"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Empty,
+ EmptyContent,
+ EmptyDescription,
+ EmptyHeader,
+ EmptyMedia,
+ EmptyTitle,
+} from "@/registry/radix-lyra/ui/empty"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function AvatarExample() {
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function AvatarSizes() {
+ return (
+
+
+
+
+ CN
+
+
+
+ CN
+
+
+
+ CN
+
+
+
+
+ CN
+
+
+ CN
+
+
+ CN
+
+
+
+ )
+}
+
+function AvatarWithBadge() {
+ return (
+
+
+
+
+ JZ
+
+
+
+
+ JZ
+
+
+
+
+ JZ
+
+
+
+
+
+ JZ
+
+
+
+ JZ
+
+
+
+ JZ
+
+
+
+
+ )
+}
+
+function AvatarWithBadgeIcon() {
+ return (
+
+
+
+
+ PP
+
+
+
+
+
+
+ PP
+
+
+
+
+
+
+ PP
+
+
+
+
+
+
+
+ PP
+
+
+
+
+
+ PP
+
+
+
+
+
+ PP
+
+
+
+
+
+
+ )
+}
+
+function AvatarGroupExample() {
+ return (
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+
+
+ )
+}
+
+function AvatarGroupWithCount() {
+ return (
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+ +3
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+ +3
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+ +3
+
+
+ )
+}
+
+function AvatarGroupWithIconCount() {
+ return (
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+
+
+
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+
+
+
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+
+
+
+
+
+ )
+}
+
+function AvatarInEmpty() {
+ return (
+
+
+
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+
+
+
+
+
+ No Team Members
+
+ Invite your team to collaborate on this project.
+
+
+
+
+
+ Invite Members
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/badge-example.tsx b/apps/v4/registry/radix-lyra/examples/badge-example.tsx
new file mode 100644
index 00000000000..a81b4c0acae
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/badge-example.tsx
@@ -0,0 +1,354 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Badge } from "@/registry/radix-lyra/ui/badge"
+import { Spinner } from "@/registry/radix-lyra/ui/spinner"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function BadgeExample() {
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function BadgeVariants() {
+ return (
+
+
+ Default
+ Secondary
+ Destructive
+ Outline
+ Ghost
+ Link
+
+
+ )
+}
+
+function BadgeWithIconLeft() {
+ return (
+
+
+
+
+ Default
+
+
+
+ Secondary
+
+
+
+ Destructive
+
+
+
+ Outline
+
+
+
+ Ghost
+
+
+
+ Link
+
+
+
+ )
+}
+
+function BadgeWithIconRight() {
+ return (
+
+
+
+ Default
+
+
+
+ Secondary
+
+
+
+ Destructive
+
+
+
+ Outline
+
+
+
+ Ghost
+
+
+
+ Link
+
+
+
+
+ )
+}
+
+function BadgeWithSpinner() {
+ return (
+
+
+
+
+ Default
+
+
+
+ Secondary
+
+
+
+ Destructive
+
+
+
+ Outline
+
+
+
+ Ghost
+
+
+
+ Link
+
+
+
+ )
+}
+
+function BadgeAsLink() {
+ return (
+
+
+
+ )
+}
+
+function BadgeLongText() {
+ return (
+
+
+
+ A badge with a lot of text to see how it wraps
+
+
+
+ )
+}
+
+function BadgeCustomColors() {
+ return (
+
+
+
+ Blue
+
+
+ Green
+
+
+ Sky
+
+
+ Purple
+
+
+ Blue
+
+
+ Green
+
+
+ Sky
+
+
+ Purple
+
+
+ Red
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/breadcrumb-example.tsx b/apps/v4/registry/radix-lyra/examples/breadcrumb-example.tsx
new file mode 100644
index 00000000000..c6b8924b83d
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/breadcrumb-example.tsx
@@ -0,0 +1,122 @@
+import Link from "next/link"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Breadcrumb,
+ BreadcrumbEllipsis,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbList,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+} from "@/registry/radix-lyra/ui/breadcrumb"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/registry/radix-lyra/ui/dropdown-menu"
+
+export default function BreadcrumbExample() {
+ return (
+
+
+
+
+
+ )
+}
+
+function BreadcrumbBasic() {
+ return (
+
+
+
+
+ Home
+
+
+
+ Components
+
+
+
+ Breadcrumb
+
+
+
+
+ )
+}
+
+function BreadcrumbWithDropdown() {
+ return (
+
+
+
+
+ Home
+
+
+
+
+
+
+
+ Toggle menu
+
+
+
+ Documentation
+ Themes
+ GitHub
+
+
+
+
+
+ Components
+
+
+
+ Breadcrumb
+
+
+
+
+ )
+}
+
+function BreadcrumbWithLink() {
+ return (
+
+
+
+
+
+ Home
+
+
+
+
+
+
+
+
+
+ Components
+
+
+
+
+ Breadcrumb
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/button-example.tsx b/apps/v4/registry/radix-lyra/examples/button-example.tsx
new file mode 100644
index 00000000000..8cb443d5747
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/button-example.tsx
@@ -0,0 +1,998 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function ButtonExample() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonVariantsAndSizes() {
+ return (
+
+
+ Default
+
+ Secondary
+
+
+ Outline
+
+
+ Ghost
+
+
+ Destructive
+
+
+ Link
+
+
+
+ Default
+
+ Secondary
+
+
+ Outline
+
+
+ Ghost
+
+
+ Destructive
+
+
+ Link
+
+
+
+ Default
+ Secondary
+ Outline
+ Ghost
+ Destructive
+ Link
+
+
+ Default
+
+ Secondary
+
+
+ Outline
+
+
+ Ghost
+
+
+ Destructive
+
+
+ Link
+
+
+
+ )
+}
+
+function ButtonIconRight() {
+ return (
+
+
+
+ Default{" "}
+
+
+
+ Secondary{" "}
+
+
+
+ Outline{" "}
+
+
+
+ Ghost{" "}
+
+
+
+ Destructive{" "}
+
+
+
+ Link{" "}
+
+
+
+
+
+ Default
+
+
+
+ Secondary{" "}
+
+
+
+ Outline{" "}
+
+
+
+ Ghost{" "}
+
+
+
+ Destructive{" "}
+
+
+
+ Link{" "}
+
+
+
+
+
+ Default{" "}
+
+
+
+ Secondary{" "}
+
+
+
+ Outline{" "}
+
+
+
+ Ghost{" "}
+
+
+
+ Destructive{" "}
+
+
+
+ Link{" "}
+
+
+
+
+
+ Default{" "}
+
+
+
+ Secondary{" "}
+
+
+
+ Outline{" "}
+
+
+
+ Ghost{" "}
+
+
+
+ Destructive{" "}
+
+
+
+ Link{" "}
+
+
+
+
+ )
+}
+
+function ButtonIconLeft() {
+ return (
+
+
+
+ {" "}
+ Default
+
+
+ {" "}
+ Secondary
+
+
+ {" "}
+ Outline
+
+
+ {" "}
+ Ghost
+
+
+ {" "}
+ Destructive
+
+
+ {" "}
+ Link
+
+
+
+
+ {" "}
+ Default
+
+
+ {" "}
+ Secondary
+
+
+ {" "}
+ Outline
+
+
+ {" "}
+ Ghost
+
+
+ {" "}
+ Destructive
+
+
+ {" "}
+ Link
+
+
+
+
+ {" "}
+ Default
+
+
+ {" "}
+ Secondary
+
+
+ {" "}
+ Outline
+
+
+ {" "}
+ Ghost
+
+
+ {" "}
+ Destructive
+
+
+ {" "}
+ Link
+
+
+
+
+ {" "}
+ Default
+
+
+ {" "}
+ Secondary
+
+
+ {" "}
+ Outline
+
+
+ {" "}
+ Ghost
+
+
+ {" "}
+ Destructive
+
+
+ {" "}
+ Link
+
+
+
+ )
+}
+
+function ButtonIconOnly() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonExamples() {
+ return (
+
+
+
+ Cancel
+
+ Submit{" "}
+
+
+
+
+ Delete
+
+
+
+
+
+
+ )
+}
+
+function ButtonInvalidStates() {
+ return (
+
+
+
+ Default
+
+
+ Secondary
+
+
+ Outline
+
+
+ Ghost
+
+
+ Destructive
+
+
+ Link
+
+
+
+
+ Default
+
+
+ Secondary
+
+
+ Outline
+
+
+ Ghost
+
+
+ Destructive
+
+
+ Link
+
+
+
+ Default
+
+ Secondary
+
+
+ Outline
+
+
+ Ghost
+
+
+ Destructive
+
+
+ Link
+
+
+
+
+ Default
+
+
+ Secondary
+
+
+ Outline
+
+
+ Ghost
+
+
+ Destructive
+
+
+ Link
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/button-group-example.tsx b/apps/v4/registry/radix-lyra/examples/button-group-example.tsx
new file mode 100644
index 00000000000..50f2296c496
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/button-group-example.tsx
@@ -0,0 +1,737 @@
+"use client"
+
+import { useState } from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ ButtonGroup,
+ ButtonGroupText,
+} from "@/registry/radix-lyra/ui/button-group"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/registry/radix-lyra/ui/dropdown-menu"
+import { Field, FieldGroup } from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+} from "@/registry/radix-lyra/ui/input-group"
+import { Label } from "@/registry/radix-lyra/ui/label"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/registry/radix-lyra/ui/tooltip"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function ButtonGroupExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupBasic() {
+ return (
+
+
+
+ Button
+ Another Button
+
+
+
+ )
+}
+
+function ButtonGroupWithInput() {
+ return (
+
+
+
+ Button
+
+
+
+
+ Button
+
+
+
+ )
+}
+
+function ButtonGroupWithText() {
+ return (
+
+
+
+ Text
+ Another Button
+
+
+
+ GPU Size
+
+
+
+
+
+ )
+}
+
+function ButtonGroupWithDropdown() {
+ return (
+
+
+
+ Update
+
+
+
+
+
+
+
+ Disable
+
+ Uninstall
+
+
+
+
+
+ Follow
+
+
+
+
+
+
+
+
+
+
+ Mute Conversation
+
+
+
+ Mark as Read
+
+
+
+ Report Conversation
+
+
+
+ Block User
+
+
+
+ Share Conversation
+
+
+
+ Copy Conversation
+
+
+
+
+
+
+ Delete Conversation
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupWithSelect() {
+ const [currency, setCurrency] = useState("$")
+
+ return (
+
+
+ Amount
+
+
+
+
+
+
+
+ $
+ €
+ £
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupWithIcons() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupWithInputGroup() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupWithFields() {
+ return (
+
+
+
+ Width
+
+
+
+
+ W
+
+
+ px
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupWithLike() {
+ return (
+
+
+
+ {" "}
+ Like
+
+
+ 1.2K
+
+
+
+ )
+}
+
+function ButtonGroupWithSelectAndInput() {
+ return (
+
+
+
+
+
+
+
+
+ Hours
+ Days
+ Weeks
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupNested() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Voice Mode
+
+
+
+
+
+ )
+}
+
+function ButtonGroupPagination() {
+ return (
+
+
+
+
+ Previous
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ Next
+
+
+
+
+ )
+}
+
+function ButtonGroupPaginationSplit() {
+ return (
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupNavigation() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupTextAlignment() {
+ return (
+
+
+ Text Alignment
+
+
+ Left
+
+
+ Center
+
+
+ Right
+
+
+ Justify
+
+
+
+
+ )
+}
+
+function ButtonGroupVertical() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ButtonGroupVerticalNested() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/calendar-example.tsx b/apps/v4/registry/radix-lyra/examples/calendar-example.tsx
new file mode 100644
index 00000000000..798101c7516
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/calendar-example.tsx
@@ -0,0 +1,536 @@
+"use client"
+
+import * as React from "react"
+import { addDays, format } from "date-fns"
+import { type DateRange } from "react-day-picker"
+import { es } from "react-day-picker/locale"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import { Calendar, CalendarDayButton } from "@/registry/radix-lyra/ui/calendar"
+import { Card, CardContent, CardFooter } from "@/registry/radix-lyra/ui/card"
+import { Field, FieldGroup, FieldLabel } from "@/registry/radix-lyra/ui/field"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+} from "@/registry/radix-lyra/ui/input-group"
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/registry/radix-lyra/ui/popover"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function CalendarExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function CalendarInCard() {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function CalendarInPopover() {
+ return (
+
+
+
+
+
+ Open Calendar
+
+
+
+
+
+
+
+ )
+}
+
+function CalendarSingle() {
+ const [date, setDate] = React.useState(
+ new Date(new Date().getFullYear(), new Date().getMonth(), 12)
+ )
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function CalendarMultiple() {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function CalendarRange() {
+ const [dateRange, setDateRange] = React.useState({
+ from: new Date(new Date().getFullYear(), 0, 12),
+ to: addDays(new Date(new Date().getFullYear(), 0, 12), 30),
+ })
+
+ return (
+
+
+
+
+ date > new Date() || date < new Date("1900-01-01")
+ }
+ />
+
+
+
+ )
+}
+
+function CalendarRangeMultipleMonths() {
+ const [range, setRange] = React.useState({
+ from: new Date(new Date().getFullYear(), 3, 12),
+ to: addDays(new Date(new Date().getFullYear(), 3, 12), 60),
+ })
+
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function CalendarBookedDates() {
+ const [date, setDate] = React.useState(
+ new Date(new Date().getFullYear(), 1, 3)
+ )
+ const bookedDates = Array.from(
+ { length: 15 },
+ (_, i) => new Date(new Date().getFullYear(), 1, 12 + i)
+ )
+
+ return (
+
+
+
+ button]:line-through opacity-100",
+ }}
+ />
+
+
+
+ )
+}
+
+function CalendarWithTime() {
+ const [date, setDate] = React.useState(
+ new Date(new Date().getFullYear(), new Date().getMonth(), 12)
+ )
+
+ return (
+
+
+
+
+
+
+
+
+ Start Time
+
+
+
+
+
+
+
+
+ End Time
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function CalendarCustomDays() {
+ const [range, setRange] = React.useState({
+ from: new Date(new Date().getFullYear(), 11, 8),
+ to: addDays(new Date(new Date().getFullYear(), 11, 8), 10),
+ })
+
+ return (
+
+
+
+ {
+ return date.toLocaleString("default", { month: "long" })
+ },
+ }}
+ components={{
+ DayButton: ({ children, modifiers, day, ...props }) => {
+ const isWeekend =
+ day.date.getDay() === 0 || day.date.getDay() === 6
+
+ return (
+
+ {children}
+ {!modifiers.outside && (
+ {isWeekend ? "$120" : "$100"}
+ )}
+
+ )
+ },
+ }}
+ />
+
+
+
+ )
+}
+
+function CalendarWithPresets() {
+ const [date, setDate] = React.useState(
+ new Date(new Date().getFullYear(), 1, 12)
+ )
+ const [currentMonth, setCurrentMonth] = React.useState(
+ new Date(new Date().getFullYear(), new Date().getMonth(), 1)
+ )
+
+ return (
+
+
+
+
+
+
+ {[
+ { label: "Today", value: 0 },
+ { label: "Tomorrow", value: 1 },
+ { label: "In 3 days", value: 3 },
+ { label: "In a week", value: 7 },
+ { label: "In 2 weeks", value: 14 },
+ ].map((preset) => (
+ {
+ const newDate = addDays(new Date(), preset.value)
+ setDate(newDate)
+ setCurrentMonth(
+ new Date(newDate.getFullYear(), newDate.getMonth(), 1)
+ )
+ }}
+ >
+ {preset.label}
+
+ ))}
+
+
+
+ )
+}
+
+function DatePickerSimple() {
+ const [date, setDate] = React.useState()
+
+ return (
+
+
+ Date
+
+
+
+
+ {date ? format(date, "PPP") : Pick a date }
+
+
+
+
+
+
+
+
+ )
+}
+
+function DatePickerWithRange() {
+ const [date, setDate] = React.useState({
+ from: new Date(new Date().getFullYear(), 0, 20),
+ to: addDays(new Date(new Date().getFullYear(), 0, 20), 20),
+ })
+
+ return (
+
+
+ Date Picker Range
+
+
+
+
+ {date?.from ? (
+ date.to ? (
+ <>
+ {format(date.from, "LLL dd, y")} -{" "}
+ {format(date.to, "LLL dd, y")}
+ >
+ ) : (
+ format(date.from, "LLL dd, y")
+ )
+ ) : (
+ Pick a date
+ )}
+
+
+
+
+
+
+
+
+ )
+}
+
+function DataPickerWithDropdowns() {
+ const [date, setDate] = React.useState()
+ const [open, setOpen] = React.useState(false)
+
+ return (
+
+
+
+
+ Date
+
+
+
+ {date ? format(date, "PPP") : Pick a date }
+
+
+
+
+
+
+ setOpen(false)}
+ >
+ Done
+
+
+
+
+
+
+ )
+}
+
+function CalendarWeekNumbers() {
+ const [date, setDate] = React.useState(
+ new Date(new Date().getFullYear(), 1, 3)
+ )
+
+ return (
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/card-example.tsx b/apps/v4/registry/radix-lyra/examples/card-example.tsx
new file mode 100644
index 00000000000..9c18515429a
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/card-example.tsx
@@ -0,0 +1,367 @@
+import Image from "next/image"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Avatar,
+ AvatarFallback,
+ AvatarGroup,
+ AvatarGroupCount,
+ AvatarImage,
+} from "@/registry/radix-lyra/ui/avatar"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Card,
+ CardAction,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import { Field, FieldGroup, FieldLabel } from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function CardExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function CardLogin() {
+ return (
+
+
+
+ Login to your account
+
+ Enter your email below to login to your account
+
+
+
+
+
+
+
+ Login
+
+
+ Login with Google
+
+
+
+
+
+ )
+}
+
+function CardMeetingNotes() {
+ return (
+
+
+
+ Meeting Notes
+
+ Transcript from the meeting with the client.
+
+
+
+
+ Transcribe
+
+
+
+
+
+ Client requested dashboard redesign with focus on mobile
+ responsiveness.
+
+
+ New analytics widgets for daily/weekly metrics
+ Simplified navigation menu
+ Dark mode support
+ Timeline: 6 weeks
+ Follow-up meeting scheduled for next Tuesday
+
+
+
+
+
+
+ CN
+
+
+
+ LR
+
+
+
+ ER
+
+ +8
+
+
+
+
+ )
+}
+
+function CardWithImage() {
+ return (
+
+
+
+
+
+ Beautiful Landscape
+
+ A stunning view that captures the essence of natural beauty.
+
+
+
+
+
+ Button
+
+
+
+
+ )
+}
+
+function CardWithImageSmall() {
+ return (
+
+
+
+
+
+ Beautiful Landscape
+
+ A stunning view that captures the essence of natural beauty.
+
+
+
+
+
+ Button
+
+
+
+
+ )
+}
+
+function CardHeaderWithBorder() {
+ return (
+
+
+
+ Header with Border
+
+ This is a card with a header that has a bottom border.
+
+
+
+
+ The header has a border-b class applied, creating a visual
+ separation between the header and content sections.
+
+
+
+
+ )
+}
+
+function CardFooterWithBorder() {
+ return (
+
+
+
+
+ The footer has a border-t class applied, creating a visual
+ separation between the content and footer sections.
+
+
+
+
+ Footer with Border
+
+
+
+
+ )
+}
+
+function CardDefault() {
+ return (
+
+
+
+ Default Card
+
+ This card uses the default size variant.
+
+
+
+
+ The card component supports a size prop that defaults to
+ "default" for standard spacing and sizing.
+
+
+
+
+ Action
+
+
+
+
+ )
+}
+
+function CardSmall() {
+ return (
+
+
+
+ Small Card
+
+ This card uses the small size variant.
+
+
+
+
+ The card component supports a size prop that can be set to
+ "sm" for a more compact appearance.
+
+
+
+
+ Action
+
+
+
+
+ )
+}
+
+function CardHeaderWithBorderSmall() {
+ return (
+
+
+
+ Header with Border
+
+ This is a small card with a header that has a bottom border.
+
+
+
+
+ The header has a border-b class applied, creating a visual
+ separation between the header and content sections.
+
+
+
+
+ )
+}
+
+function CardFooterWithBorderSmall() {
+ return (
+
+
+
+
+ The footer has a border-t class applied, creating a visual
+ separation between the content and footer sections.
+
+
+
+
+ Footer with Border
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/carousel-example.tsx b/apps/v4/registry/radix-lyra/examples/carousel-example.tsx
new file mode 100644
index 00000000000..3a7089af21e
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/carousel-example.tsx
@@ -0,0 +1,99 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Card, CardContent } from "@/registry/radix-lyra/ui/card"
+import {
+ Carousel,
+ CarouselContent,
+ CarouselItem,
+ CarouselNext,
+ CarouselPrevious,
+} from "@/registry/radix-lyra/ui/carousel"
+
+export default function CarouselExample() {
+ return (
+
+
+
+
+
+ )
+}
+
+function CarouselBasic() {
+ return (
+
+
+
+ {Array.from({ length: 5 }).map((_, index) => (
+
+
+
+
+ {index + 1}
+
+
+
+
+ ))}
+
+
+
+
+
+ )
+}
+
+function CarouselMultiple() {
+ return (
+
+
+
+ {Array.from({ length: 5 }).map((_, index) => (
+
+
+
+
+ {index + 1}
+
+
+
+
+ ))}
+
+
+
+
+
+ )
+}
+
+function CarouselWithGap() {
+ return (
+
+
+
+ {Array.from({ length: 5 }).map((_, index) => (
+
+
+
+
+ {index + 1}
+
+
+
+
+ ))}
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/chart-example.tsx b/apps/v4/registry/radix-lyra/examples/chart-example.tsx
new file mode 100644
index 00000000000..b8e0b2a82d1
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/chart-example.tsx
@@ -0,0 +1,594 @@
+"use client"
+
+import * as React from "react"
+import {
+ Area,
+ AreaChart,
+ Bar,
+ BarChart,
+ CartesianGrid,
+ Label,
+ Line,
+ LineChart,
+ Pie,
+ PieChart,
+ PolarAngleAxis,
+ PolarGrid,
+ PolarRadiusAxis,
+ Radar,
+ RadarChart,
+ RadialBar,
+ RadialBarChart,
+ XAxis,
+} from "recharts"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import {
+ ChartContainer,
+ ChartTooltip,
+ ChartTooltipContent,
+ type ChartConfig,
+} from "@/registry/radix-lyra/ui/chart"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params"
+
+const areaChartData = [
+ { month: "January", desktop: 186 },
+ { month: "February", desktop: 305 },
+ { month: "March", desktop: 237 },
+ { month: "April", desktop: 73 },
+ { month: "May", desktop: 209 },
+ { month: "June", desktop: 214 },
+]
+
+const areaChartConfig = {
+ desktop: {
+ label: "Desktop",
+ color: "var(--chart-1)",
+ },
+} satisfies ChartConfig
+
+export default function ChartExample() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+function ChartAreaExample() {
+ return (
+
+
+
+ Area Chart
+
+ Showing total visitors for the last 6 months
+
+
+
+
+
+
+ value.slice(0, 3)}
+ />
+ }
+ />
+
+
+
+
+
+
+
+
+ Trending up by 5.2% this month{" "}
+
+
+
+ January - June 2024
+
+
+
+
+
+
+ )
+}
+
+const barChartData = [
+ { month: "January", desktop: 186, mobile: 80 },
+ { month: "February", desktop: 305, mobile: 200 },
+ { month: "March", desktop: 237, mobile: 120 },
+ { month: "April", desktop: 73, mobile: 190 },
+ { month: "May", desktop: 209, mobile: 130 },
+ { month: "June", desktop: 214, mobile: 140 },
+]
+
+const barChartConfig = {
+ desktop: {
+ label: "Desktop",
+ color: "var(--chart-1)",
+ },
+ mobile: {
+ label: "Mobile",
+ color: "var(--chart-2)",
+ },
+} satisfies ChartConfig
+
+function ChartBarExample() {
+ const [params] = useDesignSystemSearchParams()
+ const isRounded = !["lyra", "sera"].includes(params.style)
+
+ return (
+
+
+
+ Bar Chart - Multiple
+ January - June 2024
+
+
+
+
+
+ value.slice(0, 3)}
+ />
+ }
+ />
+
+
+
+
+
+
+
+ Trending up by 5.2% this month{" "}
+
+
+
+ Showing total visitors for the last 6 months
+
+
+
+
+ )
+}
+
+const lineChartData = [
+ { month: "January", desktop: 186, mobile: 80 },
+ { month: "February", desktop: 305, mobile: 200 },
+ { month: "March", desktop: 237, mobile: 120 },
+ { month: "April", desktop: 73, mobile: 190 },
+ { month: "May", desktop: 209, mobile: 130 },
+ { month: "June", desktop: 214, mobile: 140 },
+]
+
+const lineChartConfig = {
+ desktop: {
+ label: "Desktop",
+ color: "var(--chart-1)",
+ },
+ mobile: {
+ label: "Mobile",
+ color: "var(--chart-2)",
+ },
+} satisfies ChartConfig
+
+function ChartLineExample() {
+ return (
+
+
+
+ Line Chart - Multiple
+ January - June 2024
+
+
+
+
+
+ value.slice(0, 3)}
+ />
+ } />
+
+
+
+
+
+
+
+
+
+ Trending up by 5.2% this month{" "}
+
+
+
+ Showing total visitors for the last 6 months
+
+
+
+
+
+
+ )
+}
+
+const pieChartData = [
+ { browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
+ { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
+ { browser: "firefox", visitors: 287, fill: "var(--color-firefox)" },
+ { browser: "edge", visitors: 173, fill: "var(--color-edge)" },
+ { browser: "other", visitors: 190, fill: "var(--color-other)" },
+]
+
+const pieChartConfig = {
+ visitors: {
+ label: "Visitors",
+ },
+ chrome: {
+ label: "Chrome",
+ color: "var(--chart-1)",
+ },
+ safari: {
+ label: "Safari",
+ color: "var(--chart-2)",
+ },
+ firefox: {
+ label: "Firefox",
+ color: "var(--chart-3)",
+ },
+ edge: {
+ label: "Edge",
+ color: "var(--chart-4)",
+ },
+ other: {
+ label: "Other",
+ color: "var(--chart-5)",
+ },
+} satisfies ChartConfig
+
+function ChartPieExample() {
+ const totalVisitors = React.useMemo(() => {
+ return pieChartData.reduce((acc, curr) => acc + curr.visitors, 0)
+ }, [])
+
+ return (
+
+
+
+ Pie Chart - Donut with Text
+ January - June 2024
+
+
+
+
+ }
+ />
+
+ {
+ if (viewBox && "cx" in viewBox && "cy" in viewBox) {
+ return (
+
+
+ {totalVisitors.toLocaleString()}
+
+
+ Visitors
+
+
+ )
+ }
+ }}
+ />
+
+
+
+
+
+
+ Trending up by 5.2% this month{" "}
+
+
+
+ Showing total visitors for the last 6 months
+
+
+
+
+ )
+}
+
+const radarChartData = [
+ { month: "January", desktop: 186, mobile: 80 },
+ { month: "February", desktop: 305, mobile: 200 },
+ { month: "March", desktop: 237, mobile: 120 },
+ { month: "April", desktop: 73, mobile: 190 },
+ { month: "May", desktop: 209, mobile: 130 },
+ { month: "June", desktop: 214, mobile: 140 },
+]
+
+const radarChartConfig = {
+ desktop: {
+ label: "Desktop",
+ color: "var(--chart-1)",
+ },
+ mobile: {
+ label: "Mobile",
+ color: "var(--chart-2)",
+ },
+} satisfies ChartConfig
+
+function ChartRadarExample() {
+ return (
+
+
+
+ Radar Chart - Multiple
+
+ Showing total visitors for the last 6 months
+
+
+
+
+
+ }
+ />
+
+
+
+
+
+
+
+
+
+ Trending up by 5.2% this month{" "}
+
+
+
+ January - June 2024
+
+
+
+
+ )
+}
+
+const radialChartData = [
+ { browser: "safari", visitors: 1260, fill: "var(--color-safari)" },
+]
+
+const radialChartConfig = {
+ visitors: {
+ label: "Visitors",
+ },
+ safari: {
+ label: "Safari",
+ color: "var(--chart-2)",
+ },
+} satisfies ChartConfig
+
+function ChartRadialExample() {
+ return (
+
+
+
+ Radial Chart - Shape
+ January - June 2024
+
+
+
+
+
+
+
+ {
+ if (viewBox && "cx" in viewBox && "cy" in viewBox) {
+ return (
+
+
+ {radialChartData[0].visitors.toLocaleString()}
+
+
+ Visitors
+
+
+ )
+ }
+ }}
+ />
+
+
+
+
+
+
+ Trending up by 5.2% this month{" "}
+
+
+
+ Showing total visitors for the last 6 months
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/checkbox-example.tsx b/apps/v4/registry/radix-lyra/examples/checkbox-example.tsx
new file mode 100644
index 00000000000..85a2537073e
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/checkbox-example.tsx
@@ -0,0 +1,260 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Checkbox } from "@/registry/radix-lyra/ui/checkbox"
+import {
+ Field,
+ FieldContent,
+ FieldDescription,
+ FieldGroup,
+ FieldLabel,
+ FieldTitle,
+} from "@/registry/radix-lyra/ui/field"
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/registry/radix-lyra/ui/table"
+
+export default function CheckboxExample() {
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function CheckboxBasic() {
+ return (
+
+
+
+ Accept terms and conditions
+
+
+ )
+}
+
+function CheckboxWithDescription() {
+ return (
+
+
+
+
+ Accept terms and conditions
+
+ By clicking this checkbox, you agree to the terms and conditions.
+
+
+
+
+ )
+}
+
+function CheckboxInvalid() {
+ return (
+
+
+
+ Accept terms and conditions
+
+
+ )
+}
+
+function CheckboxDisabled() {
+ return (
+
+
+
+ Enable notifications
+
+
+ )
+}
+
+function CheckboxWithTitle() {
+ return (
+
+
+
+
+
+
+ Enable notifications
+
+ You can enable or disable notifications at any time.
+
+
+
+
+
+
+
+
+ Enable notifications
+
+ You can enable or disable notifications at any time.
+
+
+
+
+
+
+ )
+}
+
+const tableData = [
+ {
+ id: "1",
+ name: "Sarah Chen",
+ email: "sarah.chen@example.com",
+ role: "Admin",
+ },
+ {
+ id: "2",
+ name: "Marcus Rodriguez",
+ email: "marcus.rodriguez@example.com",
+ role: "User",
+ },
+ {
+ id: "3",
+ name: "Priya Patel",
+ email: "priya.patel@example.com",
+ role: "User",
+ },
+ {
+ id: "4",
+ name: "David Kim",
+ email: "david.kim@example.com",
+ role: "Editor",
+ },
+]
+
+function CheckboxInTable() {
+ const [selectedRows, setSelectedRows] = React.useState>(
+ new Set(["1"])
+ )
+
+ const selectAll = selectedRows.size === tableData.length
+
+ const handleSelectAll = (checked: boolean) => {
+ if (checked) {
+ setSelectedRows(new Set(tableData.map((row) => row.id)))
+ } else {
+ setSelectedRows(new Set())
+ }
+ }
+
+ const handleSelectRow = (id: string, checked: boolean) => {
+ const newSelected = new Set(selectedRows)
+ if (checked) {
+ newSelected.add(id)
+ } else {
+ newSelected.delete(id)
+ }
+ setSelectedRows(newSelected)
+ }
+
+ return (
+
+
+
+
+
+
+
+ Name
+ Email
+ Role
+
+
+
+ {tableData.map((row) => (
+
+
+
+ handleSelectRow(row.id, checked === true)
+ }
+ />
+
+ {row.name}
+ {row.email}
+ {row.role}
+
+ ))}
+
+
+
+ )
+}
+
+function CheckboxGroup() {
+ return (
+
+
+ Show these items on the desktop:
+
+
+
+ Hard disks
+
+
+
+
+
+ External disks
+
+
+
+
+
+ CDs, DVDs, and iPods
+
+
+
+
+
+ Connected servers
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/collapsible-example.tsx b/apps/v4/registry/radix-lyra/examples/collapsible-example.tsx
new file mode 100644
index 00000000000..cd43c72294d
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/collapsible-example.tsx
@@ -0,0 +1,239 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import {
+ Collapsible,
+ CollapsibleContent,
+ CollapsibleTrigger,
+} from "@/registry/radix-lyra/ui/collapsible"
+import { Field, FieldGroup, FieldLabel } from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import { Tabs, TabsList, TabsTrigger } from "@/registry/radix-lyra/ui/tabs"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function CollapsibleExample() {
+ return (
+
+
+
+
+ )
+}
+
+type FileTreeItem = { name: string } | { name: string; items: FileTreeItem[] }
+
+function CollapsibleFileTree() {
+ const fileTree: FileTreeItem[] = [
+ {
+ name: "components",
+ items: [
+ {
+ name: "ui",
+ items: [
+ { name: "button.tsx" },
+ { name: "card.tsx" },
+ { name: "dialog.tsx" },
+ { name: "input.tsx" },
+ { name: "select.tsx" },
+ { name: "table.tsx" },
+ ],
+ },
+ { name: "login-form.tsx" },
+ { name: "register-form.tsx" },
+ ],
+ },
+ {
+ name: "lib",
+ items: [{ name: "utils.ts" }, { name: "cn.ts" }, { name: "api.ts" }],
+ },
+ {
+ name: "hooks",
+ items: [
+ { name: "use-media-query.ts" },
+ { name: "use-debounce.ts" },
+ { name: "use-local-storage.ts" },
+ ],
+ },
+ {
+ name: "types",
+ items: [{ name: "index.d.ts" }, { name: "api.d.ts" }],
+ },
+ {
+ name: "public",
+ items: [
+ { name: "favicon.ico" },
+ { name: "logo.svg" },
+ { name: "images" },
+ ],
+ },
+ { name: "app.tsx" },
+ { name: "layout.tsx" },
+ { name: "globals.css" },
+ { name: "package.json" },
+ { name: "tsconfig.json" },
+ { name: "README.md" },
+ { name: ".gitignore" },
+ ]
+
+ const renderItem = (fileItem: FileTreeItem) => {
+ if ("items" in fileItem) {
+ return (
+
+
+
+
+
+ {fileItem.name}
+
+
+
+
+ {fileItem.items.map((child) => renderItem(child))}
+
+
+
+ )
+ }
+ return (
+
+
+ {fileItem.name}
+
+ )
+ }
+
+ return (
+
+
+
+
+
+ Explorer
+ Outline
+
+
+
+
+
+ {fileTree.map((item) => renderItem(item))}
+
+
+
+
+ )
+}
+
+function CollapsibleSettings() {
+ const [isOpen, setIsOpen] = React.useState(false)
+
+ return (
+
+
+
+ Radius
+
+ Set the corner radius of the element.
+
+
+
+
+
+
+
+ Radius X
+
+
+
+
+
+ Radius Y
+
+
+
+
+
+
+ Radius X
+
+
+
+
+
+ Radius Y
+
+
+
+
+
+
+
+ {isOpen ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/combobox-example.tsx b/apps/v4/registry/radix-lyra/examples/combobox-example.tsx
new file mode 100644
index 00000000000..ba3c584f39a
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/combobox-example.tsx
@@ -0,0 +1,1249 @@
+"use client"
+
+import * as React from "react"
+import { toast } from "sonner"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import { Card, CardContent, CardFooter } from "@/registry/radix-lyra/ui/card"
+import {
+ Combobox,
+ ComboboxChip,
+ ComboboxChips,
+ ComboboxChipsInput,
+ ComboboxCollection,
+ ComboboxContent,
+ ComboboxEmpty,
+ ComboboxGroup,
+ ComboboxInput,
+ ComboboxItem,
+ ComboboxLabel,
+ ComboboxList,
+ ComboboxSeparator,
+ ComboboxTrigger,
+ ComboboxValue,
+ useComboboxAnchor,
+} from "@/registry/radix-lyra/ui/combobox"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import {
+ Field,
+ FieldDescription,
+ FieldError,
+ FieldGroup,
+ FieldLabel,
+} from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+} from "@/registry/radix-lyra/ui/input-group"
+import {
+ Item,
+ ItemContent,
+ ItemDescription,
+ ItemTitle,
+} from "@/registry/radix-lyra/ui/item"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function ComboboxExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+const frameworks = [
+ "Next.js",
+ "SvelteKit",
+ "Nuxt.js",
+ "Remix",
+ "Astro",
+] as const
+
+const countries = [
+ { code: "", value: "", continent: "", label: "Select country" },
+ { code: "af", value: "afghanistan", label: "Afghanistan", continent: "Asia" },
+ { code: "al", value: "albania", label: "Albania", continent: "Europe" },
+ { code: "dz", value: "algeria", label: "Algeria", continent: "Africa" },
+ { code: "ad", value: "andorra", label: "Andorra", continent: "Europe" },
+ { code: "ao", value: "angola", label: "Angola", continent: "Africa" },
+ {
+ code: "ar",
+ value: "argentina",
+ label: "Argentina",
+ continent: "South America",
+ },
+ { code: "am", value: "armenia", label: "Armenia", continent: "Asia" },
+ { code: "au", value: "australia", label: "Australia", continent: "Oceania" },
+ { code: "at", value: "austria", label: "Austria", continent: "Europe" },
+ { code: "az", value: "azerbaijan", label: "Azerbaijan", continent: "Asia" },
+ {
+ code: "bs",
+ value: "bahamas",
+ label: "Bahamas",
+ continent: "North America",
+ },
+ { code: "bh", value: "bahrain", label: "Bahrain", continent: "Asia" },
+ { code: "bd", value: "bangladesh", label: "Bangladesh", continent: "Asia" },
+ {
+ code: "bb",
+ value: "barbados",
+ label: "Barbados",
+ continent: "North America",
+ },
+ { code: "by", value: "belarus", label: "Belarus", continent: "Europe" },
+ { code: "be", value: "belgium", label: "Belgium", continent: "Europe" },
+ { code: "bz", value: "belize", label: "Belize", continent: "North America" },
+ { code: "bj", value: "benin", label: "Benin", continent: "Africa" },
+ { code: "bt", value: "bhutan", label: "Bhutan", continent: "Asia" },
+ {
+ code: "bo",
+ value: "bolivia",
+ label: "Bolivia",
+ continent: "South America",
+ },
+ {
+ code: "ba",
+ value: "bosnia-and-herzegovina",
+ label: "Bosnia and Herzegovina",
+ continent: "Europe",
+ },
+ { code: "bw", value: "botswana", label: "Botswana", continent: "Africa" },
+ { code: "br", value: "brazil", label: "Brazil", continent: "South America" },
+ { code: "bn", value: "brunei", label: "Brunei", continent: "Asia" },
+ { code: "bg", value: "bulgaria", label: "Bulgaria", continent: "Europe" },
+ {
+ code: "bf",
+ value: "burkina-faso",
+ label: "Burkina Faso",
+ continent: "Africa",
+ },
+ { code: "bi", value: "burundi", label: "Burundi", continent: "Africa" },
+ { code: "kh", value: "cambodia", label: "Cambodia", continent: "Asia" },
+ { code: "cm", value: "cameroon", label: "Cameroon", continent: "Africa" },
+ { code: "ca", value: "canada", label: "Canada", continent: "North America" },
+ { code: "cv", value: "cape-verde", label: "Cape Verde", continent: "Africa" },
+ {
+ code: "cf",
+ value: "central-african-republic",
+ label: "Central African Republic",
+ continent: "Africa",
+ },
+ { code: "td", value: "chad", label: "Chad", continent: "Africa" },
+ { code: "cl", value: "chile", label: "Chile", continent: "South America" },
+ { code: "cn", value: "china", label: "China", continent: "Asia" },
+ {
+ code: "co",
+ value: "colombia",
+ label: "Colombia",
+ continent: "South America",
+ },
+ { code: "km", value: "comoros", label: "Comoros", continent: "Africa" },
+ { code: "cg", value: "congo", label: "Congo", continent: "Africa" },
+ {
+ code: "cr",
+ value: "costa-rica",
+ label: "Costa Rica",
+ continent: "North America",
+ },
+ { code: "hr", value: "croatia", label: "Croatia", continent: "Europe" },
+ { code: "cu", value: "cuba", label: "Cuba", continent: "North America" },
+ { code: "cy", value: "cyprus", label: "Cyprus", continent: "Asia" },
+ {
+ code: "cz",
+ value: "czech-republic",
+ label: "Czech Republic",
+ continent: "Europe",
+ },
+ { code: "dk", value: "denmark", label: "Denmark", continent: "Europe" },
+ { code: "dj", value: "djibouti", label: "Djibouti", continent: "Africa" },
+ {
+ code: "dm",
+ value: "dominica",
+ label: "Dominica",
+ continent: "North America",
+ },
+ {
+ code: "do",
+ value: "dominican-republic",
+ label: "Dominican Republic",
+ continent: "North America",
+ },
+ {
+ code: "ec",
+ value: "ecuador",
+ label: "Ecuador",
+ continent: "South America",
+ },
+ { code: "eg", value: "egypt", label: "Egypt", continent: "Africa" },
+ {
+ code: "sv",
+ value: "el-salvador",
+ label: "El Salvador",
+ continent: "North America",
+ },
+ {
+ code: "gq",
+ value: "equatorial-guinea",
+ label: "Equatorial Guinea",
+ continent: "Africa",
+ },
+ { code: "er", value: "eritrea", label: "Eritrea", continent: "Africa" },
+ { code: "ee", value: "estonia", label: "Estonia", continent: "Europe" },
+ { code: "et", value: "ethiopia", label: "Ethiopia", continent: "Africa" },
+ { code: "fj", value: "fiji", label: "Fiji", continent: "Oceania" },
+ { code: "fi", value: "finland", label: "Finland", continent: "Europe" },
+ { code: "fr", value: "france", label: "France", continent: "Europe" },
+ { code: "ga", value: "gabon", label: "Gabon", continent: "Africa" },
+ { code: "gm", value: "gambia", label: "Gambia", continent: "Africa" },
+ { code: "ge", value: "georgia", label: "Georgia", continent: "Asia" },
+ { code: "de", value: "germany", label: "Germany", continent: "Europe" },
+ { code: "gh", value: "ghana", label: "Ghana", continent: "Africa" },
+ { code: "gr", value: "greece", label: "Greece", continent: "Europe" },
+ {
+ code: "gd",
+ value: "grenada",
+ label: "Grenada",
+ continent: "North America",
+ },
+ {
+ code: "gt",
+ value: "guatemala",
+ label: "Guatemala",
+ continent: "North America",
+ },
+ { code: "gn", value: "guinea", label: "Guinea", continent: "Africa" },
+ {
+ code: "gw",
+ value: "guinea-bissau",
+ label: "Guinea-Bissau",
+ continent: "Africa",
+ },
+ { code: "gy", value: "guyana", label: "Guyana", continent: "South America" },
+ { code: "ht", value: "haiti", label: "Haiti", continent: "North America" },
+ {
+ code: "hn",
+ value: "honduras",
+ label: "Honduras",
+ continent: "North America",
+ },
+ { code: "hu", value: "hungary", label: "Hungary", continent: "Europe" },
+ { code: "is", value: "iceland", label: "Iceland", continent: "Europe" },
+ { code: "in", value: "india", label: "India", continent: "Asia" },
+ { code: "id", value: "indonesia", label: "Indonesia", continent: "Asia" },
+ { code: "ir", value: "iran", label: "Iran", continent: "Asia" },
+ { code: "iq", value: "iraq", label: "Iraq", continent: "Asia" },
+ { code: "ie", value: "ireland", label: "Ireland", continent: "Europe" },
+ { code: "il", value: "israel", label: "Israel", continent: "Asia" },
+ { code: "it", value: "italy", label: "Italy", continent: "Europe" },
+ {
+ code: "jm",
+ value: "jamaica",
+ label: "Jamaica",
+ continent: "North America",
+ },
+ { code: "jp", value: "japan", label: "Japan", continent: "Asia" },
+ { code: "jo", value: "jordan", label: "Jordan", continent: "Asia" },
+ { code: "kz", value: "kazakhstan", label: "Kazakhstan", continent: "Asia" },
+ { code: "ke", value: "kenya", label: "Kenya", continent: "Africa" },
+ { code: "kw", value: "kuwait", label: "Kuwait", continent: "Asia" },
+ { code: "kg", value: "kyrgyzstan", label: "Kyrgyzstan", continent: "Asia" },
+ { code: "la", value: "laos", label: "Laos", continent: "Asia" },
+ { code: "lv", value: "latvia", label: "Latvia", continent: "Europe" },
+ { code: "lb", value: "lebanon", label: "Lebanon", continent: "Asia" },
+ { code: "ls", value: "lesotho", label: "Lesotho", continent: "Africa" },
+ { code: "lr", value: "liberia", label: "Liberia", continent: "Africa" },
+ { code: "ly", value: "libya", label: "Libya", continent: "Africa" },
+ {
+ code: "li",
+ value: "liechtenstein",
+ label: "Liechtenstein",
+ continent: "Europe",
+ },
+ { code: "lt", value: "lithuania", label: "Lithuania", continent: "Europe" },
+ { code: "lu", value: "luxembourg", label: "Luxembourg", continent: "Europe" },
+ { code: "mg", value: "madagascar", label: "Madagascar", continent: "Africa" },
+ { code: "mw", value: "malawi", label: "Malawi", continent: "Africa" },
+ { code: "my", value: "malaysia", label: "Malaysia", continent: "Asia" },
+ { code: "mv", value: "maldives", label: "Maldives", continent: "Asia" },
+ { code: "ml", value: "mali", label: "Mali", continent: "Africa" },
+ { code: "mt", value: "malta", label: "Malta", continent: "Europe" },
+ {
+ code: "mh",
+ value: "marshall-islands",
+ label: "Marshall Islands",
+ continent: "Oceania",
+ },
+ { code: "mr", value: "mauritania", label: "Mauritania", continent: "Africa" },
+ { code: "mu", value: "mauritius", label: "Mauritius", continent: "Africa" },
+ { code: "mx", value: "mexico", label: "Mexico", continent: "North America" },
+ {
+ code: "fm",
+ value: "micronesia",
+ label: "Micronesia",
+ continent: "Oceania",
+ },
+ { code: "md", value: "moldova", label: "Moldova", continent: "Europe" },
+ { code: "mc", value: "monaco", label: "Monaco", continent: "Europe" },
+ { code: "mn", value: "mongolia", label: "Mongolia", continent: "Asia" },
+ { code: "me", value: "montenegro", label: "Montenegro", continent: "Europe" },
+ { code: "ma", value: "morocco", label: "Morocco", continent: "Africa" },
+ { code: "mz", value: "mozambique", label: "Mozambique", continent: "Africa" },
+ { code: "mm", value: "myanmar", label: "Myanmar", continent: "Asia" },
+ { code: "na", value: "namibia", label: "Namibia", continent: "Africa" },
+ { code: "nr", value: "nauru", label: "Nauru", continent: "Oceania" },
+ { code: "np", value: "nepal", label: "Nepal", continent: "Asia" },
+ {
+ code: "nl",
+ value: "netherlands",
+ label: "Netherlands",
+ continent: "Europe",
+ },
+ {
+ code: "nz",
+ value: "new-zealand",
+ label: "New Zealand",
+ continent: "Oceania",
+ },
+ {
+ code: "ni",
+ value: "nicaragua",
+ label: "Nicaragua",
+ continent: "North America",
+ },
+ { code: "ne", value: "niger", label: "Niger", continent: "Africa" },
+ { code: "ng", value: "nigeria", label: "Nigeria", continent: "Africa" },
+ { code: "kp", value: "north-korea", label: "North Korea", continent: "Asia" },
+ {
+ code: "mk",
+ value: "north-macedonia",
+ label: "North Macedonia",
+ continent: "Europe",
+ },
+ { code: "no", value: "norway", label: "Norway", continent: "Europe" },
+ { code: "om", value: "oman", label: "Oman", continent: "Asia" },
+ { code: "pk", value: "pakistan", label: "Pakistan", continent: "Asia" },
+ { code: "pw", value: "palau", label: "Palau", continent: "Oceania" },
+ { code: "ps", value: "palestine", label: "Palestine", continent: "Asia" },
+ { code: "pa", value: "panama", label: "Panama", continent: "North America" },
+ {
+ code: "pg",
+ value: "papua-new-guinea",
+ label: "Papua New Guinea",
+ continent: "Oceania",
+ },
+ {
+ code: "py",
+ value: "paraguay",
+ label: "Paraguay",
+ continent: "South America",
+ },
+ { code: "pe", value: "peru", label: "Peru", continent: "South America" },
+ { code: "ph", value: "philippines", label: "Philippines", continent: "Asia" },
+ { code: "pl", value: "poland", label: "Poland", continent: "Europe" },
+ { code: "pt", value: "portugal", label: "Portugal", continent: "Europe" },
+ { code: "qa", value: "qatar", label: "Qatar", continent: "Asia" },
+ { code: "ro", value: "romania", label: "Romania", continent: "Europe" },
+ { code: "ru", value: "russia", label: "Russia", continent: "Europe" },
+ { code: "rw", value: "rwanda", label: "Rwanda", continent: "Africa" },
+ { code: "ws", value: "samoa", label: "Samoa", continent: "Oceania" },
+ { code: "sm", value: "san-marino", label: "San Marino", continent: "Europe" },
+ {
+ code: "sa",
+ value: "saudi-arabia",
+ label: "Saudi Arabia",
+ continent: "Asia",
+ },
+ { code: "sn", value: "senegal", label: "Senegal", continent: "Africa" },
+ { code: "rs", value: "serbia", label: "Serbia", continent: "Europe" },
+ { code: "sc", value: "seychelles", label: "Seychelles", continent: "Africa" },
+ {
+ code: "sl",
+ value: "sierra-leone",
+ label: "Sierra Leone",
+ continent: "Africa",
+ },
+ { code: "sg", value: "singapore", label: "Singapore", continent: "Asia" },
+ { code: "sk", value: "slovakia", label: "Slovakia", continent: "Europe" },
+ { code: "si", value: "slovenia", label: "Slovenia", continent: "Europe" },
+ {
+ code: "sb",
+ value: "solomon-islands",
+ label: "Solomon Islands",
+ continent: "Oceania",
+ },
+ { code: "so", value: "somalia", label: "Somalia", continent: "Africa" },
+ {
+ code: "za",
+ value: "south-africa",
+ label: "South Africa",
+ continent: "Africa",
+ },
+ { code: "kr", value: "south-korea", label: "South Korea", continent: "Asia" },
+ {
+ code: "ss",
+ value: "south-sudan",
+ label: "South Sudan",
+ continent: "Africa",
+ },
+ { code: "es", value: "spain", label: "Spain", continent: "Europe" },
+ { code: "lk", value: "sri-lanka", label: "Sri Lanka", continent: "Asia" },
+ { code: "sd", value: "sudan", label: "Sudan", continent: "Africa" },
+ {
+ code: "sr",
+ value: "suriname",
+ label: "Suriname",
+ continent: "South America",
+ },
+ { code: "se", value: "sweden", label: "Sweden", continent: "Europe" },
+ {
+ code: "ch",
+ value: "switzerland",
+ label: "Switzerland",
+ continent: "Europe",
+ },
+ { code: "sy", value: "syria", label: "Syria", continent: "Asia" },
+ { code: "tw", value: "taiwan", label: "Taiwan", continent: "Asia" },
+ { code: "tj", value: "tajikistan", label: "Tajikistan", continent: "Asia" },
+ { code: "tz", value: "tanzania", label: "Tanzania", continent: "Africa" },
+ { code: "th", value: "thailand", label: "Thailand", continent: "Asia" },
+ { code: "tl", value: "timor-leste", label: "Timor-Leste", continent: "Asia" },
+ { code: "tg", value: "togo", label: "Togo", continent: "Africa" },
+ { code: "to", value: "tonga", label: "Tonga", continent: "Oceania" },
+ {
+ code: "tt",
+ value: "trinidad-and-tobago",
+ label: "Trinidad and Tobago",
+ continent: "North America",
+ },
+ { code: "tn", value: "tunisia", label: "Tunisia", continent: "Africa" },
+ { code: "tr", value: "turkey", label: "Turkey", continent: "Asia" },
+ {
+ code: "tm",
+ value: "turkmenistan",
+ label: "Turkmenistan",
+ continent: "Asia",
+ },
+ { code: "tv", value: "tuvalu", label: "Tuvalu", continent: "Oceania" },
+ { code: "ug", value: "uganda", label: "Uganda", continent: "Africa" },
+ { code: "ua", value: "ukraine", label: "Ukraine", continent: "Europe" },
+ {
+ code: "ae",
+ value: "united-arab-emirates",
+ label: "United Arab Emirates",
+ continent: "Asia",
+ },
+ {
+ code: "gb",
+ value: "united-kingdom",
+ label: "United Kingdom",
+ continent: "Europe",
+ },
+ {
+ code: "us",
+ value: "united-states",
+ label: "United States",
+ continent: "North America",
+ },
+ {
+ code: "uy",
+ value: "uruguay",
+ label: "Uruguay",
+ continent: "South America",
+ },
+ { code: "uz", value: "uzbekistan", label: "Uzbekistan", continent: "Asia" },
+ { code: "vu", value: "vanuatu", label: "Vanuatu", continent: "Oceania" },
+ {
+ code: "va",
+ value: "vatican-city",
+ label: "Vatican City",
+ continent: "Europe",
+ },
+ {
+ code: "ve",
+ value: "venezuela",
+ label: "Venezuela",
+ continent: "South America",
+ },
+ { code: "vn", value: "vietnam", label: "Vietnam", continent: "Asia" },
+ { code: "ye", value: "yemen", label: "Yemen", continent: "Asia" },
+ { code: "zm", value: "zambia", label: "Zambia", continent: "Africa" },
+ { code: "zw", value: "zimbabwe", label: "Zimbabwe", continent: "Africa" },
+]
+
+const timezones = [
+ {
+ value: "Americas",
+ items: [
+ "(GMT-5) New York",
+ "(GMT-8) Los Angeles",
+ "(GMT-6) Chicago",
+ "(GMT-5) Toronto",
+ "(GMT-8) Vancouver",
+ "(GMT-3) São Paulo",
+ ],
+ },
+ {
+ value: "Europe",
+ items: [
+ "(GMT+0) London",
+ "(GMT+1) Paris",
+ "(GMT+1) Berlin",
+ "(GMT+1) Rome",
+ "(GMT+1) Madrid",
+ "(GMT+1) Amsterdam",
+ ],
+ },
+ {
+ value: "Asia/Pacific",
+ items: [
+ "(GMT+9) Tokyo",
+ "(GMT+8) Shanghai",
+ "(GMT+8) Singapore",
+ "(GMT+4) Dubai",
+ "(GMT+11) Sydney",
+ "(GMT+9) Seoul",
+ ],
+ },
+] as const
+
+function ComboboxBasic() {
+ return (
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxDisabled() {
+ return (
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+const disabledFrameworks = ["Nuxt.js", "Remix"]
+
+function ComboboxDisabledItems() {
+ return (
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxInvalid() {
+ return (
+
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+
+ Framework
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+ Please select a valid framework.
+
+
+
+
+ )
+}
+
+function ComboboxWithClear() {
+ return (
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxWithGroups() {
+ return (
+
+
+
+
+ No timezones found.
+
+ {(group) => (
+
+ {group.value}
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxWithGroupsAndSeparator() {
+ return (
+
+
+
+
+ No timezones found.
+
+ {(group) => (
+
+ {group.value}
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxWithForm() {
+ const handleSubmit = (event: React.FormEvent) => {
+ event.preventDefault()
+ const formData = new FormData(event.target as HTMLFormElement)
+ const framework = formData.get("framework") as string
+ toast(`You selected ${framework} as your framework.`)
+ }
+
+ return (
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+ )
+}
+
+const largeListItems = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`)
+
+function ComboboxLargeList() {
+ return (
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxAutoHighlight() {
+ return (
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboxboxInputAddon() {
+ return (
+
+
+
+
+
+
+
+
+ No timezones found.
+
+ {(group) => (
+
+ {group.value}
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxInPopup() {
+ return (
+
+
+
+ }
+ >
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item.label}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxMultiple() {
+ const anchor = useComboboxAnchor()
+
+ return (
+
+
+
+
+ {(values) => (
+
+ {values.map((value: string) => (
+ {value}
+ ))}
+
+
+ )}
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxMultipleDisabled() {
+ const anchor = useComboboxAnchor()
+
+ return (
+
+
+
+
+ {(values) => (
+
+ {values.map((value: string) => (
+ {value}
+ ))}
+
+
+ )}
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxMultipleInvalid() {
+ const anchor1 = useComboboxAnchor()
+ const anchor2 = useComboboxAnchor()
+
+ return (
+
+
+
+
+
+ {(values) => (
+
+ {values.map((value: string) => (
+ {value}
+ ))}
+
+
+ )}
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+
+ Frameworks
+
+
+
+
+ {(values) => (
+
+ {values.map((value: string) => (
+ {value}
+ ))}
+
+
+ )}
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ Please select at least one framework.
+
+
+
+
+
+ )
+}
+
+function ComboboxMultipleNoRemove() {
+ const anchor = useComboboxAnchor()
+
+ return (
+
+
+
+
+ {(values) => (
+
+ {values.map((value: string) => (
+
+ {value}
+
+ ))}
+
+
+ )}
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxWithCustomItems() {
+ return (
+
+ country.code !== "")}
+ itemToStringValue={(country: (typeof countries)[number]) =>
+ country.label
+ }
+ >
+
+
+ No countries found.
+
+ {(country) => (
+
+ -
+
+
+ {country.label}
+
+
+ {country.continent} ({country.code})
+
+
+
+
+ )}
+
+
+
+
+ )
+}
+
+function ComboboxInDialog() {
+ const [open, setOpen] = React.useState(false)
+
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Select Framework
+
+ Choose your preferred framework from the list below.
+
+
+
+
+ Framework
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+
+ setOpen(false)}
+ >
+ Cancel
+
+ {
+ toast("Framework selected.")
+ setOpen(false)
+ }}
+ >
+ Confirm
+
+
+
+
+
+ )
+}
+
+function ComboboxWithOtherInputs() {
+ return (
+
+
+
+
+ No items found.
+
+ {(item) => (
+
+ {item}
+
+ )}
+
+
+
+
+
+
+
+
+
+ {frameworks.map((framework) => (
+
+ {framework}
+
+ ))}
+
+
+
+
+ Select a framework
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/command-example.tsx b/apps/v4/registry/radix-lyra/examples/command-example.tsx
new file mode 100644
index 00000000000..caacdf77c81
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/command-example.tsx
@@ -0,0 +1,590 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import { Card, CardContent } from "@/registry/radix-lyra/ui/card"
+import {
+ Command,
+ CommandDialog,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+ CommandSeparator,
+ CommandShortcut,
+} from "@/registry/radix-lyra/ui/command"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function CommandExample() {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function CommandInline() {
+ return (
+
+
+
+
+
+
+ No results found.
+
+
+
+ Calendar
+
+
+
+ Search Emoji
+
+
+
+ Calculator
+
+
+
+
+
+
+ Profile
+ ⌘P
+
+
+
+ Billing
+ ⌘B
+
+
+
+ Settings
+ ⌘S
+
+
+
+
+
+
+
+ )
+}
+
+function CommandBasic() {
+ const [open, setOpen] = React.useState(false)
+
+ return (
+
+
+ setOpen(true)}
+ variant="outline"
+ className="w-fit"
+ >
+ Open Menu
+
+
+
+
+
+ No results found.
+
+ Calendar
+ Search Emoji
+ Calculator
+
+
+
+
+
+
+ )
+}
+
+function CommandWithShortcuts() {
+ const [open, setOpen] = React.useState(false)
+
+ return (
+
+
+ setOpen(true)}
+ variant="outline"
+ className="w-fit"
+ >
+ Open Menu
+
+
+
+
+
+ No results found.
+
+
+
+ Profile
+ ⌘P
+
+
+
+ Billing
+ ⌘B
+
+
+
+ Settings
+ ⌘S
+
+
+
+
+
+
+
+ )
+}
+
+function CommandWithGroups() {
+ const [open, setOpen] = React.useState(false)
+
+ return (
+
+
+ setOpen(true)}
+ variant="outline"
+ className="w-fit"
+ >
+ Open Menu
+
+
+
+
+
+ No results found.
+
+
+
+ Calendar
+
+
+
+ Search Emoji
+
+
+
+ Calculator
+
+
+
+
+
+
+ Profile
+ ⌘P
+
+
+
+ Billing
+ ⌘B
+
+
+
+ Settings
+ ⌘S
+
+
+
+
+
+
+
+ )
+}
+
+function CommandManyItems() {
+ const [open, setOpen] = React.useState(false)
+
+ return (
+
+
+ setOpen(true)}
+ variant="outline"
+ className="w-fit"
+ >
+ Open Menu
+
+
+
+
+
+ No results found.
+
+
+
+ Home
+ ⌘H
+
+
+
+ Inbox
+ ⌘I
+
+
+
+ Documents
+ ⌘D
+
+
+
+ Folders
+ ⌘F
+
+
+
+
+
+
+ New File
+ ⌘N
+
+
+
+ New Folder
+ ⇧⌘N
+
+
+
+ Copy
+ ⌘C
+
+
+
+ Cut
+ ⌘X
+
+
+
+ Paste
+ ⌘V
+
+
+
+ Delete
+ ⌫
+
+
+
+
+
+
+ Grid View
+
+
+
+ List View
+
+
+
+ Zoom In
+ ⌘+
+
+
+
+ Zoom Out
+ ⌘-
+
+
+
+
+
+
+ Profile
+ ⌘P
+
+
+
+ Billing
+ ⌘B
+
+
+
+ Settings
+ ⌘S
+
+
+
+ Notifications
+
+
+
+ Help & Support
+
+
+
+
+
+
+ Calculator
+
+
+
+ Calendar
+
+
+
+ Image Editor
+
+
+
+ Code Editor
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/context-menu-example.tsx b/apps/v4/registry/radix-lyra/examples/context-menu-example.tsx
new file mode 100644
index 00000000000..be6bceea3a1
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/context-menu-example.tsx
@@ -0,0 +1,635 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ ContextMenu,
+ ContextMenuCheckboxItem,
+ ContextMenuContent,
+ ContextMenuGroup,
+ ContextMenuItem,
+ ContextMenuLabel,
+ ContextMenuRadioGroup,
+ ContextMenuRadioItem,
+ ContextMenuSeparator,
+ ContextMenuShortcut,
+ ContextMenuSub,
+ ContextMenuSubContent,
+ ContextMenuSubTrigger,
+ ContextMenuTrigger,
+} from "@/registry/radix-lyra/ui/context-menu"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function ContextMenuExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ContextMenuBasic() {
+ return (
+
+
+
+ Right click here
+
+
+
+ Back
+ Forward
+ Reload
+
+
+
+
+ )
+}
+
+function ContextMenuWithIcons() {
+ return (
+
+
+
+ Right click here
+
+
+
+
+
+ Copy
+
+
+
+ Cut
+
+
+
+ Paste
+
+
+
+
+
+
+ Delete
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithShortcuts() {
+ return (
+
+
+
+ Right click here
+
+
+
+
+ Back
+ ⌘[
+
+
+ Forward
+ ⌘]
+
+
+ Reload
+ ⌘R
+
+
+
+
+
+ Save
+ ⌘S
+
+
+ Save As...
+ ⇧⌘S
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithSubmenu() {
+ return (
+
+
+
+ Right click here
+
+
+
+
+ Copy
+ ⌘C
+
+
+ Cut
+ ⌘X
+
+
+
+ More Tools
+
+
+ Save Page...
+ Create Shortcut...
+ Name Window...
+
+
+
+ Developer Tools
+
+
+
+ Delete
+
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithGroups() {
+ return (
+
+
+
+ Right click here
+
+
+
+ File
+
+ New File
+ ⌘N
+
+
+ Open File
+ ⌘O
+
+
+ Save
+ ⌘S
+
+
+
+
+ Edit
+
+ Undo
+ ⌘Z
+
+
+ Redo
+ ⇧⌘Z
+
+
+
+ Cut
+ ⌘X
+
+
+ Copy
+ ⌘C
+
+
+ Paste
+ ⌘V
+
+
+
+
+
+ Delete
+ ⌫
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithCheckboxes() {
+ const [showBookmarksBar, setShowBookmarksBar] = React.useState(true)
+ const [showFullUrls, setShowFullUrls] = React.useState(false)
+ const [showDeveloperTools, setShowDeveloperTools] = React.useState(false)
+
+ return (
+
+
+
+ Right click here
+
+
+
+
+ Show Bookmarks Bar
+
+
+ Show Full URLs
+
+
+ Show Developer Tools
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithRadio() {
+ const [user, setUser] = React.useState("pedro")
+ const [theme, setTheme] = React.useState("light")
+
+ return (
+
+
+
+ Right click here
+
+
+
+ People
+
+
+ Pedro Duarte
+
+
+ Colm Tuite
+
+
+
+
+
+ Theme
+
+ Light
+ Dark
+ System
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithDestructive() {
+ return (
+
+
+
+ Right click here
+
+
+
+
+
+ Edit
+
+
+
+ Share
+
+
+
+
+
+
+ Archive
+
+
+
+ Delete
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithSides() {
+ return (
+
+
+
+
+ Right click (top)
+
+
+
+ Back
+ Forward
+ Reload
+
+
+
+
+
+ Right click (right)
+
+
+
+ Back
+ Forward
+ Reload
+
+
+
+
+
+ Right click (bottom)
+
+
+
+ Back
+ Forward
+ Reload
+
+
+
+
+
+ Right click (left)
+
+
+
+ Back
+ Forward
+ Reload
+
+
+
+
+
+ )
+}
+
+function ContextMenuInDialog() {
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Context Menu Example
+
+ Right click on the area below to see the context menu.
+
+
+
+
+ Right click here
+
+
+
+
+
+ Copy
+
+
+
+ Cut
+
+
+
+ Paste
+
+
+
+
+ More Options
+
+
+ Save Page...
+ Create Shortcut...
+ Name Window...
+
+
+
+ Developer Tools
+
+
+
+
+
+
+
+ Delete
+
+
+
+
+
+
+
+ )
+}
+
+function ContextMenuWithInset() {
+ const [showBookmarks, setShowBookmarks] = React.useState(true)
+ const [showUrls, setShowUrls] = React.useState(false)
+ const [theme, setTheme] = React.useState("system")
+
+ return (
+
+
+
+ Right click here
+
+
+
+ Actions
+
+
+ Copy
+
+
+
+ Cut
+
+ Paste
+
+
+
+ Appearance
+
+ Bookmarks
+
+
+ Full URLs
+
+
+
+
+ Theme
+
+
+ Light
+
+
+ Dark
+
+
+ System
+
+
+
+
+
+ More Options
+
+
+ Save Page...
+ Create Shortcut...
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/dialog-example.tsx b/apps/v4/registry/radix-lyra/examples/dialog-example.tsx
new file mode 100644
index 00000000000..63a29914c91
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/dialog-example.tsx
@@ -0,0 +1,586 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import { Checkbox } from "@/registry/radix-lyra/ui/checkbox"
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import {
+ Field,
+ FieldContent,
+ FieldDescription,
+ FieldGroup,
+ FieldLabel,
+ FieldSeparator,
+ FieldSet,
+ FieldTitle,
+} from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupButton,
+ InputGroupInput,
+} from "@/registry/radix-lyra/ui/input-group"
+import { Kbd } from "@/registry/radix-lyra/ui/kbd"
+import {
+ NativeSelect,
+ NativeSelectOption,
+} from "@/registry/radix-lyra/ui/native-select"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectSeparator,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+import { Switch } from "@/registry/radix-lyra/ui/switch"
+import {
+ Tabs,
+ TabsContent,
+ TabsList,
+ TabsTrigger,
+} from "@/registry/radix-lyra/ui/tabs"
+import { Textarea } from "@/registry/radix-lyra/ui/textarea"
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/registry/radix-lyra/ui/tooltip"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function DialogExample() {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function DialogWithForm() {
+ return (
+
+
+
+
+
+ )
+}
+
+function DialogScrollableContent() {
+ return (
+
+
+
+ Scrollable Content
+
+
+
+ Scrollable Content
+
+ This is a dialog with scrollable content.
+
+
+
+ {Array.from({ length: 10 }).map((_, index) => (
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris
+ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
+ in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+ nulla pariatur. Excepteur sint occaecat cupidatat non proident,
+ sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+ ))}
+
+
+
+
+ )
+}
+
+function DialogWithStickyFooter() {
+ return (
+
+
+
+ Sticky Footer
+
+
+
+ Scrollable Content
+
+ This is a dialog with scrollable content.
+
+
+
+ {Array.from({ length: 10 }).map((_, index) => (
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris
+ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
+ in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+ nulla pariatur. Excepteur sint occaecat cupidatat non proident,
+ sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+ ))}
+
+
+
+ Close
+
+
+
+
+
+ )
+}
+
+function DialogNoCloseButton() {
+ return (
+
+
+
+ No Close Button
+
+
+
+ No Close Button
+
+ This dialog doesn't have a close button in the top-right
+ corner.
+
+
+
+
+ Close
+
+
+
+
+
+ )
+}
+
+const spokenLanguages = [
+ { label: "English", value: "en" },
+ { label: "Spanish", value: "es" },
+ { label: "French", value: "fr" },
+ { label: "German", value: "de" },
+ { label: "Italian", value: "it" },
+ { label: "Portuguese", value: "pt" },
+ { label: "Russian", value: "ru" },
+ { label: "Chinese", value: "zh" },
+ { label: "Japanese", value: "ja" },
+ { label: "Korean", value: "ko" },
+ { label: "Arabic", value: "ar" },
+ { label: "Hindi", value: "hi" },
+ { label: "Bengali", value: "bn" },
+ { label: "Telugu", value: "te" },
+ { label: "Marathi", value: "mr" },
+ { label: "Kannada", value: "kn" },
+ { label: "Malayalam", value: "ml" },
+]
+
+const voices = [
+ { label: "Samantha", value: "samantha" },
+ { label: "Alex", value: "alex" },
+ { label: "Fred", value: "fred" },
+ { label: "Victoria", value: "victoria" },
+ { label: "Tom", value: "tom" },
+ { label: "Karen", value: "karen" },
+ { label: "Sam", value: "sam" },
+ { label: "Daniel", value: "daniel" },
+]
+
+function DialogChatSettings() {
+ const [tab, setTab] = React.useState("general")
+ const [theme, setTheme] = React.useState("system")
+ const [accentColor, setAccentColor] = React.useState("default")
+ const [spokenLanguage, setSpokenLanguage] = React.useState("en")
+ const [voice, setVoice] = React.useState("samantha")
+
+ return (
+
+
+
+ Chat Settings
+
+
+
+ Chat Settings
+
+ Customize your chat settings: theme, accent color, spoken
+ language, voice, personality, and custom instructions.
+
+
+
+
setTab(e.target.value)}
+ className="w-full md:hidden"
+ >
+ General
+
+ Notifications
+
+
+ Personalization
+
+ Security
+
+
+
+ General
+ Notifications
+
+ Personalization
+
+ Security
+
+
+
+
+
+
+ Theme
+
+
+
+
+
+
+ Light
+ Dark
+ System
+
+
+
+
+
+
+
+ Accent Color
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+ Red
+
+
+
+ Blue
+
+
+
+ Green
+
+
+
+ Purple
+
+
+
+ Pink
+
+
+
+
+
+
+
+
+
+ Spoken Language
+
+
+ For best results, select the language you mainly
+ speak. If it's not listed, it may still be
+ supported via auto-detection.
+
+
+
+
+
+
+
+
+ Auto
+
+
+
+ {spokenLanguages.map((language) => (
+
+ {language.label}
+
+ ))}
+
+
+
+
+
+
+ Voice
+
+
+
+
+
+
+ {voices.map((voice) => (
+
+ {voice.label}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+ Responses
+
+ Get notified when ChatGPT responds to requests that take
+ time, like research or image generation.
+
+
+
+
+
+ Push notifications
+
+
+
+
+
+
+ Tasks
+
+ Get notified when tasks you've created have
+ updates. Manage tasks
+
+
+
+
+
+ Push notifications
+
+
+
+
+
+ Email notifications
+
+
+
+
+
+
+
+
+
+ Nickname
+
+
+
+
+
+
+
+
+
+
+ Used to identify you in the chat. N
+
+
+
+
+
+
+
+
+ More about you
+
+ Tell us more about yourself. This will be used to help
+ us personalize your experience.
+
+
+
+
+
+
+
+
+
+ Enable customizations
+
+
+ Enable customizations to make ChatGPT more
+ personalized.
+
+
+
+
+
+
+
+
+
+
+
+
+ Multi-factor authentication
+
+
+ Enable multi-factor authentication to secure your
+ account. If you do not have a two-factor
+ authentication device, you can use a one-time code
+ sent to your email.
+
+
+
+
+
+
+
+ Log out
+
+ Log out of your account on this device.
+
+
+
+ Log Out
+
+
+
+
+
+ Log out of all devices
+
+ This will log you out of all devices, including the
+ current session. It may take up to 30 minutes for the
+ changes to take effect.
+
+
+
+ Log Out All
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/drawer-example.tsx b/apps/v4/registry/radix-lyra/examples/drawer-example.tsx
new file mode 100644
index 00000000000..ea908e07923
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/drawer-example.tsx
@@ -0,0 +1,125 @@
+"use client"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Drawer,
+ DrawerClose,
+ DrawerContent,
+ DrawerDescription,
+ DrawerFooter,
+ DrawerHeader,
+ DrawerTitle,
+ DrawerTrigger,
+} from "@/registry/radix-lyra/ui/drawer"
+
+export default function DrawerExample() {
+ return (
+
+
+
+
+ )
+}
+
+const DRAWER_SIDES = ["top", "right", "bottom", "left"] as const
+
+function DrawerWithSides() {
+ return (
+
+
+ {DRAWER_SIDES.map((side) => (
+
+
+
+ {side}
+
+
+
+
+ Move Goal
+
+ Set your daily activity goal.
+
+
+
+ {Array.from({ length: 10 }).map((_, index) => (
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
+ do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ ullamco laboris nisi ut aliquip ex ea commodo consequat.
+ Duis aute irure dolor in reprehenderit in voluptate velit
+ esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+ occaecat cupidatat non proident, sunt in culpa qui officia
+ deserunt mollit anim id est laborum.
+
+ ))}
+
+
+ Submit
+
+ Cancel
+
+
+
+
+ ))}
+
+
+ )
+}
+
+function DrawerScrollableContent() {
+ return (
+
+
+
+ Scrollable Content
+
+
+
+ Move Goal
+ Set your daily activity goal.
+
+
+ {Array.from({ length: 10 }).map((_, index) => (
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris
+ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
+ in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+ nulla pariatur. Excepteur sint occaecat cupidatat non proident,
+ sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+ ))}
+
+
+ Submit
+
+ Cancel
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/dropdown-menu-example.tsx b/apps/v4/registry/radix-lyra/examples/dropdown-menu-example.tsx
new file mode 100644
index 00000000000..001e1e1d92c
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/dropdown-menu-example.tsx
@@ -0,0 +1,978 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Avatar,
+ AvatarFallback,
+ AvatarImage,
+} from "@/registry/radix-lyra/ui/avatar"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import {
+ DropdownMenu,
+ DropdownMenuCheckboxItem,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuPortal,
+ DropdownMenuRadioGroup,
+ DropdownMenuRadioItem,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuSub,
+ DropdownMenuSubContent,
+ DropdownMenuSubTrigger,
+ DropdownMenuTrigger,
+} from "@/registry/radix-lyra/ui/dropdown-menu"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function DropdownMenuExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function DropdownMenuBasic() {
+ return (
+
+
+
+
+ Open
+
+
+
+
+ My Account
+ Profile
+ Billing
+ Settings
+
+
+
+ GitHub
+ API
+ Support
+
+
+
+
+ )
+}
+
+function DropdownMenuWithIcons() {
+ return (
+
+
+
+
+ Open
+
+
+
+
+
+
+ Profile
+
+
+
+ Billing
+
+
+
+ Settings
+
+
+
+
+
+
+ Log out
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithShortcuts() {
+ return (
+
+
+
+
+ Open
+
+
+
+
+ My Account
+
+ Profile
+ ⇧⌘P
+
+
+ Billing
+ ⌘B
+
+
+ Settings
+ ⌘S
+
+
+ Shortcuts
+ ⌘K
+
+
+
+
+
+ Log out
+ ⇧⌘Q
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithSubmenu() {
+ return (
+
+
+
+
+ Open
+
+
+
+
+ Team
+
+ Invite users
+
+
+
+ Email
+ Message
+
+
+
+ More...
+
+
+
+
+
+ New Team
+ ⌘+T
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithCheckboxes() {
+ const [showStatusBar, setShowStatusBar] = React.useState(true)
+ const [showActivityBar, setShowActivityBar] = React.useState(false)
+ const [showPanel, setShowPanel] = React.useState(false)
+
+ return (
+
+
+
+
+ Checkboxes
+
+
+
+
+ Appearance
+
+
+ Status Bar
+
+
+
+ Activity Bar
+
+
+
+ Panel
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithRadio() {
+ const [position, setPosition] = React.useState("bottom")
+
+ return (
+
+
+
+
+ Radio Group
+
+
+
+
+ Panel Position
+
+
+
+ Top
+
+
+
+ Bottom
+
+
+
+ Right
+
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithCheckboxesIcons() {
+ const [notifications, setNotifications] = React.useState({
+ email: true,
+ sms: false,
+ push: true,
+ })
+
+ return (
+
+
+
+
+ Notifications
+
+
+
+
+ Notification Preferences
+
+ setNotifications({ ...notifications, email: checked === true })
+ }
+ >
+
+ Email notifications
+
+
+ setNotifications({ ...notifications, sms: checked === true })
+ }
+ >
+
+ SMS notifications
+
+
+ setNotifications({ ...notifications, push: checked === true })
+ }
+ >
+
+ Push notifications
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithRadioIcons() {
+ const [paymentMethod, setPaymentMethod] = React.useState("card")
+
+ return (
+
+
+
+ Payment Method
+
+
+
+ Select Payment Method
+
+
+
+ Credit Card
+
+
+
+ PayPal
+
+
+
+ Bank Transfer
+
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithDestructive() {
+ return (
+
+
+
+
+ Actions
+
+
+
+
+
+
+ Edit
+
+
+
+ Share
+
+
+
+
+
+
+ Archive
+
+
+
+ Delete
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithAvatar() {
+ const menuContent = (
+ <>
+
+
+
+ Account
+
+
+
+ Billing
+
+
+
+ Notifications
+
+
+
+
+
+
+ Sign Out
+
+
+ >
+ )
+
+ return (
+
+
+
+
+
+
+
+ CN
+
+
+ shadcn
+
+ shadcn@example.com
+
+
+
+
+
+
+ {menuContent}
+
+
+
+
+
+
+
+ LR
+
+
+
+
+ {menuContent}
+
+
+
+
+ )
+}
+
+function DropdownMenuInDialog() {
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Dropdown Menu Example
+
+ Click the button below to see the dropdown menu.
+
+
+
+
+
+ Open Menu
+
+
+
+
+
+
+ Copy
+
+
+
+ Cut
+
+
+
+ Paste
+
+
+
+
+ More Options
+
+
+
+ Save Page...
+ Create Shortcut...
+ Name Window...
+
+
+
+ Developer Tools
+
+
+
+
+
+
+
+
+ Delete
+
+
+
+
+
+
+
+ )
+}
+
+function DropdownMenuWithInset() {
+ const [showBookmarks, setShowBookmarks] = React.useState(true)
+ const [showUrls, setShowUrls] = React.useState(false)
+ const [theme, setTheme] = React.useState("system")
+
+ return (
+
+
+
+
+ Open
+
+
+
+
+ Actions
+
+
+ Copy
+
+
+
+ Cut
+
+ Paste
+
+
+
+ Appearance
+
+ Bookmarks
+
+
+ Full URLs
+
+
+
+
+ Theme
+
+
+ Light
+
+
+ Dark
+
+
+ System
+
+
+
+
+
+ More Options
+
+
+
+ Save Page...
+ Create Shortcut...
+
+
+
+
+
+
+
+ )
+}
+
+function DropdownMenuComplex() {
+ const [showSidebar, setShowSidebar] = React.useState(true)
+ const [showStatusBar, setShowStatusBar] = React.useState(false)
+
+ return (
+
+
+
+
+ Complex Menu
+
+
+
+
+ My Account
+
+
+ Profile
+ ⇧⌘P
+
+
+
+ Billing
+ ⌘B
+
+
+
+ Settings
+ ⌘S
+
+
+
+
+ View
+
+
+ Sidebar
+
+
+
+ Status Bar
+
+
+
+
+
+
+
+ Invite Users
+
+
+
+
+
+
+ Email
+
+
+
+ Message
+
+
+
+
+
+
+ More...
+
+
+
+
+
+
+
+
+
+
+ Support
+
+
+
+ Sign Out
+ ⇧⌘Q
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/empty-example.tsx b/apps/v4/registry/radix-lyra/examples/empty-example.tsx
new file mode 100644
index 00000000000..d9fc651e4f4
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/empty-example.tsx
@@ -0,0 +1,254 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Empty,
+ EmptyContent,
+ EmptyDescription,
+ EmptyHeader,
+ EmptyMedia,
+ EmptyTitle,
+} from "@/registry/radix-lyra/ui/empty"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+} from "@/registry/radix-lyra/ui/input-group"
+import { Kbd } from "@/registry/radix-lyra/ui/kbd"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function EmptyExample() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+function EmptyBasic() {
+ return (
+
+
+
+ No projects yet
+
+ You haven't created any projects yet. Get started by creating
+ your first project.
+
+
+
+
+
+
+ Learn more{" "}
+
+
+
+
+
+
+ )
+}
+
+function EmptyWithMutedBackground() {
+ return (
+
+
+
+ No results found
+
+ No results found for your search. Try adjusting your search terms.
+
+
+
+ Try again
+
+
+ Learn more{" "}
+
+
+
+
+
+
+ )
+}
+
+function EmptyWithBorder() {
+ return (
+
+
+
+ 404 - Not Found
+
+ The page you're looking for doesn't exist. Try searching
+ for what you need below.
+
+
+
+
+
+
+
+
+
+ /
+
+
+
+ Need help? Contact support
+
+
+
+
+ )
+}
+
+function EmptyWithIcon() {
+ return (
+
+
+
+
+
+
+ Nothing to see here
+
+ No posts have been created yet. Get started by{" "}
+ creating your first post .
+
+
+
+
+
+ New Post
+
+
+
+
+ )
+}
+
+function EmptyWithMutedBackgroundAlt() {
+ return (
+
+
+
+ 404 - Not Found
+
+ The page you're looking for doesn't exist. Try searching
+ for what you need below.
+
+
+
+
+
+
+
+
+
+ /
+
+
+
+ Need help? Contact support
+
+
+
+
+ )
+}
+
+function EmptyInCard() {
+ return (
+
+
+
+
+
+
+ No projects yet
+
+ You haven't created any projects yet. Get started by creating
+ your first project.
+
+
+
+
+
+
+ Learn more{" "}
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/field-example.tsx b/apps/v4/registry/radix-lyra/examples/field-example.tsx
new file mode 100644
index 00000000000..ec542c9d291
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/field-example.tsx
@@ -0,0 +1,969 @@
+"use client"
+
+import { useState } from "react"
+import { REGEXP_ONLY_DIGITS } from "input-otp"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Badge } from "@/registry/radix-lyra/ui/badge"
+import { Checkbox } from "@/registry/radix-lyra/ui/checkbox"
+import {
+ Field,
+ FieldContent,
+ FieldDescription,
+ FieldGroup,
+ FieldLabel,
+ FieldLegend,
+ FieldSet,
+ FieldTitle,
+} from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ InputOTP,
+ InputOTPGroup,
+ InputOTPSeparator,
+ InputOTPSlot,
+} from "@/registry/radix-lyra/ui/input-otp"
+import {
+ NativeSelect,
+ NativeSelectOptGroup,
+ NativeSelectOption,
+} from "@/registry/radix-lyra/ui/native-select"
+import {
+ RadioGroup,
+ RadioGroupItem,
+} from "@/registry/radix-lyra/ui/radio-group"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+import { Slider } from "@/registry/radix-lyra/ui/slider"
+import { Switch } from "@/registry/radix-lyra/ui/switch"
+import { Textarea } from "@/registry/radix-lyra/ui/textarea"
+
+export default function FieldExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputFields() {
+ return (
+
+
+
+ Basic Input
+
+
+
+
+ Input with Description
+
+
+
+ Choose a unique username for your account.
+
+
+
+ Email Address
+
+ We'll never share your email with anyone.
+
+
+
+
+
+ Required Field *
+
+
+ This field must be filled out.
+
+
+ Disabled Input
+
+ This field is currently disabled.
+
+
+
+ Input with Badge{" "}
+
+ Recommended
+
+
+
+
+
+ Invalid Input
+
+
+ This field contains validation errors.
+
+
+
+ Disabled Field
+
+ This field is currently disabled.
+
+
+
+ )
+}
+
+function TextareaFields() {
+ return (
+
+
+
+ Basic Textarea
+
+
+
+ Comments
+
+ Maximum 500 characters allowed.
+
+
+ Bio
+
+ Tell us about yourself in a few sentences.
+
+
+
+
+ Message
+
+
+ Enter your message so it is long enough to test the layout.
+
+
+
+ Invalid Textarea
+
+
+ This field contains validation errors.
+
+
+
+
+ Disabled Field
+
+
+ This field is currently disabled.
+
+
+
+ )
+}
+
+function SelectFields() {
+ return (
+
+
+
+ Basic Select
+
+
+
+
+
+
+ Option 1
+ Option 2
+ Option 3
+
+
+
+
+
+ Country
+
+
+
+
+
+
+ United States
+ United Kingdom
+ Canada
+
+
+
+
+ Select the country where you currently reside.
+
+
+
+ Timezone
+
+ Choose your local timezone for accurate scheduling.
+
+
+
+
+
+
+
+ UTC
+ Eastern Time
+ Pacific Time
+
+
+
+
+
+ Invalid Select
+
+
+
+
+
+
+ Option 1
+ Option 2
+ Option 3
+
+
+
+
+ This field contains validation errors.
+
+
+
+
+ Disabled Field
+
+
+
+
+
+
+
+ Option 1
+ Option 2
+ Option 3
+
+
+
+ This field is currently disabled.
+
+
+
+ )
+}
+
+function NativeSelectFields() {
+ return (
+
+
+
+
+ Basic Native Select
+
+
+ Choose an option
+ Option 1
+ Option 2
+ Option 3
+
+
+
+ Country
+
+
+ Select your country
+
+ United States
+ United Kingdom
+ Canada
+
+
+ Select the country where you currently reside.
+
+
+
+ Timezone
+
+ Choose your local timezone for accurate scheduling.
+
+
+ Select timezone
+ UTC
+ Eastern Time
+ Pacific Time
+
+
+
+
+ Grouped Options
+
+
+ Select a region
+
+ United States
+ Canada
+ Mexico
+
+
+ United Kingdom
+ France
+ Germany
+
+
+
+ Native select with grouped options using optgroup.
+
+
+
+
+ Invalid Native Select
+
+
+
+ This field has an error
+
+ Option 1
+ Option 2
+ Option 3
+
+
+ This field contains validation errors.
+
+
+
+
+ Disabled Field
+
+
+ Cannot select
+ Option 1
+ Option 2
+ Option 3
+
+ This field is currently disabled.
+
+
+
+ )
+}
+
+function CheckboxFields() {
+ return (
+
+
+
+
+
+ I agree to the terms and conditions
+
+
+
+
+ Accept terms and conditions
+
+
+
+
+
+
+
+ Subscribe to newsletter
+
+
+ Receive weekly updates about new features and promotions.
+
+
+
+
+
+
+
+ Enable Touch ID
+
+ Enable Touch ID to quickly unlock your device.
+
+
+
+
+
+ Preferences
+
+ Select all that apply to customize your experience.
+
+
+
+
+ Dark mode
+
+
+
+ Compact view
+
+
+
+
+ Enable notifications
+
+
+
+
+
+
+ Invalid checkbox
+
+
+
+
+ Disabled checkbox
+
+
+
+
+ )
+}
+
+function RadioFields() {
+ return (
+
+
+
+ Subscription Plan
+
+
+
+ Free Plan
+
+
+
+ Pro Plan
+
+
+
+ Enterprise
+
+
+
+
+ Battery Level
+
+ Choose your preferred battery level.
+
+
+
+
+ High
+
+
+
+ Medium
+
+
+
+ Low
+
+
+
+
+
+
+
+ Enable Touch ID
+
+ Enable Touch ID to quickly unlock your device.
+
+
+
+
+
+
+
+
+
+ Enable Touch ID
+
+ Enable Touch ID to quickly unlock your device.
+
+
+
+
+
+
+ Invalid Radio Group
+
+
+
+
+ Invalid Option 1
+
+
+
+
+
+ Invalid Option 2
+
+
+
+
+
+ Disabled Radio Group
+
+
+
+
+ Disabled Option 1
+
+
+
+
+
+ Disabled Option 2
+
+
+
+
+
+
+ )
+}
+
+function SwitchFields() {
+ return (
+
+
+
+
+ Airplane Mode
+
+ Turn on airplane mode to disable all connections.
+
+
+
+
+
+ Dark Mode
+
+
+
+
+
+ Marketing Emails
+
+ Receive emails about new products, features, and more.
+
+
+
+
+ Privacy Settings
+ Manage your privacy preferences.
+
+
+
+ Make profile visible to others
+
+
+
+
+
+ Show email on profile
+
+
+
+
+
+ Invalid Switch
+
+ This switch has validation errors.
+
+
+
+
+
+
+
+ Disabled Switch
+
+
+ This switch is currently disabled.
+
+
+
+
+
+
+ )
+}
+
+function SliderFields() {
+ const [volume, setVolume] = useState([50])
+ const [brightness, setBrightness] = useState([75])
+ const [temperature, setTemperature] = useState([0.3, 0.7])
+ const [priceRange, setPriceRange] = useState([25, 75])
+ const [colorBalance, setColorBalance] = useState([10, 20, 70])
+
+ return (
+
+
+
+ Volume
+
+
+
+ Screen Brightness
+
+
+ Current brightness: {brightness[0]}%
+
+
+
+ Video Quality
+
+ Higher quality uses more bandwidth.
+
+
+
+
+
+ Temperature Range
+
+
+
+ Range: {temperature[0].toFixed(1)} - {temperature[1].toFixed(1)}
+
+
+
+ Price Range
+
+
+ ${priceRange[0]} - ${priceRange[1]}
+
+
+
+ Color Balance
+
+
+ Red: {colorBalance[0]}%, Green: {colorBalance[1]}%, Blue:{" "}
+ {colorBalance[2]}%
+
+
+
+ Invalid Slider
+
+
+ This slider has validation errors.
+
+
+
+
+ Disabled Slider
+
+
+
+ This slider is currently disabled.
+
+
+
+
+ )
+}
+
+function InputOTPFields() {
+ const [value, setValue] = useState("")
+ const [pinValue, setPinValue] = useState("")
+
+ return (
+
+
+
+ Verification Code
+
+
+
+
+
+
+
+
+
+
+
+
+ Enter OTP
+
+
+
+
+
+
+
+
+
+
+
+ Enter the 6-digit code sent to your email.
+
+
+
+
+ Two-Factor Authentication
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Enter the code from your authenticator app.
+
+
+
+ PIN Code
+
+
+
+
+
+
+
+
+
+ Enter your 4-digit PIN (numbers only).
+
+
+
+ Invalid OTP
+
+
+
+
+
+
+
+
+
+
+
+ This OTP field contains validation errors.
+
+
+
+ Disabled OTP
+
+
+
+
+
+
+
+
+
+
+
+ This OTP field is currently disabled.
+
+
+
+
+ )
+}
+
+function HorizontalFields() {
+ return (
+
+
+
+
+ Username
+ Enter your preferred username.
+
+
+
+
+
+ Bio
+
+ Write a short description about yourself.
+
+
+
+
+
+
+
+ Email Notifications
+
+
+ Receive email updates about your account.
+
+
+
+
+
+
+ Favorite Fruit
+ Choose your favorite fruit.
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Orange
+
+
+
+
+
+
+ Country
+ Select your country.
+
+
+ Select a country
+ United States
+ United Kingdom
+ Canada
+
+
+
+
+ Volume
+ Adjust the volume level.
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/hover-card-example.tsx b/apps/v4/registry/radix-lyra/examples/hover-card-example.tsx
new file mode 100644
index 00000000000..036735b5ac2
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/hover-card-example.tsx
@@ -0,0 +1,98 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import {
+ HoverCard,
+ HoverCardContent,
+ HoverCardTrigger,
+} from "@/registry/radix-lyra/ui/hover-card"
+
+export default function HoverCardExample() {
+ return (
+
+
+
+
+ )
+}
+
+const HOVER_CARD_SIDES = ["top", "right", "bottom", "left"] as const
+
+function HoverCardSides() {
+ return (
+
+
+ {HOVER_CARD_SIDES.map((side) => (
+
+
+
+ {side}
+
+
+
+
+
+ Hover Card
+
+
+ This hover card appears on the {side} side of the trigger.
+
+
+
+
+ ))}
+
+
+ )
+}
+
+function HoverCardInDialog() {
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Hover Card Example
+
+ Hover over the button below to see the hover card.
+
+
+
+
+
+ Hover me
+
+
+
+
+
+ Hover Card
+
+
+ This hover card appears inside a dialog. Hover over the button
+ to see it.
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/input-example.tsx b/apps/v4/registry/radix-lyra/examples/input-example.tsx
new file mode 100644
index 00000000000..ed6786b3a73
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/input-example.tsx
@@ -0,0 +1,268 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Field,
+ FieldDescription,
+ FieldGroup,
+ FieldLabel,
+} from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ NativeSelect,
+ NativeSelectOption,
+} from "@/registry/radix-lyra/ui/native-select"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+
+export default function InputExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputBasic() {
+ return (
+
+
+
+ )
+}
+
+function InputInvalid() {
+ return (
+
+
+
+ )
+}
+
+function InputWithLabel() {
+ return (
+
+
+ Email
+
+
+
+ )
+}
+
+function InputWithDescription() {
+ return (
+
+
+ Username
+
+
+ Choose a unique username for your account.
+
+
+
+ )
+}
+
+function InputDisabled() {
+ return (
+
+
+ Email
+
+
+
+ )
+}
+
+function InputTypes() {
+ return (
+
+
+
+ Password
+
+
+
+ Phone
+
+
+
+ URL
+
+
+
+ Search
+
+
+
+ Number
+
+
+
+ Date
+
+
+
+ Time
+
+
+
+ File
+
+
+
+
+ )
+}
+
+function InputWithSelect() {
+ return (
+
+
+
+
+
+
+
+
+
+ USD
+ EUR
+ GBP
+
+
+
+
+
+ )
+}
+
+function InputWithButton() {
+ return (
+
+
+
+ Search
+
+
+ )
+}
+
+function InputWithNativeSelect() {
+ return (
+
+
+
+
+ +1
+ +44
+ +46
+
+
+
+ )
+}
+
+function InputForm() {
+ return (
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/input-group-example.tsx b/apps/v4/registry/radix-lyra/examples/input-group-example.tsx
new file mode 100644
index 00000000000..2ba0f48a1f5
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/input-group-example.tsx
@@ -0,0 +1,887 @@
+"use client"
+
+import { useState } from "react"
+import { toast } from "sonner"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ ButtonGroup,
+ ButtonGroupText,
+} from "@/registry/radix-lyra/ui/button-group"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/registry/radix-lyra/ui/dropdown-menu"
+import {
+ Field,
+ FieldDescription,
+ FieldGroup,
+ FieldLabel,
+} from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupButton,
+ InputGroupInput,
+ InputGroupText,
+ InputGroupTextarea,
+} from "@/registry/radix-lyra/ui/input-group"
+import { Kbd, KbdGroup } from "@/registry/radix-lyra/ui/kbd"
+import {
+ Popover,
+ PopoverContent,
+ PopoverDescription,
+ PopoverHeader,
+ PopoverTitle,
+ PopoverTrigger,
+} from "@/registry/radix-lyra/ui/popover"
+import { Spinner } from "@/registry/radix-lyra/ui/spinner"
+import { Textarea } from "@/registry/radix-lyra/ui/textarea"
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/registry/radix-lyra/ui/tooltip"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function InputGroupExample() {
+ const [country, setCountry] = useState("+1")
+
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputGroupBasic() {
+ return (
+
+
+
+
+ Default (No Input Group)
+
+
+
+
+ Input Group
+
+
+
+
+
+ Disabled
+
+
+
+
+
+ Invalid
+
+
+
+
+
+
+ )
+}
+
+function InputGroupWithAddons() {
+ return (
+
+
+
+
+ Addon (inline-start)
+
+
+
+
+
+
+
+
+
+
+ Addon (inline-end)
+
+
+
+
+
+
+
+
+
+
+ Addon (inline-start and inline-end)
+
+
+
+
+
+
+
+
+
+
+
+
+ Addon (block-start)
+
+
+
+ First Name
+
+
+
+
+
+ Addon (block-end)
+
+
+
+ 20/240 characters
+
+
+
+
+
+ Multiple Icons
+
+
+
+
+ toast("Copied to clipboard")}
+ >
+
+
+
+
+
+
+
+
+
+ Description
+
+
+
+
+
+
+
+ This is a description of the input group.
+
+
+
+ Label
+
+
+ Label
+
+
+
+
+
+
+ (optional)
+
+
+
+
+
+ )
+}
+
+function InputGroupWithButtons() {
+ return (
+
+
+
+ Button
+
+
+
+ Default
+
+
+
+
+
+ Outline
+
+
+
+
+
+ Secondary
+
+
+
+
+
+ Button
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputGroupWithTooltip({
+ country,
+ setCountry,
+}: {
+ country: string
+ setCountry: (value: string) => void
+}) {
+ return (
+
+
+
+ Tooltip
+
+
+
+
+
+
+
+
+
+ This is content in a tooltip.
+
+
+
+
+ This is a description of the input group.
+
+
+
+ Dropdown
+
+
+
+
+
+
+ {country}{" "}
+
+
+
+
+ setCountry("+1")}>
+ +1
+
+ setCountry("+44")}>
+ +44
+
+ setCountry("+46")}>
+ +46
+
+
+
+
+
+
+ This is a description of the input group.
+
+
+
+ Popover
+
+
+
+
+
+
+
+
+
+
+
+ Your connection is not secure.
+
+ You should not enter any sensitive information on this site.
+
+
+
+
+
+ https://
+
+
+
+ toast("Added to favorites")}
+ >
+
+
+
+
+
+ This is a description of the input group.
+
+
+
+
+ )
+}
+
+function InputGroupWithKbd() {
+ return (
+
+
+
+ Input Group with Kbd
+
+
+
+ ⌘K
+
+
+
+
+
+ ⌘K
+
+
+
+
+ Ask AI
+
+ Tab
+
+
+
+
+
+
+
+
+
+ Ctrl
+ C
+
+
+
+
+
+ Username
+
+
+
+
+
+
+
+
+
+ This username is available.
+
+
+
+
+
+
+
+ 12 results
+
+
+
+
+
+
+ Disabled
+
+
+
+ First Name
+
+
+
+
+
+
+
+
+ Last Name
+
+
+
+
+
+
+
+
+
+
+ Loading ("data-disabled="true")
+
+
+
+
+
+
+
+
+ This is a description of the input group.
+
+
+
+
+ )
+}
+
+function InputGroupInCard() {
+ return (
+
+
+
+ Card with Input Group
+ This is a card with an input group.
+
+
+
+
+ Email Address
+
+
+
+
+
+
+
+
+ Website URL
+
+
+ https://
+
+
+
+
+
+
+
+
+
+ Feedback & Comments
+
+
+
+
+ 0/500 characters
+
+
+
+
+
+
+ Cancel
+ Submit
+
+
+
+ )
+}
+
+function InputGroupTextareaExamples() {
+ return (
+
+
+
+
+ Default Textarea (No Input Group)
+
+
+
+
+
+ Input Group
+
+
+
+
+
+ This is a description of the input group.
+
+
+
+ Invalid
+
+
+
+
+ This is a description of the input group.
+
+
+
+ Disabled
+
+
+
+
+ This is a description of the input group.
+
+
+
+ Addon (block-start)
+
+
+
+ Ask, Search or Chat...
+
+
+
+
+ This is a description of the input group.
+
+
+
+
+ Addon (block-end)
+
+
+
+
+ 0/280 characters
+
+
+ Send
+
+
+
+
+
+ Addon (Buttons)
+
+
+
+
+ Cancel
+
+
+ Post Comment
+
+
+
+
+
+ Code Editor
+
+
+
+
+
+ script.js
+
+
+
+
+
+
+
+
+
+ Line 1, Column 1
+ JavaScript
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/input-otp-example.tsx b/apps/v4/registry/radix-lyra/examples/input-otp-example.tsx
new file mode 100644
index 00000000000..4130bf7f2e7
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/input-otp-example.tsx
@@ -0,0 +1,292 @@
+"use client"
+
+import * as React from "react"
+import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import {
+ Field,
+ FieldDescription,
+ FieldError,
+ FieldLabel,
+} from "@/registry/radix-lyra/ui/field"
+import {
+ InputOTP,
+ InputOTPGroup,
+ InputOTPSeparator,
+ InputOTPSlot,
+} from "@/registry/radix-lyra/ui/input-otp"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function InputOTPExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPSimple() {
+ return (
+
+
+ Simple
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPPattern() {
+ return (
+
+
+ Digits Only
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPWithSeparator() {
+ const [value, setValue] = React.useState("123456")
+
+ return (
+
+
+ With Separator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPAlphanumeric() {
+ return (
+
+
+ Alphanumeric
+ Accepts both letters and numbers.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPDisabled() {
+ return (
+
+
+ Disabled
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPFourDigits() {
+ return (
+
+
+ 4 Digits
+ Common pattern for PIN codes.
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPInvalid() {
+ const [value, setValue] = React.useState("000000")
+
+ return (
+
+
+ Invalid State
+
+ Example showing the invalid error state.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function InputOTPForm() {
+ return (
+
+
+
+ Verify your login
+
+ Enter the verification code we sent to your email address:{" "}
+ m@example.com .
+
+
+
+
+
+
+
+ Verify
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/item-example.tsx b/apps/v4/registry/radix-lyra/examples/item-example.tsx
new file mode 100644
index 00000000000..ecbecf61f97
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/item-example.tsx
@@ -0,0 +1,2009 @@
+import Image from "next/image"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Item,
+ ItemActions,
+ ItemContent,
+ ItemDescription,
+ ItemFooter,
+ ItemGroup,
+ ItemHeader,
+ ItemMedia,
+ ItemSeparator,
+ ItemTitle,
+} from "@/registry/radix-lyra/ui/item"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function ItemExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function DefaultVariantItems() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+ Action
+
+
+ -
+
+ Title + Description
+
+ This is a description that provides additional context.
+
+
+
+ -
+
+ Title + Description + Button
+
+ This item includes a title, description, and action button.
+
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+ This item includes media, title, and description.
+
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+ Complete item with all components: media, title, description, and
+ button.
+
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+ Item with multiple action buttons in the actions area.
+
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function OutlineVariantItems() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+ Action
+
+
+ -
+
+ Title + Description
+
+ This is a description that provides additional context.
+
+
+
+ -
+
+ Title + Description + Button
+
+ This item includes a title, description, and action button.
+
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+ This item includes media, title, and description.
+
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+ Complete item with all components: media, title, description, and
+ button.
+
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+ Item with multiple action buttons in the actions area.
+
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function MutedVariantItems() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+ Action
+
+
+ -
+
+ Title + Description
+
+ This is a description that provides additional context.
+
+
+
+ -
+
+ Title + Description + Button
+
+ This item includes a title, description, and action button.
+
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+ This item includes media, title, and description.
+
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+ Complete item with all components: media, title, description, and
+ button.
+
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+ Item with multiple action buttons in the actions area.
+
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function DefaultVariantItemsSmall() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+
+ Action
+
+
+
+ -
+
+ Title + Description
+
+ This is a description that provides additional context.
+
+
+
+ -
+
+ Title + Description + Button
+
+ This item includes a title, description, and action button.
+
+
+
+
+ Action
+
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+ This item includes media, title, and description.
+
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+ Complete item with all components: media, title, description, and
+ button.
+
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+ Item with multiple action buttons in the actions area.
+
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function OutlineVariantItemsSmall() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+
+ Action
+
+
+
+ -
+
+ Title + Description
+
+ This is a description that provides additional context.
+
+
+
+ -
+
+ Title + Description + Button
+
+ This item includes a title, description, and action button.
+
+
+
+
+ Action
+
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+ This item includes media, title, and description.
+
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+ Complete item with all components: media, title, description, and
+ button.
+
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+ Item with multiple action buttons in the actions area.
+
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function MutedVariantItemsSmall() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+
+ Action
+
+
+
+ -
+
+ Title + Description
+
+ This is a description that provides additional context.
+
+
+
+ -
+
+ Title + Description + Button
+
+ This item includes a title, description, and action button.
+
+
+
+
+ Action
+
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+ This item includes media, title, and description.
+
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+ Complete item with all components: media, title, description, and
+ button.
+
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+ Item with multiple action buttons in the actions area.
+
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function DefaultVariantItemsExtraSmall() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+
+ Action
+
+
+
+ -
+
+ Title + Description
+
+
+ -
+
+ Title + Description + Button
+
+
+
+ Action
+
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function OutlineVariantItemsExtraSmall() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+
+ Action
+
+
+
+ -
+
+ Title + Description
+
+
+ -
+
+ Title + Description + Button
+
+
+
+ Action
+
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function MutedVariantItemsExtraSmall() {
+ return (
+
+ -
+
+ Title Only
+
+
+ -
+
+ Title + Button
+
+
+
+ Action
+
+
+
+ -
+
+ Title + Description
+
+
+ -
+
+ Title + Description + Button
+
+
+
+ Action
+
+
+
+ -
+
+
+
+
+ Media + Title
+
+
+ -
+
+
+
+
+ Media + Title + Button
+
+
+ Action
+
+
+ -
+
+
+
+
+ Media + Title + Description
+
+
+ -
+
+
+
+
+ Media + Title + Description + Button
+
+
+ Action
+
+
+ -
+
+ Multiple Actions
+
+
+
+ Cancel
+
+ Confirm
+
+
+
+ )
+}
+
+function DefaultLinkItems() {
+ return (
+
+
+ -
+
+
+ Title Only (Link)
+
+
+
+ -
+
+
+ Title + Description (Link)
+
+ Clickable item with title and description.
+
+
+
+
+ -
+
+
+
+
+
+ Media + Title (Link)
+
+
+
+ -
+
+
+
+
+
+ Media + Title + Description (Link)
+
+ Complete link item with media, title, and description.
+
+
+
+
+ -
+
+
+ With Actions (Link)
+
+ Link item that also has action buttons.
+
+
+
+
+ Share
+
+
+
+
+
+
+ )
+}
+
+function OutlineLinkItems() {
+ return (
+
+
+ -
+
+
+ Title Only (Link)
+
+
+
+ -
+
+
+ Title + Description (Link)
+
+ Clickable item with title and description.
+
+
+
+
+ -
+
+
+
+
+
+ Media + Title (Link)
+
+
+
+ -
+
+
+
+
+
+ Media + Title + Description (Link)
+
+ Complete link item with media, title, and description.
+
+
+
+
+ -
+
+
+ With Actions (Link)
+
+ Link item that also has action buttons.
+
+
+
+
+ Share
+
+
+
+
+
+
+ )
+}
+
+function MutedLinkItems() {
+ return (
+
+
+ -
+
+
+ Title Only (Link)
+
+
+
+ -
+
+
+ Title + Description (Link)
+
+ Clickable item with title and description.
+
+
+
+
+ -
+
+
+
+
+
+ Media + Title (Link)
+
+
+
+ -
+
+
+
+
+
+ Media + Title + Description (Link)
+
+ Complete link item with media, title, and description.
+
+
+
+
+ -
+
+
+ With Actions (Link)
+
+ Link item that also has action buttons.
+
+
+
+
+ Share
+
+
+
+
+
+
+ )
+}
+
+function DefaultItemGroup() {
+ return (
+
+
+ -
+
+ Item 1
+ First item in the group.
+
+
+ -
+
+ Item 2
+ Second item in the group.
+
+
+ -
+
+ Item 3
+ Third item in the group.
+
+
+
+
+ )
+}
+
+function OutlineItemGroup() {
+ return (
+
+
+ -
+
+
+
+
+ Item 1
+ First item with icon.
+
+
+ -
+
+
+
+
+ Item 2
+ Second item with icon.
+
+
+ -
+
+
+
+
+ Item 3
+ Third item with icon.
+
+
+
+
+ )
+}
+
+function MutedItemGroup() {
+ return (
+
+
+ -
+
+ Item 1
+ First item in muted group.
+
+
+
+ Action
+
+
+
+ -
+
+ Item 2
+ Second item in muted group.
+
+
+
+ Action
+
+
+
+ -
+
+ Item 3
+ Third item in muted group.
+
+
+
+ Action
+
+
+
+
+
+ )
+}
+
+function ItemSeparatorExample() {
+ return (
+
+
+ -
+
+
+
+
+ Inbox
+ View all incoming messages.
+
+
+
+ -
+
+
+
+
+ Sent
+ View all sent messages.
+
+
+
+ -
+
+
+
+
+ Drafts
+ View all draft messages.
+
+
+
+ -
+
+
+
+
+ Archive
+ View archived messages.
+
+
+
+
+ )
+}
+
+function ItemHeaderExamples() {
+ return (
+
+ -
+
+ Design System
+
+
+ Component Library
+
+ A comprehensive collection of reusable UI components for building
+ consistent interfaces.
+
+
+
+ -
+
+ Marketing
+
+
+ Campaign Analytics
+
+ Track performance metrics and engagement rates across all marketing
+ channels.
+
+
+
+ -
+
+ Engineering
+
+
+ API Documentation
+
+ Complete reference guide for all available endpoints and
+ authentication methods.
+
+
+
+
+ )
+}
+
+function ItemFooterExamples() {
+ return (
+
+ -
+
+ Quarterly Report Q4 2024
+
+ Financial overview including revenue, expenses, and growth metrics
+ for the fourth quarter.
+
+
+
+
+ Last updated 2 hours ago
+
+
+
+ -
+
+ User Research Findings
+
+ Insights from interviews and surveys conducted with 50+ users across
+ different demographics.
+
+
+
+
+ Created by Sarah Chen
+
+
+
+ -
+
+ Product Roadmap
+
+ Planned features and improvements scheduled for the next three
+ months.
+
+
+
+ 12 comments
+
+
+
+ )
+}
+
+function ItemHeaderAndFooterExamples() {
+ return (
+
+ -
+
+ Team Project
+
+
+ Website Redesign
+
+ Complete overhaul of the company website with modern design
+ principles and improved user experience.
+
+
+
+
+ Updated 5 minutes ago
+
+
+
+ -
+
+ Client Work
+
+
+ Mobile App Development
+
+ Building a cross-platform mobile application for iOS and Android
+ with React Native.
+
+
+
+
+ Status: In Progress
+
+
+
+ -
+
+ Documentation
+
+
+ API Integration Guide
+
+ Step-by-step instructions for integrating third-party APIs with
+ authentication and error handling.
+
+
+
+
+ Category: Technical • 3 attachments
+
+
+
+
+ )
+}
+
+function DefaultVariantItemsWithImage() {
+ return (
+
+ -
+
+
+
+
+ Project Dashboard
+
+ Overview of project settings and configuration.
+
+
+
+ -
+
+
+
+
+ Document
+ A document with metadata displayed.
+
+
+
+ View
+
+
+
+ -
+
+
+
+
+ File Attachment
+
+ Complete file with image, title, description, and action button.
+
+
+
+ Download
+
+
+
+ )
+}
+
+function OutlineVariantItemsWithImage() {
+ return (
+
+ -
+
+
+
+
+ Project Dashboard
+
+ Overview of project settings and configuration.
+
+
+
+ -
+
+
+
+
+ Document
+ A document with metadata displayed.
+
+
+
+ View
+
+
+
+ -
+
+
+
+
+ File Attachment
+
+ Complete file with image, title, description, and action button.
+
+
+
+ Download
+
+
+
+ )
+}
+
+function OutlineVariantItemsWithImageSmall() {
+ return (
+
+ -
+
+
+
+
+ Project Dashboard
+
+ Overview of project settings and configuration.
+
+
+
+ -
+
+
+
+
+ Document
+ A document with metadata displayed.
+
+
+
+ View
+
+
+
+ -
+
+
+
+
+ File Attachment
+
+ Complete file with image, title, description, and action button.
+
+
+
+ Download
+
+
+
+ )
+}
+
+function OutlineVariantItemsWithImageExtraSmall() {
+ return (
+
+ -
+
+
+
+
+ Project Dashboard
+
+
+ -
+
+
+
+
+ Document
+
+
+
+ View
+
+
+
+ -
+
+
+
+
+ File Attachment
+
+
+ Download
+
+
+
+ )
+}
+
+function MutedVariantItemsWithImage() {
+ return (
+
+ -
+
+
+
+
+ Project Dashboard
+
+ Overview of project settings and configuration.
+
+
+
+ -
+
+
+
+
+ Document
+ A document with metadata displayed.
+
+
+
+ View
+
+
+
+ -
+
+
+
+
+ File Attachment
+
+ Complete file with image, title, description, and action button.
+
+
+
+ Download
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/kbd-example.tsx b/apps/v4/registry/radix-lyra/examples/kbd-example.tsx
new file mode 100644
index 00000000000..c2fbb7ee601
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/kbd-example.tsx
@@ -0,0 +1,194 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+} from "@/registry/radix-lyra/ui/input-group"
+import { Kbd, KbdGroup } from "@/registry/radix-lyra/ui/kbd"
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/registry/radix-lyra/ui/tooltip"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function KbdExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function KbdBasic() {
+ return (
+
+
+ Ctrl
+ ⌘K
+ Ctrl + B
+
+
+ )
+}
+
+function KbdModifierKeys() {
+ return (
+
+
+ ⌘
+ C
+
+
+ )
+}
+
+function KbdGroupExample() {
+ return (
+
+
+ Ctrl
+ Shift
+ P
+
+
+ )
+}
+
+function KbdArrowKeys() {
+ return (
+
+
+ ↑
+ ↓
+ ←
+ →
+
+
+ )
+}
+
+function KbdWithIcons() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function KbdWithIconsAndText() {
+ return (
+
+
+
+
+ Left
+
+
+
+ Voice Enabled
+
+
+
+ )
+}
+
+function KbdInInputGroup() {
+ return (
+
+
+
+
+ Space
+
+
+
+ )
+}
+
+function KbdInTooltip() {
+ return (
+
+
+
+
+
+
+
+
+
+ Save Changes S
+
+
+
+
+ )
+}
+
+function KbdWithSamp() {
+ return (
+
+
+ File
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/label-example.tsx b/apps/v4/registry/radix-lyra/examples/label-example.tsx
new file mode 100644
index 00000000000..a2c1d65d29a
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/label-example.tsx
@@ -0,0 +1,64 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Checkbox } from "@/registry/radix-lyra/ui/checkbox"
+import { Field } from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import { Label } from "@/registry/radix-lyra/ui/label"
+import { Textarea } from "@/registry/radix-lyra/ui/textarea"
+
+export default function LabelExample() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+function LabelWithCheckbox() {
+ return (
+
+
+
+ Accept terms and conditions
+
+
+ )
+}
+
+function LabelWithInput() {
+ return (
+
+
+ Username
+
+
+
+ )
+}
+
+function LabelDisabled() {
+ return (
+
+
+ Disabled
+
+
+
+ )
+}
+
+function LabelWithTextarea() {
+ return (
+
+
+ Message
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/menubar-example.tsx b/apps/v4/registry/radix-lyra/examples/menubar-example.tsx
new file mode 100644
index 00000000000..1eb305deba4
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/menubar-example.tsx
@@ -0,0 +1,807 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import {
+ Menubar,
+ MenubarCheckboxItem,
+ MenubarContent,
+ MenubarGroup,
+ MenubarItem,
+ MenubarLabel,
+ MenubarMenu,
+ MenubarRadioGroup,
+ MenubarRadioItem,
+ MenubarSeparator,
+ MenubarShortcut,
+ MenubarSub,
+ MenubarSubContent,
+ MenubarSubTrigger,
+ MenubarTrigger,
+} from "@/registry/radix-lyra/ui/menubar"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function MenubarExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function MenubarBasic() {
+ return (
+
+
+
+ File
+
+
+
+ New Tab ⌘T
+
+
+ New Window ⌘N
+
+ New Incognito Window
+
+
+
+
+ Print... ⌘P
+
+
+
+
+
+ Edit
+
+
+
+ Undo ⌘Z
+
+
+ Redo ⇧⌘Z
+
+
+
+
+ Cut
+ Copy
+ Paste
+
+
+
+
+
+ )
+}
+
+function MenubarWithSubmenu() {
+ return (
+
+
+
+ File
+
+
+ Share
+
+
+ Email link
+ Messages
+ Notes
+
+
+
+
+
+
+ Print... ⌘P
+
+
+
+
+
+ Edit
+
+
+
+ Undo ⌘Z
+
+
+ Redo ⇧⌘Z
+
+
+
+
+ Find
+
+
+ Find...
+ Find Next
+ Find Previous
+
+
+
+
+
+ Cut
+ Copy
+ Paste
+
+
+
+
+
+ )
+}
+
+function MenubarWithCheckboxes() {
+ return (
+
+
+
+ View
+
+
+
+ Always Show Bookmarks Bar
+
+
+ Always Show Full URLs
+
+
+
+
+
+ Reload ⌘R
+
+
+ Force Reload ⇧⌘R
+
+
+
+
+
+ Format
+
+ Strikethrough
+ Code
+ Superscript
+
+
+
+
+ )
+}
+
+function MenubarWithRadio() {
+ const [user, setUser] = React.useState("benoit")
+ const [theme, setTheme] = React.useState("system")
+
+ return (
+
+
+
+ Profiles
+
+
+ Andy
+ Benoit
+ Luis
+
+
+
+ Edit...
+ Add Profile...
+
+
+
+
+ Theme
+
+
+ Light
+ Dark
+ System
+
+
+
+
+
+ )
+}
+
+function MenubarWithIcons() {
+ return (
+
+
+
+ File
+
+
+
+
+ New File ⌘N
+
+
+
+ Open Folder
+
+
+
+
+
+
+ Save ⌘S
+
+
+
+
+
+ More
+
+
+
+
+ Settings
+
+
+
+ Help
+
+
+
+
+ Delete
+
+
+
+
+
+
+ )
+}
+
+function MenubarWithShortcuts() {
+ return (
+
+
+
+ File
+
+
+
+ New Tab ⌘T
+
+
+ New Window ⌘N
+
+
+ Print... ⌘P
+
+
+
+
+
+ Edit
+
+
+
+ Undo ⌘Z
+
+
+ Redo ⇧⌘Z
+
+
+
+
+
+ Cut ⌘X
+
+
+ Copy ⌘C
+
+
+ Paste ⌘V
+
+
+
+
+
+
+ )
+}
+
+function MenubarFormat() {
+ return (
+
+
+
+ Format
+
+
+
+
+ Bold ⌘B
+
+
+
+ Italic ⌘I
+
+
+
+ Underline ⌘U
+
+
+
+
+ Strikethrough
+ Code
+
+
+
+
+ View
+
+ Show Ruler
+ Show Grid
+
+
+ Zoom In
+ Zoom Out
+
+
+
+
+
+ )
+}
+
+function MenubarInsert() {
+ return (
+
+
+
+ Insert
+
+
+
+
+ Media
+
+
+
+ Image
+ Video
+ Audio
+
+
+
+
+
+
+
+ Link ⌘K
+
+
+
+ Table
+
+
+
+
+
+ Tools
+
+
+
+
+ Find & Replace ⌘F
+
+
+
+ Spell Check
+
+
+
+
+
+
+ )
+}
+
+function MenubarDestructive() {
+ return (
+
+
+
+ File
+
+
+
+
+ New File ⌘N
+
+
+
+ Open Folder
+
+
+
+
+
+
+ Delete File ⌘⌫
+
+
+
+
+
+ Account
+
+
+
+
+ Profile
+
+
+
+ Settings
+
+
+
+
+
+
+ Sign out
+
+
+
+
+
+
+ Delete
+
+
+
+
+
+
+ )
+}
+
+function MenubarInDialog() {
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Menubar Example
+
+ Use the menubar below to see the menu options.
+
+
+
+
+ File
+
+
+
+
+ Copy
+
+
+
+ Cut
+
+
+
+ Paste
+
+
+
+
+ More Options
+
+
+ Save Page...
+ Create Shortcut...
+ Name Window...
+
+
+
+ Developer Tools
+
+
+
+
+
+
+
+ Delete
+
+
+
+
+
+ Edit
+
+
+
+ Undo ⌘Z
+
+
+ Redo ⇧⌘Z
+
+
+
+
+
+
+
+
+ )
+}
+
+function MenubarWithInset() {
+ const [showBookmarks, setShowBookmarks] = React.useState(true)
+ const [showUrls, setShowUrls] = React.useState(false)
+ const [theme, setTheme] = React.useState("system")
+
+ return (
+
+
+
+ View
+
+
+ Actions
+
+
+ Copy
+
+
+
+ Cut
+
+ Paste
+
+
+
+ Appearance
+
+ Bookmarks
+
+
+ Full URLs
+
+
+
+
+ Theme
+
+
+ Light
+
+
+ Dark
+
+
+ System
+
+
+
+
+
+ More Options
+
+
+ Save Page...
+ Create Shortcut...
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/native-select-example.tsx b/apps/v4/registry/radix-lyra/examples/native-select-example.tsx
new file mode 100644
index 00000000000..a709a32133d
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/native-select-example.tsx
@@ -0,0 +1,129 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Field,
+ FieldDescription,
+ FieldLabel,
+} from "@/registry/radix-lyra/ui/field"
+import {
+ NativeSelect,
+ NativeSelectOptGroup,
+ NativeSelectOption,
+} from "@/registry/radix-lyra/ui/native-select"
+
+export default function NativeSelectExample() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+function NativeSelectBasic() {
+ return (
+
+
+ Select a fruit
+ Apple
+ Banana
+ Blueberry
+
+ Grapes
+
+ Pineapple
+
+
+ )
+}
+
+function NativeSelectWithGroups() {
+ return (
+
+
+ Select a food
+
+ Apple
+ Banana
+ Blueberry
+
+
+ Carrot
+ Broccoli
+ Spinach
+
+
+
+ )
+}
+
+function NativeSelectSizes() {
+ return (
+
+
+
+ Select a fruit
+ Apple
+ Banana
+ Blueberry
+
+
+ Select a fruit
+ Apple
+ Banana
+ Blueberry
+
+
+
+ )
+}
+
+function NativeSelectWithField() {
+ return (
+
+
+ Country
+
+ Select a country
+ United States
+ United Kingdom
+ Canada
+ Australia
+
+ Select your country of residence.
+
+
+ )
+}
+
+function NativeSelectDisabled() {
+ return (
+
+
+ Disabled
+ Apple
+ Banana
+ Blueberry
+
+
+ )
+}
+
+function NativeSelectInvalid() {
+ return (
+
+
+ Error state
+ Apple
+ Banana
+ Blueberry
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/navigation-menu-example.tsx b/apps/v4/registry/radix-lyra/examples/navigation-menu-example.tsx
new file mode 100644
index 00000000000..5c54b6ce8cd
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/navigation-menu-example.tsx
@@ -0,0 +1,268 @@
+"use client"
+
+import * as React from "react"
+import Link from "next/link"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ NavigationMenu,
+ NavigationMenuContent,
+ NavigationMenuItem,
+ NavigationMenuLink,
+ NavigationMenuList,
+ NavigationMenuTrigger,
+ navigationMenuTriggerStyle,
+} from "@/registry/radix-lyra/ui/navigation-menu"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+const components: { title: string; href: string; description: string }[] = [
+ {
+ title: "Alert Dialog",
+ href: "/docs/primitives/alert-dialog",
+ description:
+ "A modal dialog that interrupts the user with important content and expects a response.",
+ },
+ {
+ title: "Hover Card",
+ href: "/docs/primitives/hover-card",
+ description:
+ "For sighted users to preview content available behind a link.",
+ },
+ {
+ title: "Progress",
+ href: "/docs/primitives/progress",
+ description:
+ "Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.",
+ },
+ {
+ title: "Scroll-area",
+ href: "/docs/primitives/scroll-area",
+ description: "Visually or semantically separates content.",
+ },
+ {
+ title: "Tabs",
+ href: "/docs/primitives/tabs",
+ description:
+ "A set of layered sections of content—known as tab panels—that are displayed one at a time.",
+ },
+ {
+ title: "Tooltip",
+ href: "/docs/primitives/tooltip",
+ description:
+ "A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.",
+ },
+]
+
+export default function NavigationMenuExample() {
+ return (
+
+
+
+
+ )
+}
+
+function NavigationMenuWithViewport() {
+ return (
+
+
+
+
+ Getting started
+
+
+
+ Re-usable components built with Tailwind CSS.
+
+
+ How to install dependencies and structure your app.
+
+
+ Styles for headings, paragraphs, lists...etc
+
+
+
+
+
+ Components
+
+
+ {components.map((component) => (
+
+ {component.description}
+
+ ))}
+
+
+
+
+
+ Documentation
+
+
+
+
+
+ )
+}
+
+function NavigationMenuWithoutViewport() {
+ return (
+
+
+
+
+
+ Documentation
+
+
+
+ List
+
+
+
+
+
+
+
+ Components
+
+
+ Browse all components in the library.
+
+
+
+
+
+
+
+
+ Documentation
+
+
+ Learn how to use the library.
+
+
+
+
+
+
+
+
+ Blog
+
+
+ Read our latest blog posts.
+
+
+
+
+
+
+
+
+
+ Simple List
+
+
+
+
+ Components
+
+
+ Documentation
+
+
+ Blocks
+
+
+
+
+
+
+ With Icon
+
+
+
+
+
+
+ Backlog
+
+
+
+
+
+ To Do
+
+
+
+
+
+ Done
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function ListItem({
+ title,
+ children,
+ href,
+ ...props
+}: React.ComponentPropsWithoutRef<"li"> & { href: string }) {
+ return (
+
+
+
+
+
+ {title}
+
+
+ {children}
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/pagination-example.tsx b/apps/v4/registry/radix-lyra/examples/pagination-example.tsx
new file mode 100644
index 00000000000..549d0ed1dd4
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/pagination-example.tsx
@@ -0,0 +1,126 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Field, FieldLabel } from "@/registry/radix-lyra/ui/field"
+import {
+ Pagination,
+ PaginationContent,
+ PaginationEllipsis,
+ PaginationItem,
+ PaginationLink,
+ PaginationNext,
+ PaginationPrevious,
+} from "@/registry/radix-lyra/ui/pagination"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+
+export default function PaginationExample() {
+ return (
+
+
+
+
+
+ )
+}
+
+function PaginationBasic() {
+ return (
+
+
+
+
+
+
+
+ 1
+
+
+
+ 2
+
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function PaginationSimple() {
+ return (
+
+
+
+
+ 1
+
+
+
+ 2
+
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+
+
+ )
+}
+
+function PaginationIconsOnly() {
+ return (
+
+
+
+ Rows per page
+
+
+
+
+
+
+ 10
+ 25
+ 50
+ 100
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/popover-example.tsx b/apps/v4/registry/radix-lyra/examples/popover-example.tsx
new file mode 100644
index 00000000000..01a301729e5
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/popover-example.tsx
@@ -0,0 +1,163 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import { Field, FieldGroup, FieldLabel } from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ Popover,
+ PopoverContent,
+ PopoverDescription,
+ PopoverHeader,
+ PopoverTitle,
+ PopoverTrigger,
+} from "@/registry/radix-lyra/ui/popover"
+
+export default function PopoverExample() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+function PopoverBasic() {
+ return (
+
+
+
+ Open Popover
+
+
+
+ Dimensions
+
+ Set the dimensions for the layer.
+
+
+
+
+
+ )
+}
+
+function PopoverWithForm() {
+ return (
+
+
+
+ Open Popover
+
+
+
+ Dimensions
+
+ Set the dimensions for the layer.
+
+
+
+
+
+ Width
+
+
+
+
+
+ Height
+
+
+
+
+
+
+
+ )
+}
+
+function PopoverAlignments() {
+ return (
+
+
+
+
+
+ Start
+
+
+
+ Aligned to start
+
+
+
+
+
+ Center
+
+
+
+ Aligned to center
+
+
+
+
+
+ End
+
+
+
+ Aligned to end
+
+
+
+
+ )
+}
+
+function PopoverInDialog() {
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Popover Example
+
+ Click the button below to see the popover.
+
+
+
+
+
+ Open Popover
+
+
+
+
+ Popover in Dialog
+
+ This popover appears inside a dialog. Click the button to open
+ it.
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/progress-example.tsx b/apps/v4/registry/radix-lyra/examples/progress-example.tsx
new file mode 100644
index 00000000000..1eed193c401
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/progress-example.tsx
@@ -0,0 +1,142 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Field, FieldLabel } from "@/registry/radix-lyra/ui/field"
+import {
+ Item,
+ ItemActions,
+ ItemContent,
+ ItemGroup,
+ ItemMedia,
+ ItemTitle,
+} from "@/registry/radix-lyra/ui/item"
+import { Progress } from "@/registry/radix-lyra/ui/progress"
+import { Slider } from "@/registry/radix-lyra/ui/slider"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function ProgressExample() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+function ProgressValues() {
+ return (
+
+
+
+ )
+}
+
+function ProgressWithLabel() {
+ return (
+
+
+
+ Upload progress
+ 66%
+
+
+
+
+ )
+}
+
+function ProgressControlled() {
+ const [value, setValue] = React.useState([50])
+
+ return (
+
+
+
+ )
+}
+
+function FileUploadList() {
+ const files = React.useMemo(
+ () => [
+ {
+ id: "1",
+ name: "document.pdf",
+ progress: 45,
+ timeRemaining: "2m 30s",
+ },
+ {
+ id: "2",
+ name: "presentation.pptx",
+ progress: 78,
+ timeRemaining: "45s",
+ },
+ {
+ id: "3",
+ name: "spreadsheet.xlsx",
+ progress: 12,
+ timeRemaining: "5m 12s",
+ },
+ {
+ id: "4",
+ name: "image.jpg",
+ progress: 100,
+ timeRemaining: "Complete",
+ },
+ ],
+ []
+ )
+
+ return (
+
+
+ {files.map((file) => (
+ -
+
+
+
+
+ {file.name}
+
+
+
+
+
+
+ {file.timeRemaining}
+
+
+
+ ))}
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/radio-group-example.tsx b/apps/v4/registry/radix-lyra/examples/radio-group-example.tsx
new file mode 100644
index 00000000000..dabdee238a2
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/radio-group-example.tsx
@@ -0,0 +1,222 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ Field,
+ FieldContent,
+ FieldDescription,
+ FieldLabel,
+ FieldLegend,
+ FieldSet,
+} from "@/registry/radix-lyra/ui/field"
+import {
+ RadioGroup,
+ RadioGroupItem,
+} from "@/registry/radix-lyra/ui/radio-group"
+
+export default function RadioGroupExample() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+function RadioGroupBasic() {
+ return (
+
+
+
+
+
+ Default
+
+
+
+
+
+ Comfortable
+
+
+
+
+
+ Compact
+
+
+
+
+ )
+}
+
+function RadioGroupWithDescriptions() {
+ return (
+
+
+
+
+
+ Plus
+
+ For individuals and small teams
+
+
+
+
+
+
+
+
+ Pro
+ For growing businesses
+
+
+
+
+
+
+
+ Enterprise
+
+ For large teams and enterprises
+
+
+
+
+
+
+
+ )
+}
+
+function RadioGroupWithFieldSet() {
+ return (
+
+
+ Battery Level
+
+ Choose your preferred battery level.
+
+
+
+
+
+ High
+
+
+
+
+
+ Medium
+
+
+
+
+
+ Low
+
+
+
+
+
+ )
+}
+
+function RadioGroupGrid() {
+ return (
+
+
+
+
+
+ Small
+
+
+
+
+
+ Medium
+
+
+
+
+
+ Large
+
+
+
+
+
+ X-Large
+
+
+
+
+ )
+}
+
+function RadioGroupDisabled() {
+ return (
+
+
+
+
+
+ Option 1
+
+
+
+
+
+ Option 2
+
+
+
+
+
+ Option 3
+
+
+
+
+ )
+}
+
+function RadioGroupInvalid() {
+ return (
+
+
+ Notification Preferences
+
+ Choose how you want to receive notifications.
+
+
+
+
+
+ Email only
+
+
+
+
+
+ SMS only
+
+
+
+
+
+ Both Email & SMS
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/resizable-example.tsx b/apps/v4/registry/radix-lyra/examples/resizable-example.tsx
new file mode 100644
index 00000000000..59bc07a9d8d
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/resizable-example.tsx
@@ -0,0 +1,158 @@
+"use client"
+
+import * as React from "react"
+import type { Layout } from "react-resizable-panels"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import {
+ ResizableHandle,
+ ResizablePanel,
+ ResizablePanelGroup,
+} from "@/registry/radix-lyra/ui/resizable"
+
+export default function ResizableExample() {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+function ResizableHorizontal() {
+ return (
+
+
+
+
+ Sidebar
+
+
+
+
+
+ Content
+
+
+
+
+ )
+}
+
+function ResizableVertical() {
+ return (
+
+
+
+
+ Header
+
+
+
+
+
+ Content
+
+
+
+
+ )
+}
+
+function ResizableWithHandle() {
+ return (
+
+
+
+
+ Sidebar
+
+
+
+
+
+ Content
+
+
+
+
+ )
+}
+
+function ResizableNested() {
+ return (
+
+
+
+
+ One
+
+
+
+
+
+
+
+ Two
+
+
+
+
+
+ Three
+
+
+
+
+
+
+ )
+}
+
+function ResizableControlled() {
+ const [layout, setLayout] = React.useState({})
+
+ return (
+
+
+
+
+
+ {Math.round(layout.left ?? 30)}%
+
+
+
+
+
+
+
+ {Math.round(layout.right ?? 70)}%
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/scroll-area-example.tsx b/apps/v4/registry/radix-lyra/examples/scroll-area-example.tsx
new file mode 100644
index 00000000000..ccfe5e476fd
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/scroll-area-example.tsx
@@ -0,0 +1,86 @@
+import * as React from "react"
+import Image from "next/image"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { ScrollArea, ScrollBar } from "@/registry/radix-lyra/ui/scroll-area"
+import { Separator } from "@/registry/radix-lyra/ui/separator"
+
+const tags = Array.from({ length: 50 }).map(
+ (_, i, a) => `v1.2.0-beta.${a.length - i}`
+)
+
+const works = [
+ {
+ artist: "Ornella Binni",
+ art: "https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80",
+ },
+ {
+ artist: "Tom Byrom",
+ art: "https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80",
+ },
+ {
+ artist: "Vladimir Malyav",
+ art: "https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80",
+ },
+] as const
+
+export default function ScrollAreaExample() {
+ return (
+
+
+
+
+ )
+}
+
+function ScrollAreaVertical() {
+ return (
+
+
+
+
Tags
+ {tags.map((tag) => (
+
+ {tag}
+
+
+ ))}
+
+
+
+ )
+}
+
+function ScrollAreaHorizontal() {
+ return (
+
+
+
+ {works.map((artwork) => (
+
+
+
+
+
+ Photo by{" "}
+
+ {artwork.artist}
+
+
+
+ ))}
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/select-example.tsx b/apps/v4/registry/radix-lyra/examples/select-example.tsx
new file mode 100644
index 00000000000..cf198cd7927
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/select-example.tsx
@@ -0,0 +1,554 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/registry/radix-lyra/ui/dialog"
+import {
+ Field,
+ FieldDescription,
+ FieldError,
+ FieldLabel,
+} from "@/registry/radix-lyra/ui/field"
+import { Input } from "@/registry/radix-lyra/ui/input"
+import {
+ Item,
+ ItemContent,
+ ItemDescription,
+ ItemTitle,
+} from "@/registry/radix-lyra/ui/item"
+import {
+ NativeSelect,
+ NativeSelectOption,
+} from "@/registry/radix-lyra/ui/native-select"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectLabel,
+ SelectSeparator,
+ SelectTrigger,
+ SelectValue,
+} from "@/registry/radix-lyra/ui/select"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function SelectExample() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function SelectBasic() {
+ return (
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+
+ Grapes
+
+ Pineapple
+
+
+
+
+ )
+}
+
+function SelectWithIcons() {
+ return (
+
+
+
+
+
+
+ Chart Type
+ >
+ }
+ />
+
+
+
+
+
+ Line
+
+
+
+ Bar
+
+
+
+ Pie
+
+
+
+
+
+
+
+
+ Chart Type
+ >
+ }
+ />
+
+
+
+
+
+ Line
+
+
+
+ Bar
+
+
+
+ Pie
+
+
+
+
+
+
+ )
+}
+
+function SelectWithGroups() {
+ return (
+
+
+
+
+
+
+
+ Fruits
+ Apple
+ Banana
+ Blueberry
+
+
+
+ Vegetables
+ Carrot
+ Broccoli
+ Spinach
+
+
+
+
+ )
+}
+
+function SelectLargeList() {
+ return (
+
+
+
+
+
+
+
+ {Array.from({ length: 100 }).map((_, i) => (
+
+ Item {i}
+
+ ))}
+
+
+
+
+ )
+}
+
+function SelectSizes() {
+ return (
+
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+
+
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+
+
+
+
+
+ )
+}
+
+function SelectWithButton() {
+ return (
+
+
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+
+
+
+ Submit
+
+
+
+ )
+}
+
+function SelectItemAligned() {
+ return (
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+
+ Grapes
+
+ Pineapple
+
+
+
+
+ )
+}
+
+function SelectWithField() {
+ return (
+
+
+ Favorite Fruit
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+ Grapes
+ Pineapple
+
+
+
+
+ Choose your favorite fruit from the list.
+
+
+
+ )
+}
+
+function SelectInvalid() {
+ return (
+
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+ Grapes
+ Pineapple
+
+
+
+
+ Favorite Fruit
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+ Grapes
+ Pineapple
+
+
+
+
+
+
+
+ )
+}
+
+function SelectInline() {
+ return (
+
+
+
+
+
+
+
+
+
+ All
+ Active
+ Inactive
+
+
+
+
+ Sort by
+ Name
+ Date
+ Status
+
+
+
+ )
+}
+
+function SelectDisabled() {
+ return (
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+
+ Grapes
+
+ Pineapple
+
+
+
+
+ )
+}
+
+const plans = [
+ {
+ name: "Starter",
+ description: "Perfect for individuals getting started.",
+ },
+ {
+ name: "Professional",
+ description: "Ideal for growing teams and businesses.",
+ },
+ {
+ name: "Enterprise",
+ description: "Advanced features for large organizations.",
+ },
+]
+
+function SelectPlan() {
+ const [plan, setPlan] = React.useState(plans[0].name)
+
+ const selectedPlan = plans.find((p) => p.name === plan)
+
+ return (
+
+
+
+
+ {selectedPlan && }
+
+
+
+
+ {plans.map((plan) => (
+
+
+
+ ))}
+
+
+
+
+ )
+}
+
+function SelectPlanItem({ plan }: { plan: (typeof plans)[number] }) {
+ return (
+ -
+
+ {plan.name}
+
+ {plan.description}
+
+
+
+ )
+}
+
+function SelectInDialog() {
+ return (
+
+
+
+ Open Dialog
+
+
+
+ Select Example
+
+ Use the select below to choose a fruit.
+
+
+
+
+
+
+
+
+ Apple
+ Banana
+ Blueberry
+ Grapes
+ Pineapple
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/separator-example.tsx b/apps/v4/registry/radix-lyra/examples/separator-example.tsx
new file mode 100644
index 00000000000..b03dbd635b1
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/separator-example.tsx
@@ -0,0 +1,100 @@
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Separator } from "@/registry/radix-lyra/ui/separator"
+
+export default function SeparatorExample() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+function SeparatorHorizontal() {
+ return (
+
+
+
+
shadcn/ui
+
+ The Foundation for your Design System
+
+
+
+
+ A set of beautifully designed components that you can customize,
+ extend, and build on.
+
+
+
+ )
+}
+
+function SeparatorVertical() {
+ return (
+
+
+
Blog
+
+
Docs
+
+
Source
+
+
+ )
+}
+
+function SeparatorVerticalMenu() {
+ return (
+
+
+
+ Settings
+
+ Manage preferences
+
+
+
+
+ Account
+
+ Profile & security
+
+
+
+
+ Help
+ Support & docs
+
+
+
+ )
+}
+
+function SeparatorInList() {
+ return (
+
+
+
+ Item 1
+ Value 1
+
+
+
+ Item 2
+ Value 2
+
+
+
+ Item 3
+ Value 3
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/sidebar-example.tsx b/apps/v4/registry/radix-lyra/examples/sidebar-example.tsx
new file mode 100644
index 00000000000..410b17476cd
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/sidebar-example.tsx
@@ -0,0 +1,286 @@
+"use client"
+
+import * as React from "react"
+
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/registry/radix-lyra/ui/dropdown-menu"
+import {
+ Item,
+ ItemActions,
+ ItemContent,
+ ItemDescription,
+ ItemMedia,
+ ItemTitle,
+} from "@/registry/radix-lyra/ui/item"
+import { Label } from "@/registry/radix-lyra/ui/label"
+import {
+ Sidebar,
+ SidebarContent,
+ SidebarGroup,
+ SidebarGroupContent,
+ SidebarGroupLabel,
+ SidebarHeader,
+ SidebarInput,
+ SidebarInset,
+ SidebarMenu,
+ SidebarMenuButton,
+ SidebarMenuItem,
+ SidebarProvider,
+ SidebarRail,
+ SidebarTrigger,
+} from "@/registry/radix-lyra/ui/sidebar"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function SidebarExample() {
+ const data = {
+ versions: ["1.0.1", "1.1.0-alpha", "2.0.0-beta1"],
+ navMain: [
+ {
+ title: "Getting Started",
+ url: "#",
+ items: [
+ {
+ title: "Installation",
+ url: "#",
+ },
+ {
+ title: "Project Structure",
+ url: "#",
+ },
+ ],
+ },
+ {
+ title: "Build Your Application",
+ url: "#",
+ items: [
+ {
+ title: "Routing",
+ url: "#",
+ },
+ {
+ title: "Data Fetching",
+ url: "#",
+ isActive: true,
+ },
+ {
+ title: "Rendering",
+ url: "#",
+ },
+ {
+ title: "Caching",
+ url: "#",
+ },
+ {
+ title: "Styling",
+ url: "#",
+ },
+ {
+ title: "Optimizing",
+ url: "#",
+ },
+ {
+ title: "Configuring",
+ url: "#",
+ },
+ {
+ title: "Testing",
+ url: "#",
+ },
+ {
+ title: "Authentication",
+ url: "#",
+ },
+ {
+ title: "Deploying",
+ url: "#",
+ },
+ {
+ title: "Upgrading",
+ url: "#",
+ },
+ {
+ title: "Examples",
+ url: "#",
+ },
+ ],
+ },
+ {
+ title: "API Reference",
+ url: "#",
+ items: [
+ {
+ title: "Components",
+ url: "#",
+ },
+ {
+ title: "File Conventions",
+ url: "#",
+ },
+ {
+ title: "Functions",
+ url: "#",
+ },
+ {
+ title: "next.config.js Options",
+ url: "#",
+ },
+ {
+ title: "CLI",
+ url: "#",
+ },
+ {
+ title: "Edge Runtime",
+ url: "#",
+ },
+ ],
+ },
+ {
+ title: "Architecture",
+ url: "#",
+ items: [
+ {
+ title: "Accessibility",
+ url: "#",
+ },
+ {
+ title: "Fast Refresh",
+ url: "#",
+ },
+ {
+ title: "Next.js Compiler",
+ url: "#",
+ },
+ {
+ title: "Supported Browsers",
+ url: "#",
+ },
+ {
+ title: "Turbopack",
+ url: "#",
+ },
+ ],
+ },
+ ],
+ }
+
+ const [selectedVersion, setSelectedVersion] = React.useState(data.versions[0])
+
+ return (
+
+
+
+
+
+
+
+
+ -
+
+ Documentation
+ v{selectedVersion}
+
+
+
+
+
+
+
+
+
+ {data.versions.map((version) => (
+ setSelectedVersion(version)}
+ >
+ v{version}{" "}
+ {version === selectedVersion && (
+
+ )}
+
+ ))}
+
+
+
+
+
+
+
+
+ {data.navMain.map((item) => (
+
+ {item.title}
+
+
+ {item.items.map((subItem) => (
+
+
+ {subItem.title}
+
+
+ ))}
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/sidebar-floating-example.tsx b/apps/v4/registry/radix-lyra/examples/sidebar-floating-example.tsx
new file mode 100644
index 00000000000..fac4f4550ef
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/sidebar-floating-example.tsx
@@ -0,0 +1,275 @@
+"use client"
+
+import * as React from "react"
+
+import { Button } from "@/registry/radix-lyra/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/registry/radix-lyra/ui/card"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/registry/radix-lyra/ui/dropdown-menu"
+import { Field } from "@/registry/radix-lyra/ui/field"
+import {
+ Item,
+ ItemContent,
+ ItemDescription,
+ ItemMedia,
+ ItemTitle,
+} from "@/registry/radix-lyra/ui/item"
+import {
+ Sidebar,
+ SidebarContent,
+ SidebarFooter,
+ SidebarGroup,
+ SidebarHeader,
+ SidebarInput,
+ SidebarInset,
+ SidebarMenu,
+ SidebarMenuButton,
+ SidebarMenuItem,
+ SidebarProvider,
+ SidebarRail,
+ SidebarTrigger,
+} from "@/registry/radix-lyra/ui/sidebar"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+export default function SidebarFloatingExample() {
+ const data = {
+ navMain: [
+ {
+ title: "Getting Started",
+ url: "#",
+ items: [
+ {
+ title: "Installation",
+ url: "#",
+ },
+ {
+ title: "Project Structure",
+ url: "#",
+ },
+ ],
+ },
+ {
+ title: "Build Your Application",
+ url: "#",
+ items: [
+ {
+ title: "Routing",
+ url: "#",
+ },
+ {
+ title: "Data Fetching",
+ url: "#",
+ isActive: true,
+ },
+ {
+ title: "Rendering",
+ url: "#",
+ },
+ {
+ title: "Caching",
+ url: "#",
+ },
+ {
+ title: "Styling",
+ url: "#",
+ },
+ {
+ title: "Optimizing",
+ url: "#",
+ },
+ {
+ title: "Configuring",
+ url: "#",
+ },
+ {
+ title: "Testing",
+ url: "#",
+ },
+ {
+ title: "Authentication",
+ url: "#",
+ },
+ {
+ title: "Deploying",
+ url: "#",
+ },
+ {
+ title: "Upgrading",
+ url: "#",
+ },
+ {
+ title: "Examples",
+ url: "#",
+ },
+ ],
+ },
+ {
+ title: "API Reference",
+ url: "#",
+ items: [
+ {
+ title: "Components",
+ url: "#",
+ },
+ {
+ title: "File Conventions",
+ url: "#",
+ },
+ {
+ title: "Functions",
+ url: "#",
+ },
+ {
+ title: "next.config.js Options",
+ url: "#",
+ },
+ {
+ title: "CLI",
+ url: "#",
+ },
+ {
+ title: "Edge Runtime",
+ url: "#",
+ },
+ ],
+ },
+ {
+ title: "Architecture",
+ url: "#",
+ items: [
+ {
+ title: "Accessibility",
+ url: "#",
+ },
+ {
+ title: "Fast Refresh",
+ url: "#",
+ },
+ {
+ title: "Next.js Compiler",
+ url: "#",
+ },
+ {
+ title: "Supported Browsers",
+ url: "#",
+ },
+ {
+ title: "Turbopack",
+ url: "#",
+ },
+ ],
+ },
+ ],
+ }
+
+ return (
+
+
+
+
+
+
+
+ -
+
+ Documentation
+ v1.0.0
+
+
+
+
+
+
+
+
+
+
+ {data.navMain.map((item) => (
+
+
+
+
+ {item.title}{" "}
+
+
+
+ {item.items?.length ? (
+
+
+ {item.items.map((subItem) => (
+
+ {subItem.title}
+
+ ))}
+
+
+ ) : null}
+
+
+ ))}
+
+
+
+
+
+
+
+
+ Subscribe to our newsletter
+
+
+ Opt-in to receive updates and news about the sidebar.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/examples/slider-example.tsx b/apps/v4/registry/radix-lyra/examples/slider-example.tsx
new file mode 100644
index 00000000000..d2352524083
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/examples/slider-example.tsx
@@ -0,0 +1,103 @@
+"use client"
+
+import * as React from "react"
+
+import {
+ Example,
+ ExampleWrapper,
+} from "@/registry/radix-lyra/components/example"
+import { Label } from "@/registry/radix-lyra/ui/label"
+import { Slider } from "@/registry/radix-lyra/ui/slider"
+
+export default function SliderExample() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+function SliderBasic() {
+ return (
+
+
+
+ )
+}
+
+function SliderRange() {
+ return (
+
+
+
+ )
+}
+
+function SliderMultiple() {
+ return (
+
+
+
+ )
+}
+
+function SliderVertical() {
+ return (
+
+
+
+
+
+
+ )
+}
+
+function SliderControlled() {
+ const [value, setValue] = React.useState([0.3, 0.7])
+
+ return (
+
+
+
+ Temperature
+
+ {value.join(", ")}
+
+
+
+
+
+ )
+}
+
+function SliderDisabled() {
+ return (
+
+
+
+ )
+}
diff --git a/apps/v4/registry/radix-lyra/registry.ts b/apps/v4/registry/radix-lyra/registry.ts
new file mode 100644
index 00000000000..98afe7f990b
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/registry.ts
@@ -0,0 +1,4018 @@
+export const registry = {
+ "name": "shadcn/ui",
+ "homepage": "https://ui.shadcn.com",
+ "items": [
+ {
+ "name": "index",
+ "dependencies": [
+ "class-variance-authority",
+ "lucide-react",
+ "radix-ui"
+ ],
+ "devDependencies": [
+ "tw-animate-css",
+ "shadcn"
+ ],
+ "registryDependencies": [
+ "utils"
+ ],
+ "files": [],
+ "cssVars": {},
+ "css": {
+ "@import \"tw-animate-css\"": {},
+ "@import \"shadcn/tailwind.css\"": {},
+ "@layer base": {
+ "*": {
+ "@apply border-border outline-ring/50": {}
+ },
+ "body": {
+ "@apply bg-background text-foreground": {}
+ }
+ }
+ },
+ "type": "registry:style"
+ },
+ {
+ "name": "style",
+ "dependencies": [
+ "class-variance-authority",
+ "lucide-react",
+ "radix-ui"
+ ],
+ "devDependencies": [
+ "tw-animate-css",
+ "shadcn"
+ ],
+ "registryDependencies": [
+ "utils"
+ ],
+ "files": [],
+ "cssVars": {},
+ "css": {
+ "@import \"tw-animate-css\"": {},
+ "@import \"shadcn/tailwind.css\"": {},
+ "@layer base": {
+ "*": {
+ "@apply border-border outline-ring/50": {}
+ },
+ "body": {
+ "@apply bg-background text-foreground": {}
+ }
+ }
+ },
+ "type": "registry:style"
+ },
+ {
+ "name": "accordion",
+ "files": [
+ {
+ "path": "ui/accordion.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/accordion",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/accordion-example.tsx",
+ "api": "https://www.radix-ui.com/primitives/docs/components/accordion.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "alert",
+ "files": [
+ {
+ "path": "ui/alert.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/alert",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/alert-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "alert-dialog",
+ "registryDependencies": [
+ "button"
+ ],
+ "files": [
+ {
+ "path": "ui/alert-dialog.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/alert-dialog",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/alert-dialog-example.tsx",
+ "api": "https://www.radix-ui.com/primitives/docs/components/alert-dialog.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "aspect-ratio",
+ "files": [
+ {
+ "path": "ui/aspect-ratio.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/aspect-ratio",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/aspect-ratio-example.tsx",
+ "api": "https://www.radix-ui.com/primitives/docs/components/aspect-ratio.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "avatar",
+ "files": [
+ {
+ "path": "ui/avatar.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/avatar",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/avatar-example.tsx",
+ "api": "https://www.radix-ui.com/primitives/docs/components/avatar.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "badge",
+ "files": [
+ {
+ "path": "ui/badge.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/badge",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/badge-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "breadcrumb",
+ "files": [
+ {
+ "path": "ui/breadcrumb.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/breadcrumb",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/breadcrumb-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "button",
+ "files": [
+ {
+ "path": "ui/button.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/button",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/button-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "button-group",
+ "registryDependencies": [
+ "separator"
+ ],
+ "files": [
+ {
+ "path": "ui/button-group.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/button-group",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/button-group-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "calendar",
+ "dependencies": [
+ "react-day-picker@latest",
+ "date-fns"
+ ],
+ "registryDependencies": [
+ "button"
+ ],
+ "files": [
+ {
+ "path": "ui/calendar.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/calendar",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/calendar-example.tsx",
+ "api": "https://react-day-picker.js.org"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "card",
+ "files": [
+ {
+ "path": "ui/card.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/card",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/card-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "carousel",
+ "dependencies": [
+ "embla-carousel-react"
+ ],
+ "registryDependencies": [
+ "button"
+ ],
+ "files": [
+ {
+ "path": "ui/carousel.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/carousel",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/carousel-example.tsx",
+ "api": "https://www.embla-carousel.com/get-started/react"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "chart",
+ "dependencies": [
+ "recharts@3.8.0"
+ ],
+ "files": [
+ {
+ "path": "ui/chart.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/chart",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/chart-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "checkbox",
+ "files": [
+ {
+ "path": "ui/checkbox.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/checkbox",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/checkbox-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/checkbox.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "collapsible",
+ "files": [
+ {
+ "path": "ui/collapsible.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/collapsible",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/collapsible-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/collapsible.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "combobox",
+ "dependencies": [
+ "@base-ui/react"
+ ],
+ "registryDependencies": [
+ "button",
+ "input-group"
+ ],
+ "files": [
+ {
+ "path": "ui/combobox.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/combobox",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/combobox-example.tsx",
+ "api": "https://base-ui.com/react/components/combobox"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "command",
+ "dependencies": [
+ "cmdk"
+ ],
+ "registryDependencies": [
+ "dialog",
+ "input-group"
+ ],
+ "files": [
+ {
+ "path": "ui/command.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/command",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/command-example.tsx",
+ "api": "https://github.com/dip/cmdk"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "context-menu",
+ "files": [
+ {
+ "path": "ui/context-menu.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/context-menu",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/context-menu-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/context-menu.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "dialog",
+ "registryDependencies": [
+ "button"
+ ],
+ "files": [
+ {
+ "path": "ui/dialog.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/dialog",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/dialog-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/dialog.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "drawer",
+ "dependencies": [
+ "vaul"
+ ],
+ "files": [
+ {
+ "path": "ui/drawer.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/drawer",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/drawer-example.tsx",
+ "api": "https://vaul.emilkowal.ski/getting-started"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "dropdown-menu",
+ "files": [
+ {
+ "path": "ui/dropdown-menu.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/dropdown-menu",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/dropdown-menu-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/dropdown-menu.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "empty",
+ "files": [
+ {
+ "path": "ui/empty.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/empty",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/empty-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "field",
+ "registryDependencies": [
+ "label",
+ "separator"
+ ],
+ "files": [
+ {
+ "path": "ui/field.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/field",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/field-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "form",
+ "type": "registry:ui"
+ },
+ {
+ "name": "hover-card",
+ "files": [
+ {
+ "path": "ui/hover-card.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/hover-card",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/hover-card-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/hover-card.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "input",
+ "files": [
+ {
+ "path": "ui/input.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/input",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/input-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "input-group",
+ "registryDependencies": [
+ "button",
+ "input",
+ "textarea"
+ ],
+ "files": [
+ {
+ "path": "ui/input-group.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/input-group",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/input-group-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "input-otp",
+ "dependencies": [
+ "input-otp"
+ ],
+ "files": [
+ {
+ "path": "ui/input-otp.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/input-otp",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/input-otp-example.tsx",
+ "api": "https://input-otp.rodz.dev"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "item",
+ "registryDependencies": [
+ "separator"
+ ],
+ "files": [
+ {
+ "path": "ui/item.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/item",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/item-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "label",
+ "files": [
+ {
+ "path": "ui/label.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/label",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/label-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/label.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "menubar",
+ "files": [
+ {
+ "path": "ui/menubar.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/menubar",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/menubar-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/menubar.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "navigation-menu",
+ "files": [
+ {
+ "path": "ui/navigation-menu.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/navigation-menu",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/navigation-menu-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/navigation-menu.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "pagination",
+ "registryDependencies": [
+ "button"
+ ],
+ "files": [
+ {
+ "path": "ui/pagination.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/pagination",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/pagination-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "popover",
+ "files": [
+ {
+ "path": "ui/popover.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/popover",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/popover-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/popover.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "progress",
+ "files": [
+ {
+ "path": "ui/progress.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/progress",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/progress-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/progress.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "radio-group",
+ "files": [
+ {
+ "path": "ui/radio-group.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/radio-group",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/radio-group-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/radio-group.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "resizable",
+ "dependencies": [
+ "react-resizable-panels"
+ ],
+ "files": [
+ {
+ "path": "ui/resizable.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/resizable",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/resizable-example.tsx",
+ "api": "https://github.com/bvaughn/react-resizable-panels"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "scroll-area",
+ "files": [
+ {
+ "path": "ui/scroll-area.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/scroll-area",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/scroll-area-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/scroll-area.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "select",
+ "files": [
+ {
+ "path": "ui/select.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/select",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/select-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/select.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "separator",
+ "files": [
+ {
+ "path": "ui/separator.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/separator",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/separator-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/separator.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "sheet",
+ "registryDependencies": [
+ "button"
+ ],
+ "files": [
+ {
+ "path": "ui/sheet.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/sheet",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/sheet-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/dialog.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "sidebar",
+ "registryDependencies": [
+ "button",
+ "separator",
+ "sheet",
+ "tooltip",
+ "input",
+ "use-mobile",
+ "skeleton"
+ ],
+ "files": [
+ {
+ "path": "ui/sidebar.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/sidebar",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/sidebar-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "skeleton",
+ "files": [
+ {
+ "path": "ui/skeleton.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/skeleton",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/skeleton-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "slider",
+ "files": [
+ {
+ "path": "ui/slider.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/slider",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/slider-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/slider.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "sonner",
+ "dependencies": [
+ "sonner",
+ "next-themes"
+ ],
+ "files": [
+ {
+ "path": "ui/sonner.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/sonner",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/sonner-example.tsx",
+ "api": "https://sonner.emilkowal.ski"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "spinner",
+ "files": [
+ {
+ "path": "ui/spinner.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/spinner",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/spinner-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "switch",
+ "files": [
+ {
+ "path": "ui/switch.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/switch",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/switch-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/switch.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "table",
+ "files": [
+ {
+ "path": "ui/table.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/table",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/table-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "tabs",
+ "files": [
+ {
+ "path": "ui/tabs.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/tabs",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/tabs-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/tabs.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "textarea",
+ "files": [
+ {
+ "path": "ui/textarea.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/textarea",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/textarea-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "toggle",
+ "files": [
+ {
+ "path": "ui/toggle.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/toggle",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/toggle-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/toggle.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "toggle-group",
+ "registryDependencies": [
+ "toggle"
+ ],
+ "files": [
+ {
+ "path": "ui/toggle-group.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/toggle-group",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/toggle-group-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/toggle-group.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "tooltip",
+ "files": [
+ {
+ "path": "ui/tooltip.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/tooltip",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/tooltip-example.tsx",
+ "api": "https://www.radix-ui.com/docs/primitives/components/tooltip.md"
+ }
+ },
+ "docs": "The `tooltip` component has been added. Remember to wrap your app with the `TooltipProvider` component.\n\n```tsx title=\"app/layout.tsx\"\nimport { TooltipProvider } from \"@/components/ui/tooltip\"\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n return (\n \n \n {children} \n \n \n )\n}\n```\n",
+ "type": "registry:ui"
+ },
+ {
+ "name": "kbd",
+ "files": [
+ {
+ "path": "ui/kbd.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/kbd",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/kbd-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "native-select",
+ "files": [
+ {
+ "path": "ui/native-select.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/native-select",
+ "examples": "https://ui.shadcn.com/code/apps/v4/registry/bases/radix/examples/native-select-example.tsx"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "direction",
+ "files": [
+ {
+ "path": "ui/direction.tsx",
+ "type": "registry:ui"
+ }
+ ],
+ "meta": {
+ "links": {
+ "docs": "https://ui.shadcn.com/docs/components/radix/direction",
+ "api": "https://www.radix-ui.com/primitives/docs/utilities/direction-provider.md"
+ }
+ },
+ "type": "registry:ui"
+ },
+ {
+ "name": "accordion-example",
+ "title": "Accordion",
+ "registryDependencies": [
+ "accordion",
+ "button",
+ "card",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/accordion-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "alert-example",
+ "title": "Alert",
+ "registryDependencies": [
+ "alert",
+ "badge",
+ "button",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/alert-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "alert-dialog-example",
+ "title": "Alert Dialog",
+ "registryDependencies": [
+ "alert-dialog",
+ "button",
+ "dialog",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/alert-dialog-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "aspect-ratio-example",
+ "title": "Aspect Ratio",
+ "registryDependencies": [
+ "aspect-ratio",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/aspect-ratio-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "avatar-example",
+ "title": "Avatar",
+ "registryDependencies": [
+ "avatar",
+ "button",
+ "empty",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/avatar-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "badge-example",
+ "title": "Badge",
+ "registryDependencies": [
+ "badge",
+ "spinner",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/badge-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "breadcrumb-example",
+ "title": "Breadcrumb",
+ "registryDependencies": [
+ "breadcrumb",
+ "dropdown-menu",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/breadcrumb-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "button-example",
+ "title": "Button",
+ "registryDependencies": [
+ "button",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/button-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "button-group-example",
+ "title": "Button Group",
+ "registryDependencies": [
+ "button",
+ "button-group",
+ "dropdown-menu",
+ "field",
+ "input",
+ "input-group",
+ "label",
+ "popover",
+ "select",
+ "tooltip",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/button-group-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "calendar-example",
+ "title": "Calendar",
+ "registryDependencies": [
+ "button",
+ "calendar",
+ "card",
+ "field",
+ "input",
+ "label",
+ "popover",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/calendar-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "card-example",
+ "title": "Card",
+ "registryDependencies": [
+ "avatar",
+ "button",
+ "card",
+ "field",
+ "input",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/card-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "carousel-example",
+ "title": "Carousel",
+ "registryDependencies": [
+ "card",
+ "carousel",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/carousel-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "chart-example",
+ "title": "Chart",
+ "registryDependencies": [
+ "chart",
+ "card",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/chart-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "checkbox-example",
+ "title": "Checkbox",
+ "registryDependencies": [
+ "checkbox",
+ "field",
+ "table",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/checkbox-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "collapsible-example",
+ "title": "Collapsible",
+ "registryDependencies": [
+ "button",
+ "card",
+ "collapsible",
+ "field",
+ "input",
+ "tabs",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/collapsible-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "combobox-example",
+ "title": "Combobox",
+ "registryDependencies": [
+ "button",
+ "card",
+ "combobox",
+ "dialog",
+ "field",
+ "input",
+ "input-group",
+ "item",
+ "select",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/combobox-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "command-example",
+ "title": "Command",
+ "registryDependencies": [
+ "button",
+ "command",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/command-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "context-menu-example",
+ "title": "Context Menu",
+ "registryDependencies": [
+ "button",
+ "context-menu",
+ "dialog",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/context-menu-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "dialog-example",
+ "title": "Dialog",
+ "registryDependencies": [
+ "button",
+ "checkbox",
+ "dialog",
+ "field",
+ "input",
+ "input-group",
+ "kbd",
+ "native-select",
+ "select",
+ "switch",
+ "tabs",
+ "textarea",
+ "tooltip",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/dialog-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "drawer-example",
+ "title": "Drawer",
+ "registryDependencies": [
+ "drawer",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/drawer-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "dropdown-menu-example",
+ "title": "Dropdown Menu",
+ "registryDependencies": [
+ "avatar",
+ "button",
+ "dialog",
+ "dropdown-menu",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/dropdown-menu-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "empty-example",
+ "title": "Empty",
+ "registryDependencies": [
+ "button",
+ "empty",
+ "input-group",
+ "kbd",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/empty-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "field-example",
+ "title": "Field",
+ "registryDependencies": [
+ "badge",
+ "checkbox",
+ "field",
+ "input",
+ "input-otp",
+ "native-select",
+ "radio-group",
+ "select",
+ "slider",
+ "switch",
+ "textarea",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/field-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "hover-card-example",
+ "title": "Hover Card",
+ "registryDependencies": [
+ "button",
+ "dialog",
+ "hover-card",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/hover-card-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "input-example",
+ "title": "Input",
+ "registryDependencies": [
+ "button",
+ "field",
+ "input",
+ "native-select",
+ "select",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/input-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "input-group-example",
+ "title": "Input Group",
+ "registryDependencies": [
+ "button",
+ "button-group",
+ "card",
+ "dropdown-menu",
+ "field",
+ "input",
+ "input-group",
+ "kbd",
+ "popover",
+ "spinner",
+ "textarea",
+ "tooltip",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/input-group-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "input-otp-example",
+ "title": "Input OTP",
+ "registryDependencies": [
+ "button",
+ "card",
+ "field",
+ "input-otp",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/input-otp-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "item-example",
+ "title": "Item",
+ "registryDependencies": [
+ "button",
+ "item",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/item-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "kbd-example",
+ "title": "Kbd",
+ "registryDependencies": [
+ "button",
+ "input-group",
+ "kbd",
+ "tooltip",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/kbd-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "label-example",
+ "title": "Label",
+ "registryDependencies": [
+ "checkbox",
+ "field",
+ "input",
+ "label",
+ "textarea",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/label-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "menubar-example",
+ "title": "Menubar",
+ "registryDependencies": [
+ "button",
+ "dialog",
+ "menubar",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/menubar-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "native-select-example",
+ "title": "Native Select",
+ "registryDependencies": [
+ "field",
+ "native-select",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/native-select-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "navigation-menu-example",
+ "title": "Navigation Menu",
+ "registryDependencies": [
+ "button",
+ "dialog",
+ "navigation-menu",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/navigation-menu-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "pagination-example",
+ "title": "Pagination",
+ "registryDependencies": [
+ "field",
+ "pagination",
+ "select",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/pagination-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "popover-example",
+ "title": "Popover",
+ "registryDependencies": [
+ "button",
+ "dialog",
+ "field",
+ "input",
+ "popover",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/popover-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "progress-example",
+ "title": "Progress",
+ "registryDependencies": [
+ "field",
+ "item",
+ "progress",
+ "slider",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/progress-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "radio-group-example",
+ "title": "Radio Group",
+ "registryDependencies": [
+ "field",
+ "radio-group",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/radio-group-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "resizable-example",
+ "title": "Resizable",
+ "registryDependencies": [
+ "resizable",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/resizable-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "scroll-area-example",
+ "title": "Scroll Area",
+ "registryDependencies": [
+ "scroll-area",
+ "separator",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/scroll-area-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "select-example",
+ "title": "Select",
+ "registryDependencies": [
+ "button",
+ "dialog",
+ "field",
+ "input",
+ "item",
+ "native-select",
+ "select",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/select-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "separator-example",
+ "title": "Separator",
+ "registryDependencies": [
+ "separator",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/separator-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "sheet-example",
+ "title": "Sheet",
+ "registryDependencies": [
+ "button",
+ "field",
+ "input",
+ "sheet",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/sheet-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "sidebar-example",
+ "title": "Sidebar",
+ "registryDependencies": [
+ "button",
+ "dropdown-menu",
+ "item",
+ "label",
+ "sidebar",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/sidebar-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "sidebar-icon-example",
+ "title": "Sidebar (Icon)",
+ "registryDependencies": [
+ "avatar",
+ "button",
+ "collapsible",
+ "dropdown-menu",
+ "item",
+ "sidebar",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/sidebar-icon-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "sidebar-inset-example",
+ "title": "Sidebar (Inset)",
+ "registryDependencies": [
+ "collapsible",
+ "sidebar",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/sidebar-inset-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "sidebar-floating-example",
+ "title": "Sidebar (Floating)",
+ "registryDependencies": [
+ "button",
+ "card",
+ "dropdown-menu",
+ "field",
+ "item",
+ "sidebar",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/sidebar-floating-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "skeleton-example",
+ "title": "Skeleton",
+ "registryDependencies": [
+ "skeleton",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/skeleton-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "slider-example",
+ "title": "Slider",
+ "registryDependencies": [
+ "label",
+ "slider",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/slider-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "sonner-example",
+ "title": "Sonner",
+ "registryDependencies": [
+ "sonner",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/sonner-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "spinner-example",
+ "title": "Spinner",
+ "registryDependencies": [
+ "badge",
+ "button",
+ "empty",
+ "field",
+ "input-group",
+ "spinner",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/spinner-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "switch-example",
+ "title": "Switch",
+ "registryDependencies": [
+ "field",
+ "label",
+ "switch",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/switch-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "table-example",
+ "title": "Table",
+ "registryDependencies": [
+ "button",
+ "dropdown-menu",
+ "input",
+ "select",
+ "table",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/table-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "tabs-example",
+ "title": "Tabs",
+ "registryDependencies": [
+ "button",
+ "dropdown-menu",
+ "tabs",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/tabs-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "textarea-example",
+ "title": "Textarea",
+ "registryDependencies": [
+ "field",
+ "textarea",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/textarea-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "toggle-example",
+ "title": "Toggle",
+ "registryDependencies": [
+ "toggle",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/toggle-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "toggle-group-example",
+ "title": "Toggle Group",
+ "registryDependencies": [
+ "input",
+ "select",
+ "toggle-group",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/toggle-group-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "tooltip-example",
+ "title": "Tooltip",
+ "registryDependencies": [
+ "button",
+ "kbd",
+ "tooltip",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/tooltip-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "demo",
+ "title": "Demo",
+ "registryDependencies": [
+ "alert-dialog",
+ "badge",
+ "button",
+ "button-group",
+ "card",
+ "checkbox",
+ "dropdown-menu",
+ "field",
+ "input-group",
+ "item",
+ "radio-group",
+ "slider",
+ "switch",
+ "textarea"
+ ],
+ "files": [
+ {
+ "path": "examples/demo.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "component-example",
+ "title": "Example",
+ "registryDependencies": [
+ "alert-dialog",
+ "badge",
+ "button",
+ "card",
+ "combobox",
+ "dropdown-menu",
+ "field",
+ "input",
+ "select",
+ "textarea",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "examples/component-example.tsx",
+ "type": "registry:example"
+ }
+ ],
+ "type": "registry:example"
+ },
+ {
+ "name": "utils",
+ "dependencies": [
+ "clsx",
+ "tailwind-merge"
+ ],
+ "files": [
+ {
+ "path": "lib/utils.ts",
+ "type": "registry:lib"
+ }
+ ],
+ "type": "registry:lib"
+ },
+ {
+ "name": "example",
+ "title": "Example",
+ "files": [
+ {
+ "path": "components/example.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "type": "registry:component"
+ },
+ {
+ "name": "preview",
+ "title": "Preview",
+ "registryDependencies": [
+ "alert-dialog",
+ "avatar",
+ "badge",
+ "button",
+ "button-group",
+ "card",
+ "checkbox",
+ "combobox",
+ "dropdown-menu",
+ "empty",
+ "field",
+ "input",
+ "input-group",
+ "item",
+ "label",
+ "popover",
+ "radio-group",
+ "select",
+ "separator",
+ "sheet",
+ "slider",
+ "spinner",
+ "switch",
+ "textarea",
+ "tooltip",
+ "example"
+ ],
+ "files": [
+ {
+ "path": "blocks/preview/index.tsx",
+ "type": "registry:block"
+ }
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "preview-02",
+ "title": "Preview 02",
+ "dependencies": [
+ "react-qr-code"
+ ],
+ "registryDependencies": [
+ "accordion",
+ "badge",
+ "breadcrumb",
+ "button",
+ "calendar",
+ "card",
+ "chart",
+ "checkbox",
+ "combobox",
+ "dropdown-menu",
+ "empty",
+ "field",
+ "input",
+ "input-group",
+ "item",
+ "label",
+ "native-select",
+ "progress",
+ "radio-group",
+ "select",
+ "separator",
+ "sidebar",
+ "skeleton",
+ "slider",
+ "spinner",
+ "switch",
+ "table",
+ "tabs",
+ "textarea",
+ "toggle-group"
+ ],
+ "files": [
+ {
+ "path": "blocks/preview-02/index.tsx",
+ "type": "registry:block"
+ }
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "login-01",
+ "title": "Login 01",
+ "description": "A simple login form.",
+ "registryDependencies": [
+ "button",
+ "card",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/login-01/page.tsx",
+ "type": "registry:page",
+ "target": "app/login/page.tsx"
+ },
+ {
+ "path": "blocks/login-01/components/login-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "login"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "login-02",
+ "title": "Login 02",
+ "description": "A two column login page with a cover image.",
+ "registryDependencies": [
+ "button",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/login-02/page.tsx",
+ "type": "registry:page",
+ "target": "app/login/page.tsx"
+ },
+ {
+ "path": "blocks/login-02/components/login-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "login"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "login-03",
+ "title": "Login 03",
+ "description": "A login page with a muted background color.",
+ "registryDependencies": [
+ "button",
+ "card",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/login-03/page.tsx",
+ "type": "registry:page",
+ "target": "app/login/page.tsx"
+ },
+ {
+ "path": "blocks/login-03/components/login-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "login"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "login-04",
+ "title": "Login 04",
+ "description": "A login page with form and image.",
+ "registryDependencies": [
+ "button",
+ "card",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/login-04/page.tsx",
+ "type": "registry:page",
+ "target": "app/login/page.tsx"
+ },
+ {
+ "path": "blocks/login-04/components/login-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "login"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "login-05",
+ "title": "Login 05",
+ "description": "A simple email-only login page.",
+ "registryDependencies": [
+ "button",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/login-05/page.tsx",
+ "type": "registry:page",
+ "target": "app/login/page.tsx"
+ },
+ {
+ "path": "blocks/login-05/components/login-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "login"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "signup-01",
+ "title": "Signup 01",
+ "description": "A simple signup form.",
+ "registryDependencies": [
+ "button",
+ "card",
+ "input",
+ "label"
+ ],
+ "files": [
+ {
+ "path": "blocks/signup-01/page.tsx",
+ "type": "registry:page",
+ "target": "app/signup/page.tsx"
+ },
+ {
+ "path": "blocks/signup-01/components/signup-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "signup"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "signup-02",
+ "title": "Signup 02",
+ "description": "A two column signup page with a cover image.",
+ "registryDependencies": [
+ "button",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/signup-02/page.tsx",
+ "type": "registry:page",
+ "target": "app/signup/page.tsx"
+ },
+ {
+ "path": "blocks/signup-02/components/signup-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "signup"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "signup-03",
+ "title": "Signup 03",
+ "description": "A signup page with a muted background color.",
+ "registryDependencies": [
+ "button",
+ "card",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/signup-03/page.tsx",
+ "type": "registry:page",
+ "target": "app/signup/page.tsx"
+ },
+ {
+ "path": "blocks/signup-03/components/signup-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "signup"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "signup-04",
+ "title": "Signup 04",
+ "description": "A signup page with form and image.",
+ "registryDependencies": [
+ "button",
+ "card",
+ "input",
+ "label",
+ "field"
+ ],
+ "files": [
+ {
+ "path": "blocks/signup-04/page.tsx",
+ "type": "registry:page",
+ "target": "app/signup/page.tsx"
+ },
+ {
+ "path": "blocks/signup-04/components/signup-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "signup"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "signup-05",
+ "title": "Signup 05",
+ "description": "A simple signup form with social providers.",
+ "registryDependencies": [
+ "button",
+ "input",
+ "label"
+ ],
+ "files": [
+ {
+ "path": "blocks/signup-05/page.tsx",
+ "type": "registry:page",
+ "target": "app/signup/page.tsx"
+ },
+ {
+ "path": "blocks/signup-05/components/signup-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "authentication",
+ "signup"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "dashboard-01",
+ "title": "Dashboard 01",
+ "description": "A dashboard with sidebar, charts and data table.",
+ "dependencies": [
+ "@dnd-kit/core",
+ "@dnd-kit/modifiers",
+ "@dnd-kit/sortable",
+ "@dnd-kit/utilities",
+ "@tanstack/react-table",
+ "zod"
+ ],
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "label",
+ "chart",
+ "card",
+ "select",
+ "tabs",
+ "table",
+ "toggle-group",
+ "badge",
+ "button",
+ "checkbox",
+ "dropdown-menu",
+ "drawer",
+ "input",
+ "avatar",
+ "sheet",
+ "sonner"
+ ],
+ "files": [
+ {
+ "path": "blocks/dashboard-01/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/dashboard-01/data.json",
+ "type": "registry:file",
+ "target": "app/dashboard/data.json"
+ },
+ {
+ "path": "blocks/dashboard-01/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/chart-area-interactive.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/data-table.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/nav-documents.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/nav-main.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/nav-secondary.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/nav-user.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/section-cards.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/dashboard-01/components/site-header.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "meta": {
+ "iframeHeight": "1000px"
+ },
+ "categories": [
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-01",
+ "title": "Sidebar 01",
+ "description": "A simple sidebar with navigation grouped by section.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "label",
+ "dropdown-menu"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-01/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-01/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-01/components/search-form.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-01/components/version-switcher.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-02",
+ "title": "Sidebar 02",
+ "description": "A sidebar with collapsible sections.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "label",
+ "dropdown-menu"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-02/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-02/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-02/components/search-form.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-02/components/version-switcher.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-03",
+ "title": "Sidebar 03",
+ "description": "A sidebar with submenus.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-03/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-03/components/app-sidebar.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-04",
+ "title": "Sidebar 04",
+ "description": "A floating sidebar with submenus.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-04/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-04/components/app-sidebar.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-05",
+ "title": "Sidebar 05",
+ "description": "A sidebar with collapsible submenus.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "label",
+ "collapsible"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-05/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-05/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-05/components/search-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-06",
+ "title": "Sidebar 06",
+ "description": "A sidebar with submenus as dropdowns.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "card",
+ "dropdown-menu"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-06/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-06/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-06/components/nav-main.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-06/components/sidebar-opt-in-form.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-07",
+ "title": "Sidebar 07",
+ "description": "A sidebar that collapses to icons.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "collapsible",
+ "dropdown-menu",
+ "avatar"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-07/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-07/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-07/components/nav-main.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-07/components/nav-projects.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-07/components/nav-user.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-07/components/team-switcher.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-08",
+ "title": "Sidebar 08",
+ "description": "An inset sidebar with secondary navigation.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "collapsible",
+ "dropdown-menu",
+ "avatar"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-08/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-08/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-08/components/nav-main.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-08/components/nav-projects.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-08/components/nav-secondary.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-08/components/nav-user.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-09",
+ "title": "Sidebar 09",
+ "description": "Collapsible nested sidebars.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "collapsible",
+ "dropdown-menu",
+ "avatar",
+ "switch",
+ "label"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-09/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-09/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-09/components/nav-user.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-10",
+ "title": "Sidebar 10",
+ "description": "A sidebar in a popover.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "popover",
+ "collapsible",
+ "dropdown-menu"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-10/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-10/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-10/components/nav-actions.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-10/components/nav-favorites.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-10/components/nav-main.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-10/components/nav-secondary.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-10/components/nav-workspaces.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-10/components/team-switcher.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-11",
+ "title": "Sidebar 11",
+ "description": "A sidebar with a collapsible file tree.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "collapsible"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-11/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-11/components/app-sidebar.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-12",
+ "title": "Sidebar 12",
+ "description": "A sidebar with a calendar.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "collapsible",
+ "calendar",
+ "dropdown-menu",
+ "avatar"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-12/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-12/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-12/components/calendars.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-12/components/date-picker.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-12/components/nav-user.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-13",
+ "title": "Sidebar 13",
+ "description": "A sidebar in a dialog.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "button",
+ "dialog"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-13/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-13/components/settings-dialog.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-14",
+ "title": "Sidebar 14",
+ "description": "A sidebar on the right.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-14/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-14/components/app-sidebar.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-15",
+ "title": "Sidebar 15",
+ "description": "A left and right sidebar.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "popover",
+ "collapsible",
+ "dropdown-menu",
+ "calendar",
+ "avatar"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-15/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-15/components/calendars.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/date-picker.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/nav-favorites.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/nav-main.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/nav-secondary.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/nav-user.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/nav-workspaces.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/sidebar-left.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/sidebar-right.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-15/components/team-switcher.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "sidebar-16",
+ "title": "Sidebar 16",
+ "description": "A sidebar with a sticky site header.",
+ "registryDependencies": [
+ "sidebar",
+ "breadcrumb",
+ "separator",
+ "collapsible",
+ "dropdown-menu",
+ "avatar",
+ "button",
+ "label"
+ ],
+ "files": [
+ {
+ "path": "blocks/sidebar-16/page.tsx",
+ "type": "registry:page",
+ "target": "app/dashboard/page.tsx"
+ },
+ {
+ "path": "blocks/sidebar-16/components/app-sidebar.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-16/components/nav-main.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-16/components/nav-projects.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-16/components/nav-secondary.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-16/components/nav-user.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-16/components/search-form.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "blocks/sidebar-16/components/site-header.tsx",
+ "type": "registry:component"
+ }
+ ],
+ "categories": [
+ "sidebar",
+ "dashboard"
+ ],
+ "type": "registry:block"
+ },
+ {
+ "name": "use-mobile",
+ "files": [
+ {
+ "path": "hooks/use-mobile.ts",
+ "type": "registry:hook"
+ }
+ ],
+ "type": "registry:hook"
+ },
+ {
+ "name": "font-geist",
+ "title": "Geist",
+ "type": "registry:font",
+ "font": {
+ "family": "'Geist Variable', sans-serif",
+ "provider": "google",
+ "import": "Geist",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/geist"
+ }
+ },
+ {
+ "name": "font-inter",
+ "title": "Inter",
+ "type": "registry:font",
+ "font": {
+ "family": "'Inter Variable', sans-serif",
+ "provider": "google",
+ "import": "Inter",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/inter"
+ }
+ },
+ {
+ "name": "font-noto-sans",
+ "title": "Noto Sans",
+ "type": "registry:font",
+ "font": {
+ "family": "'Noto Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Noto_Sans",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/noto-sans"
+ }
+ },
+ {
+ "name": "font-nunito-sans",
+ "title": "Nunito Sans",
+ "type": "registry:font",
+ "font": {
+ "family": "'Nunito Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Nunito_Sans",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/nunito-sans"
+ }
+ },
+ {
+ "name": "font-figtree",
+ "title": "Figtree",
+ "type": "registry:font",
+ "font": {
+ "family": "'Figtree Variable', sans-serif",
+ "provider": "google",
+ "import": "Figtree",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/figtree"
+ }
+ },
+ {
+ "name": "font-roboto",
+ "title": "Roboto",
+ "type": "registry:font",
+ "font": {
+ "family": "'Roboto Variable', sans-serif",
+ "provider": "google",
+ "import": "Roboto",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/roboto"
+ }
+ },
+ {
+ "name": "font-raleway",
+ "title": "Raleway",
+ "type": "registry:font",
+ "font": {
+ "family": "'Raleway Variable', sans-serif",
+ "provider": "google",
+ "import": "Raleway",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/raleway"
+ }
+ },
+ {
+ "name": "font-dm-sans",
+ "title": "DM Sans",
+ "type": "registry:font",
+ "font": {
+ "family": "'DM Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "DM_Sans",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/dm-sans"
+ }
+ },
+ {
+ "name": "font-public-sans",
+ "title": "Public Sans",
+ "type": "registry:font",
+ "font": {
+ "family": "'Public Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Public_Sans",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/public-sans"
+ }
+ },
+ {
+ "name": "font-outfit",
+ "title": "Outfit",
+ "type": "registry:font",
+ "font": {
+ "family": "'Outfit Variable', sans-serif",
+ "provider": "google",
+ "import": "Outfit",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/outfit"
+ }
+ },
+ {
+ "name": "font-oxanium",
+ "title": "Oxanium",
+ "type": "registry:font",
+ "font": {
+ "family": "'Oxanium Variable', sans-serif",
+ "provider": "google",
+ "import": "Oxanium",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/oxanium"
+ }
+ },
+ {
+ "name": "font-manrope",
+ "title": "Manrope",
+ "type": "registry:font",
+ "font": {
+ "family": "'Manrope Variable', sans-serif",
+ "provider": "google",
+ "import": "Manrope",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/manrope"
+ }
+ },
+ {
+ "name": "font-space-grotesk",
+ "title": "Space Grotesk",
+ "type": "registry:font",
+ "font": {
+ "family": "'Space Grotesk Variable', sans-serif",
+ "provider": "google",
+ "import": "Space_Grotesk",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/space-grotesk"
+ }
+ },
+ {
+ "name": "font-montserrat",
+ "title": "Montserrat",
+ "type": "registry:font",
+ "font": {
+ "family": "'Montserrat Variable', sans-serif",
+ "provider": "google",
+ "import": "Montserrat",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/montserrat"
+ }
+ },
+ {
+ "name": "font-ibm-plex-sans",
+ "title": "IBM Plex Sans",
+ "type": "registry:font",
+ "font": {
+ "family": "'IBM Plex Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "IBM_Plex_Sans",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/ibm-plex-sans"
+ }
+ },
+ {
+ "name": "font-source-sans-3",
+ "title": "Source Sans 3",
+ "type": "registry:font",
+ "font": {
+ "family": "'Source Sans 3 Variable', sans-serif",
+ "provider": "google",
+ "import": "Source_Sans_3",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/source-sans-3"
+ }
+ },
+ {
+ "name": "font-instrument-sans",
+ "title": "Instrument Sans",
+ "type": "registry:font",
+ "font": {
+ "family": "'Instrument Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Instrument_Sans",
+ "variable": "--font-sans",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/instrument-sans"
+ }
+ },
+ {
+ "name": "font-jetbrains-mono",
+ "title": "JetBrains Mono",
+ "type": "registry:font",
+ "font": {
+ "family": "'JetBrains Mono Variable', monospace",
+ "provider": "google",
+ "import": "JetBrains_Mono",
+ "variable": "--font-mono",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/jetbrains-mono"
+ }
+ },
+ {
+ "name": "font-geist-mono",
+ "title": "Geist Mono",
+ "type": "registry:font",
+ "font": {
+ "family": "'Geist Mono Variable', monospace",
+ "provider": "google",
+ "import": "Geist_Mono",
+ "variable": "--font-mono",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/geist-mono"
+ }
+ },
+ {
+ "name": "font-noto-serif",
+ "title": "Noto Serif",
+ "type": "registry:font",
+ "font": {
+ "family": "'Noto Serif Variable', serif",
+ "provider": "google",
+ "import": "Noto_Serif",
+ "variable": "--font-serif",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/noto-serif"
+ }
+ },
+ {
+ "name": "font-roboto-slab",
+ "title": "Roboto Slab",
+ "type": "registry:font",
+ "font": {
+ "family": "'Roboto Slab Variable', serif",
+ "provider": "google",
+ "import": "Roboto_Slab",
+ "variable": "--font-serif",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/roboto-slab"
+ }
+ },
+ {
+ "name": "font-merriweather",
+ "title": "Merriweather",
+ "type": "registry:font",
+ "font": {
+ "family": "'Merriweather Variable', serif",
+ "provider": "google",
+ "import": "Merriweather",
+ "variable": "--font-serif",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/merriweather"
+ }
+ },
+ {
+ "name": "font-lora",
+ "title": "Lora",
+ "type": "registry:font",
+ "font": {
+ "family": "'Lora Variable', serif",
+ "provider": "google",
+ "import": "Lora",
+ "variable": "--font-serif",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/lora"
+ }
+ },
+ {
+ "name": "font-playfair-display",
+ "title": "Playfair Display",
+ "type": "registry:font",
+ "font": {
+ "family": "'Playfair Display Variable', serif",
+ "provider": "google",
+ "import": "Playfair_Display",
+ "variable": "--font-serif",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/playfair-display"
+ }
+ },
+ {
+ "name": "font-eb-garamond",
+ "title": "EB Garamond",
+ "type": "registry:font",
+ "font": {
+ "family": "'EB Garamond Variable', serif",
+ "provider": "google",
+ "import": "EB_Garamond",
+ "variable": "--font-serif",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/eb-garamond"
+ }
+ },
+ {
+ "name": "font-instrument-serif",
+ "title": "Instrument Serif",
+ "type": "registry:font",
+ "font": {
+ "family": "'Instrument Serif', serif",
+ "provider": "google",
+ "import": "Instrument_Serif",
+ "variable": "--font-serif",
+ "weight": [
+ "400"
+ ],
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource/instrument-serif"
+ }
+ },
+ {
+ "name": "font-heading-geist",
+ "title": "Geist (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Geist Variable', sans-serif",
+ "provider": "google",
+ "import": "Geist",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/geist"
+ }
+ },
+ {
+ "name": "font-heading-inter",
+ "title": "Inter (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Inter Variable', sans-serif",
+ "provider": "google",
+ "import": "Inter",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/inter"
+ }
+ },
+ {
+ "name": "font-heading-noto-sans",
+ "title": "Noto Sans (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Noto Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Noto_Sans",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/noto-sans"
+ }
+ },
+ {
+ "name": "font-heading-nunito-sans",
+ "title": "Nunito Sans (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Nunito Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Nunito_Sans",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/nunito-sans"
+ }
+ },
+ {
+ "name": "font-heading-figtree",
+ "title": "Figtree (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Figtree Variable', sans-serif",
+ "provider": "google",
+ "import": "Figtree",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/figtree"
+ }
+ },
+ {
+ "name": "font-heading-roboto",
+ "title": "Roboto (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Roboto Variable', sans-serif",
+ "provider": "google",
+ "import": "Roboto",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/roboto"
+ }
+ },
+ {
+ "name": "font-heading-raleway",
+ "title": "Raleway (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Raleway Variable', sans-serif",
+ "provider": "google",
+ "import": "Raleway",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/raleway"
+ }
+ },
+ {
+ "name": "font-heading-dm-sans",
+ "title": "DM Sans (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'DM Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "DM_Sans",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/dm-sans"
+ }
+ },
+ {
+ "name": "font-heading-public-sans",
+ "title": "Public Sans (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Public Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Public_Sans",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/public-sans"
+ }
+ },
+ {
+ "name": "font-heading-outfit",
+ "title": "Outfit (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Outfit Variable', sans-serif",
+ "provider": "google",
+ "import": "Outfit",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/outfit"
+ }
+ },
+ {
+ "name": "font-heading-oxanium",
+ "title": "Oxanium (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Oxanium Variable', sans-serif",
+ "provider": "google",
+ "import": "Oxanium",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/oxanium"
+ }
+ },
+ {
+ "name": "font-heading-manrope",
+ "title": "Manrope (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Manrope Variable', sans-serif",
+ "provider": "google",
+ "import": "Manrope",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/manrope"
+ }
+ },
+ {
+ "name": "font-heading-space-grotesk",
+ "title": "Space Grotesk (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Space Grotesk Variable', sans-serif",
+ "provider": "google",
+ "import": "Space_Grotesk",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/space-grotesk"
+ }
+ },
+ {
+ "name": "font-heading-montserrat",
+ "title": "Montserrat (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Montserrat Variable', sans-serif",
+ "provider": "google",
+ "import": "Montserrat",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/montserrat"
+ }
+ },
+ {
+ "name": "font-heading-ibm-plex-sans",
+ "title": "IBM Plex Sans (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'IBM Plex Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "IBM_Plex_Sans",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/ibm-plex-sans"
+ }
+ },
+ {
+ "name": "font-heading-source-sans-3",
+ "title": "Source Sans 3 (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Source Sans 3 Variable', sans-serif",
+ "provider": "google",
+ "import": "Source_Sans_3",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/source-sans-3"
+ }
+ },
+ {
+ "name": "font-heading-instrument-sans",
+ "title": "Instrument Sans (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Instrument Sans Variable', sans-serif",
+ "provider": "google",
+ "import": "Instrument_Sans",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/instrument-sans"
+ }
+ },
+ {
+ "name": "font-heading-jetbrains-mono",
+ "title": "JetBrains Mono (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'JetBrains Mono Variable', monospace",
+ "provider": "google",
+ "import": "JetBrains_Mono",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/jetbrains-mono"
+ }
+ },
+ {
+ "name": "font-heading-geist-mono",
+ "title": "Geist Mono (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Geist Mono Variable', monospace",
+ "provider": "google",
+ "import": "Geist_Mono",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/geist-mono"
+ }
+ },
+ {
+ "name": "font-heading-noto-serif",
+ "title": "Noto Serif (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Noto Serif Variable', serif",
+ "provider": "google",
+ "import": "Noto_Serif",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/noto-serif"
+ }
+ },
+ {
+ "name": "font-heading-roboto-slab",
+ "title": "Roboto Slab (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Roboto Slab Variable', serif",
+ "provider": "google",
+ "import": "Roboto_Slab",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/roboto-slab"
+ }
+ },
+ {
+ "name": "font-heading-merriweather",
+ "title": "Merriweather (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Merriweather Variable', serif",
+ "provider": "google",
+ "import": "Merriweather",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/merriweather"
+ }
+ },
+ {
+ "name": "font-heading-lora",
+ "title": "Lora (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Lora Variable', serif",
+ "provider": "google",
+ "import": "Lora",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/lora"
+ }
+ },
+ {
+ "name": "font-heading-playfair-display",
+ "title": "Playfair Display (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Playfair Display Variable', serif",
+ "provider": "google",
+ "import": "Playfair_Display",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/playfair-display"
+ }
+ },
+ {
+ "name": "font-heading-eb-garamond",
+ "title": "EB Garamond (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'EB Garamond Variable', serif",
+ "provider": "google",
+ "import": "EB_Garamond",
+ "variable": "--font-heading",
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource-variable/eb-garamond"
+ }
+ },
+ {
+ "name": "font-heading-instrument-serif",
+ "title": "Instrument Serif (Heading)",
+ "type": "registry:font",
+ "font": {
+ "family": "'Instrument Serif', serif",
+ "provider": "google",
+ "import": "Instrument_Serif",
+ "variable": "--font-heading",
+ "weight": [
+ "400"
+ ],
+ "subsets": [
+ "latin"
+ ],
+ "dependency": "@fontsource/instrument-serif"
+ }
+ }
+ ]
+}
diff --git a/apps/v4/registry/radix-lyra/ui/accordion.tsx b/apps/v4/registry/radix-lyra/ui/accordion.tsx
new file mode 100644
index 00000000000..4a5bdef7eaa
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/accordion.tsx
@@ -0,0 +1,97 @@
+"use client"
+
+import * as React from "react"
+import { Accordion as AccordionPrimitive } from "radix-ui"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+function Accordion({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AccordionItem({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AccordionTrigger({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+ {children}
+
+
+
+
+ )
+}
+
+function AccordionContent({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+ {children}
+
+
+ )
+}
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
diff --git a/apps/v4/registry/radix-lyra/ui/alert-dialog.tsx b/apps/v4/registry/radix-lyra/ui/alert-dialog.tsx
new file mode 100644
index 00000000000..c9205ed4d44
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/alert-dialog.tsx
@@ -0,0 +1,199 @@
+"use client"
+
+import * as React from "react"
+import { AlertDialog as AlertDialogPrimitive } from "radix-ui"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+import { Button } from "@/registry/radix-lyra/ui/button"
+
+function AlertDialog({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function AlertDialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogContent({
+ className,
+ size = "default",
+ ...props
+}: React.ComponentProps & {
+ size?: "default" | "sm"
+}) {
+ return (
+
+
+
+
+ )
+}
+
+function AlertDialogHeader({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertDialogFooter({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertDialogMedia({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertDialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogAction({
+ className,
+ variant = "default",
+ size = "default",
+ ...props
+}: React.ComponentProps &
+ Pick, "variant" | "size">) {
+ return (
+
+
+
+ )
+}
+
+function AlertDialogCancel({
+ className,
+ variant = "outline",
+ size = "default",
+ ...props
+}: React.ComponentProps &
+ Pick, "variant" | "size">) {
+ return (
+
+
+
+ )
+}
+
+export {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogMedia,
+ AlertDialogOverlay,
+ AlertDialogPortal,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+}
diff --git a/apps/v4/registry/radix-lyra/ui/alert.tsx b/apps/v4/registry/radix-lyra/ui/alert.tsx
new file mode 100644
index 00000000000..5ec379b05c9
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/alert.tsx
@@ -0,0 +1,79 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+
+const alertVariants = cva(
+ "group/alert relative grid w-full gap-0.5 rounded-none border px-2.5 py-2 text-left text-xs has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
+ {
+ variants: {
+ variant: {
+ default: "bg-card text-card-foreground",
+ destructive:
+ "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+function Alert({
+ className,
+ variant,
+ ...props
+}: React.ComponentProps<"div"> & VariantProps) {
+ return (
+
+ )
+}
+
+function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+ svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+function AlertDescription({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export { Alert, AlertTitle, AlertDescription, AlertAction }
diff --git a/apps/v4/registry/radix-lyra/ui/aspect-ratio.tsx b/apps/v4/registry/radix-lyra/ui/aspect-ratio.tsx
new file mode 100644
index 00000000000..57e38fa96f9
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/aspect-ratio.tsx
@@ -0,0 +1,11 @@
+"use client"
+
+import { AspectRatio as AspectRatioPrimitive } from "radix-ui"
+
+function AspectRatio({
+ ...props
+}: React.ComponentProps
) {
+ return
+}
+
+export { AspectRatio }
diff --git a/apps/v4/registry/radix-lyra/ui/avatar.tsx b/apps/v4/registry/radix-lyra/ui/avatar.tsx
new file mode 100644
index 00000000000..dde6e782a77
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/avatar.tsx
@@ -0,0 +1,112 @@
+"use client"
+
+import * as React from "react"
+import { Avatar as AvatarPrimitive } from "radix-ui"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+
+function Avatar({
+ className,
+ size = "default",
+ ...props
+}: React.ComponentProps & {
+ size?: "default" | "sm" | "lg"
+}) {
+ return (
+
+ )
+}
+
+function AvatarImage({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AvatarFallback({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
+ return (
+ svg]:hidden",
+ "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
+ "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AvatarGroupCount({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+ svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+export {
+ Avatar,
+ AvatarImage,
+ AvatarFallback,
+ AvatarGroup,
+ AvatarGroupCount,
+ AvatarBadge,
+}
diff --git a/apps/v4/registry/radix-lyra/ui/badge.tsx b/apps/v4/registry/radix-lyra/ui/badge.tsx
new file mode 100644
index 00000000000..27a82afaa74
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/badge.tsx
@@ -0,0 +1,49 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+import { Slot } from "radix-ui"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+
+const badgeVariants = cva(
+ "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-none border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
+ secondary:
+ "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
+ destructive:
+ "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
+ outline:
+ "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
+ ghost:
+ "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+function Badge({
+ className,
+ variant = "default",
+ asChild = false,
+ ...props
+}: React.ComponentProps<"span"> &
+ VariantProps
& { asChild?: boolean }) {
+ const Comp = asChild ? Slot.Root : "span"
+
+ return (
+
+ )
+}
+
+export { Badge, badgeVariants }
diff --git a/apps/v4/registry/radix-lyra/ui/breadcrumb.tsx b/apps/v4/registry/radix-lyra/ui/breadcrumb.tsx
new file mode 100644
index 00000000000..012b906de23
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/breadcrumb.tsx
@@ -0,0 +1,134 @@
+import * as React from "react"
+import { Slot } from "radix-ui"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) {
+ return (
+
+ )
+}
+
+function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
+ return (
+
+ )
+}
+
+function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
+ return (
+
+ )
+}
+
+function BreadcrumbLink({
+ asChild,
+ className,
+ ...props
+}: React.ComponentProps<"a"> & {
+ asChild?: boolean
+}) {
+ const Comp = asChild ? Slot.Root : "a"
+
+ return (
+
+ )
+}
+
+function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
+ return (
+
+ )
+}
+
+function BreadcrumbSeparator({
+ children,
+ className,
+ ...props
+}: React.ComponentProps<"li">) {
+ return (
+ svg]:size-3.5", className)}
+ {...props}
+ >
+ {children ?? (
+
+ )}
+
+ )
+}
+
+function BreadcrumbEllipsis({
+ className,
+ ...props
+}: React.ComponentProps<"span">) {
+ return (
+ svg]:size-4",
+ className
+ )}
+ {...props}
+ >
+
+ More
+
+ )
+}
+
+export {
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+ BreadcrumbEllipsis,
+}
diff --git a/apps/v4/registry/radix-lyra/ui/button-group.tsx b/apps/v4/registry/radix-lyra/ui/button-group.tsx
new file mode 100644
index 00000000000..8cb59948ad7
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/button-group.tsx
@@ -0,0 +1,83 @@
+import { cva, type VariantProps } from "class-variance-authority"
+import { Slot } from "radix-ui"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+import { Separator } from "@/registry/radix-lyra/ui/separator"
+
+const buttonGroupVariants = cva(
+ "group/button-group flex w-fit items-stretch rounded-none *:focus-visible:relative *:focus-visible:z-10 has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-none [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
+ {
+ variants: {
+ orientation: {
+ horizontal:
+ "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
+ vertical:
+ "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none",
+ },
+ },
+ defaultVariants: {
+ orientation: "horizontal",
+ },
+ }
+)
+
+function ButtonGroup({
+ className,
+ orientation,
+ ...props
+}: React.ComponentProps<"div"> & VariantProps) {
+ return (
+
+ )
+}
+
+function ButtonGroupText({
+ className,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"div"> & {
+ asChild?: boolean
+}) {
+ const Comp = asChild ? Slot.Root : "div"
+
+ return (
+
+ )
+}
+
+function ButtonGroupSeparator({
+ className,
+ orientation = "vertical",
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ ButtonGroup,
+ ButtonGroupSeparator,
+ ButtonGroupText,
+ buttonGroupVariants,
+}
diff --git a/apps/v4/registry/radix-lyra/ui/button.tsx b/apps/v4/registry/radix-lyra/ui/button.tsx
new file mode 100644
index 00000000000..fedb1ac5e2f
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/button.tsx
@@ -0,0 +1,65 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+import { Slot } from "radix-ui"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+
+const buttonVariants = cva(
+ "group/button inline-flex shrink-0 items-center justify-center rounded-none border border-transparent bg-clip-padding text-xs font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
+ outline:
+ "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
+ secondary:
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
+ ghost:
+ "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
+ destructive:
+ "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default:
+ "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
+ xs: "h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
+ sm: "h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
+ icon: "size-8",
+ "icon-xs": "size-6 rounded-none [&_svg:not([class*='size-'])]:size-3",
+ "icon-sm": "size-7 rounded-none",
+ "icon-lg": "size-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function Button({
+ className,
+ variant = "default",
+ size = "default",
+ asChild = false,
+ ...props
+}: React.ComponentProps<"button"> &
+ VariantProps & {
+ asChild?: boolean
+ }) {
+ const Comp = asChild ? Slot.Root : "button"
+
+ return (
+
+ )
+}
+
+export { Button, buttonVariants }
diff --git a/apps/v4/registry/radix-lyra/ui/calendar.tsx b/apps/v4/registry/radix-lyra/ui/calendar.tsx
new file mode 100644
index 00000000000..bcdc435f997
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/calendar.tsx
@@ -0,0 +1,246 @@
+"use client"
+
+import * as React from "react"
+import {
+ DayPicker,
+ getDefaultClassNames,
+ type DayButton,
+ type Locale,
+} from "react-day-picker"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+import { Button, buttonVariants } from "@/registry/radix-lyra/ui/button"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+function Calendar({
+ className,
+ classNames,
+ showOutsideDays = true,
+ captionLayout = "label",
+ buttonVariant = "ghost",
+ locale,
+ formatters,
+ components,
+ ...props
+}: React.ComponentProps & {
+ buttonVariant?: React.ComponentProps["variant"]
+}) {
+ const defaultClassNames = getDefaultClassNames()
+
+ return (
+ svg]:rotate-180`,
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
+ className
+ )}
+ captionLayout={captionLayout}
+ locale={locale}
+ formatters={{
+ formatMonthDropdown: (date) =>
+ date.toLocaleString(locale?.code, { month: "short" }),
+ ...formatters,
+ }}
+ classNames={{
+ root: cn("w-fit", defaultClassNames.root),
+ months: cn(
+ "relative flex flex-col gap-4 md:flex-row",
+ defaultClassNames.months
+ ),
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
+ nav: cn(
+ "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
+ defaultClassNames.nav
+ ),
+ button_previous: cn(
+ buttonVariants({ variant: buttonVariant }),
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
+ defaultClassNames.button_previous
+ ),
+ button_next: cn(
+ buttonVariants({ variant: buttonVariant }),
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
+ defaultClassNames.button_next
+ ),
+ month_caption: cn(
+ "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
+ defaultClassNames.month_caption
+ ),
+ dropdowns: cn(
+ "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
+ defaultClassNames.dropdowns
+ ),
+ dropdown_root: cn(
+ "cn-calendar-dropdown-root relative rounded-(--cell-radius)",
+ defaultClassNames.dropdown_root
+ ),
+ dropdown: cn(
+ "absolute inset-0 bg-popover opacity-0",
+ defaultClassNames.dropdown
+ ),
+ caption_label: cn(
+ "font-medium select-none",
+ captionLayout === "label"
+ ? "cn-calendar-caption text-sm"
+ : "cn-calendar-caption-label flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
+ defaultClassNames.caption_label
+ ),
+ table: "w-full border-collapse",
+ weekdays: cn("flex", defaultClassNames.weekdays),
+ weekday: cn(
+ "flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none",
+ defaultClassNames.weekday
+ ),
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
+ week_number_header: cn(
+ "w-(--cell-size) select-none",
+ defaultClassNames.week_number_header
+ ),
+ week_number: cn(
+ "text-[0.8rem] text-muted-foreground select-none",
+ defaultClassNames.week_number
+ ),
+ day: cn(
+ "group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)",
+ props.showWeekNumber
+ ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)"
+ : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
+ defaultClassNames.day
+ ),
+ range_start: cn(
+ "relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted",
+ defaultClassNames.range_start
+ ),
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
+ range_end: cn(
+ "relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted",
+ defaultClassNames.range_end
+ ),
+ today: cn(
+ "rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none",
+ defaultClassNames.today
+ ),
+ outside: cn(
+ "text-muted-foreground aria-selected:text-muted-foreground",
+ defaultClassNames.outside
+ ),
+ disabled: cn(
+ "text-muted-foreground opacity-50",
+ defaultClassNames.disabled
+ ),
+ hidden: cn("invisible", defaultClassNames.hidden),
+ ...classNames,
+ }}
+ components={{
+ Root: ({ className, rootRef, ...props }) => {
+ return (
+
+ )
+ },
+ Chevron: ({ className, orientation, ...props }) => {
+ if (orientation === "left") {
+ return (
+
+ )
+ }
+
+ if (orientation === "right") {
+ return (
+
+ )
+ }
+
+ return (
+
+ )
+ },
+ DayButton: ({ ...props }) => (
+
+ ),
+ WeekNumber: ({ children, ...props }) => {
+ return (
+
+
+ {children}
+
+
+ )
+ },
+ ...components,
+ }}
+ {...props}
+ />
+ )
+}
+
+function CalendarDayButton({
+ className,
+ day,
+ modifiers,
+ locale,
+ ...props
+}: React.ComponentProps & { locale?: Partial }) {
+ const defaultClassNames = getDefaultClassNames()
+
+ const ref = React.useRef(null)
+ React.useEffect(() => {
+ if (modifiers.focused) ref.current?.focus()
+ }, [modifiers.focused])
+
+ return (
+ span]:text-xs [&>span]:opacity-70",
+ defaultClassNames.day,
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+export { Calendar, CalendarDayButton }
diff --git a/apps/v4/registry/radix-lyra/ui/card.tsx b/apps/v4/registry/radix-lyra/ui/card.tsx
new file mode 100644
index 00000000000..f7823d31ab6
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/card.tsx
@@ -0,0 +1,103 @@
+import * as React from "react"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+
+function Card({
+ className,
+ size = "default",
+ ...props
+}: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
+ return (
+ img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardAction({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardContent({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardAction,
+ CardDescription,
+ CardContent,
+}
diff --git a/apps/v4/registry/radix-lyra/ui/carousel.tsx b/apps/v4/registry/radix-lyra/ui/carousel.tsx
new file mode 100644
index 00000000000..05a8adae39b
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/carousel.tsx
@@ -0,0 +1,256 @@
+"use client"
+
+import * as React from "react"
+import useEmblaCarousel, {
+ type UseEmblaCarouselType,
+} from "embla-carousel-react"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+import { Button } from "@/registry/radix-lyra/ui/button"
+import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
+
+type CarouselApi = UseEmblaCarouselType[1]
+type UseCarouselParameters = Parameters
+type CarouselOptions = UseCarouselParameters[0]
+type CarouselPlugin = UseCarouselParameters[1]
+
+type CarouselProps = {
+ opts?: CarouselOptions
+ plugins?: CarouselPlugin
+ orientation?: "horizontal" | "vertical"
+ setApi?: (api: CarouselApi) => void
+}
+
+type CarouselContextProps = {
+ carouselRef: ReturnType[0]
+ api: ReturnType[1]
+ scrollPrev: () => void
+ scrollNext: () => void
+ canScrollPrev: boolean
+ canScrollNext: boolean
+} & CarouselProps
+
+const CarouselContext = React.createContext(null)
+
+function useCarousel() {
+ const context = React.useContext(CarouselContext)
+
+ if (!context) {
+ throw new Error("useCarousel must be used within a ")
+ }
+
+ return context
+}
+
+function Carousel({
+ orientation = "horizontal",
+ opts,
+ setApi,
+ plugins,
+ className,
+ children,
+ ...props
+}: React.ComponentProps<"div"> & CarouselProps) {
+ const [carouselRef, api] = useEmblaCarousel(
+ {
+ ...opts,
+ axis: orientation === "horizontal" ? "x" : "y",
+ },
+ plugins
+ )
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
+
+ const onSelect = React.useCallback((api: CarouselApi) => {
+ if (!api) return
+ setCanScrollPrev(api.canScrollPrev())
+ setCanScrollNext(api.canScrollNext())
+ }, [])
+
+ const scrollPrev = React.useCallback(() => {
+ api?.scrollPrev()
+ }, [api])
+
+ const scrollNext = React.useCallback(() => {
+ api?.scrollNext()
+ }, [api])
+
+ const handleKeyDown = React.useCallback(
+ (event: React.KeyboardEvent) => {
+ if (event.key === "ArrowLeft") {
+ event.preventDefault()
+ scrollPrev()
+ } else if (event.key === "ArrowRight") {
+ event.preventDefault()
+ scrollNext()
+ }
+ },
+ [scrollPrev, scrollNext]
+ )
+
+ React.useEffect(() => {
+ if (!api || !setApi) return
+ setApi(api)
+ }, [api, setApi])
+
+ React.useEffect(() => {
+ if (!api) return
+ onSelect(api)
+ api.on("reInit", onSelect)
+ api.on("select", onSelect)
+
+ return () => {
+ api?.off("select", onSelect)
+ }
+ }, [api, onSelect])
+
+ return (
+
+
+ {children}
+
+
+ )
+}
+
+function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
+ const { carouselRef, orientation } = useCarousel()
+
+ return (
+
+ )
+}
+
+function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
+ const { orientation } = useCarousel()
+
+ return (
+
+ )
+}
+
+function CarouselPrevious({
+ className,
+ variant = "outline",
+ size = "icon-sm",
+ ...props
+}: React.ComponentProps) {
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel()
+
+ return (
+
+
+ Previous slide
+
+ )
+}
+
+function CarouselNext({
+ className,
+ variant = "outline",
+ size = "icon-sm",
+ ...props
+}: React.ComponentProps) {
+ const { orientation, scrollNext, canScrollNext } = useCarousel()
+
+ return (
+
+
+ Next slide
+
+ )
+}
+
+export {
+ type CarouselApi,
+ Carousel,
+ CarouselContent,
+ CarouselItem,
+ CarouselPrevious,
+ CarouselNext,
+ useCarousel,
+}
diff --git a/apps/v4/registry/radix-lyra/ui/chart.tsx b/apps/v4/registry/radix-lyra/ui/chart.tsx
new file mode 100644
index 00000000000..7c69e0489b9
--- /dev/null
+++ b/apps/v4/registry/radix-lyra/ui/chart.tsx
@@ -0,0 +1,373 @@
+"use client"
+
+import * as React from "react"
+import * as RechartsPrimitive from "recharts"
+import type { TooltipValueType } from "recharts"
+
+import { cn } from "@/registry/radix-lyra/lib/utils"
+
+// Format: { THEME_NAME: CSS_SELECTOR }
+const THEMES = { light: "", dark: ".dark" } as const
+
+const INITIAL_DIMENSION = { width: 320, height: 200 } as const
+type TooltipNameType = number | string
+
+export type ChartConfig = Record<
+ string,
+ {
+ label?: React.ReactNode
+ icon?: React.ComponentType
+ } & (
+ | { color?: string; theme?: never }
+ | { color?: never; theme: Record }
+ )
+>
+
+type ChartContextProps = {
+ config: ChartConfig
+}
+
+const ChartContext = React.createContext(null)
+
+function useChart() {
+ const context = React.useContext(ChartContext)
+
+ if (!context) {
+ throw new Error("useChart must be used within a ")
+ }
+
+ return context
+}
+
+function ChartContainer({
+ id,
+ className,
+ children,
+ config,
+ initialDimension = INITIAL_DIMENSION,
+ ...props
+}: React.ComponentProps<"div"> & {
+ config: ChartConfig
+ children: React.ComponentProps<
+ typeof RechartsPrimitive.ResponsiveContainer
+ >["children"]
+ initialDimension?: {
+ width: number
+ height: number
+ }
+}) {
+ const uniqueId = React.useId()
+ const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`
+
+ return (
+
+
+
+
+ {children}
+
+
+
+ )
+}
+
+const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
+ const colorConfig = Object.entries(config).filter(
+ ([, config]) => config.theme ?? config.color
+ )
+
+ if (!colorConfig.length) {
+ return null
+ }
+
+ return (
+