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. +

+ + + ), + }, + { + 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 ( + + + + + + + + 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 ( + + + + + + + + Allow accessory to connect? + + Do you want to allow the USB accessory to connect to this device? + + + + Don't allow + Allow + + + + + ) +} + +function AlertDialogWithMedia() { + return ( + + + + + + + + + + + Are you absolutely sure? + + This will permanently delete your account and remove your data + from our servers. + + + + Cancel + Continue + + + + + ) +} + +function AlertDialogSmallWithMedia() { + return ( + + + + + + + + + + + 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? + + This will permanently delete this chat conversation. View{" "} + Settings delete any memories saved during this + chat. + + + + Cancel + Delete + + + + + ) +} + +function AlertDialogInDialog() { + return ( + + + + + + + + Alert Dialog Example + + Click the button below to open an 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. + + + + + + + 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 + + + + + + + + + Project Alpha + Created 2 days ago + + + + + + + + + ) +} 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 ( + + + Photo + + + ) +} + +function AspectRatio1x1() { + return ( + + + Photo + + + ) +} + +function AspectRatio9x16() { + return ( + + + Photo + + + ) +} + +function AspectRatio21x9() { + return ( + + + Photo + + + ) +} 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. + + + + + + + + ) +} 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 ( + +
+ + + Link{" "} + + + + + + Link{" "} + + + + + + Link{" "} + + + + + + Link{" "} + + + + + + Link{" "} + + + + + + Link{" "} + + + +
+
+ ) +} + +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 + + + + + + + + + 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 ( + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ ) +} + +function ButtonIconRight() { + return ( + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ ) +} + +function ButtonIconLeft() { + return ( + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ ) +} + +function ButtonIconOnly() { + return ( + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ ) +} + +function ButtonExamples() { + return ( + +
+
+ + +
+
+ + +
+
+
+ ) +} + +function ButtonInvalidStates() { + return ( + +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ ) +} 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 ( + +
+ + + + +
+
+ ) +} + +function ButtonGroupWithInput() { + return ( + +
+ + + + + + + + +
+
+ ) +} + +function ButtonGroupWithText() { + return ( + +
+ + Text + + + + + + + + +
+
+ ) +} + +function ButtonGroupWithDropdown() { + return ( + +
+ + + + + + + + Disable + + Uninstall + + + + + + + + + + + + + + + Mute Conversation + + + + Mark as Read + + + + Report Conversation + + + + Block User + + + + Share Conversation + + + + Copy Conversation + + + + + + + Delete Conversation + + + + + +
+
+ ) +} + +function ButtonGroupWithSelect() { + const [currency, setCurrency] = useState("$") + + return ( + + + + + + + + + + + ) +} + +function ButtonGroupWithIcons() { + return ( + +
+ + + + + +
+
+ ) +} + +function ButtonGroupWithInputGroup() { + return ( + +
+ + + + + + +
+
+ ) +} + +function ButtonGroupWithFields() { + return ( + + + + + + + + + W + + + px + + + + + + + + + ) +} + +function ButtonGroupWithLike() { + return ( + + + + + + + ) +} + +function ButtonGroupWithSelectAndInput() { + return ( + + + + + + + ) +} + +function ButtonGroupNested() { + return ( + + + + + + + + + + + + + + + Voice Mode + + + + + + ) +} + +function ButtonGroupPagination() { + return ( + + + + + + + + + + + + ) +} + +function ButtonGroupPaginationSplit() { + return ( + + + + + + + + + + + + + + + + ) +} + +function ButtonGroupNavigation() { + return ( + + + + + + + + + + + + ) +} + +function ButtonGroupTextAlignment() { + return ( + + + + + + + + + + + + ) +} + +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 ( + + + + + + + + + + + ) +} + +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) => ( + + ))} + + + + ) +} + +function DatePickerSimple() { + const [date, setDate] = React.useState() + + return ( + + + 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 + + + + + + + + + + + ) +} + +function DataPickerWithDropdowns() { + const [date, setDate] = React.useState() + const [open, setOpen] = React.useState(false) + + return ( + + + + + Date + + + + + + +
+ +
+
+
+
+
+ ) +} + +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 + + + +
+ + + Email + + + + + + + +
+
+ + + +
+ Don't have an account?{" "} + + Sign up + +
+
+
+
+ ) +} + +function CardMeetingNotes() { + return ( + + + + Meeting Notes + + Transcript from the meeting with the client. + + + + + + +

+ Client requested dashboard redesign with focus on mobile + responsiveness. +

+
    +
  1. New analytics widgets for daily/weekly metrics
  2. +
  3. Simplified navigation menu
  4. +
  5. Dark mode support
  6. +
  7. Timeline: 6 weeks
  8. +
  9. Follow-up meeting scheduled for next Tuesday
  10. +
+
+ + + + + CN + + + + LR + + + + ER + + +8 + + +
+
+ ) +} + +function CardWithImage() { + return ( + + +
+ Photo by mymind on Unsplash + + Beautiful Landscape + + A stunning view that captures the essence of natural beauty. + + + + + + + + ) +} + +function CardWithImageSmall() { + return ( + + +
+ Photo by mymind on Unsplash + + Beautiful Landscape + + A stunning view that captures the essence of natural beauty. + + + + + + + + ) +} + +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. +

+
+ + + +
+
+ ) +} + +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. +

+
+ + + +
+
+ ) +} + +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. +

+
+ + + +
+
+ ) +} + +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. +

+
+ + + +
+
+ ) +} 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 + + + + + } + /> + + + + + + +
+ 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 + + + + + + + + + + + + +
+ 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.items.map((child) => renderItem(child))} +
+
+
+ ) + } + return ( + + ) + } + + 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 + + + + + + + + + + + + + ) +} 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 ( + + + +
+ + + Framework + + + + No items found. + + {(item) => ( + + {item} + + )} + + + + + +
+
+ + + +
+
+ ) +} + +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 ( + + + + + + + + Select Framework + + Choose your preferred framework from the list below. + + + + + Framework + + + + + No items found. + + {(item) => ( + + {item} + + )} + + + + + + + + + + + + ) +} + +function ComboboxWithOtherInputs() { + return ( + + + + + No items found. + + {(item) => ( + + {item} + + )} + + + + + + + + + + + + + + ) +} 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 ( + +
+ + + + + + No results found. + + Calendar + Search Emoji + Calculator + + + + +
+
+ ) +} + +function CommandWithShortcuts() { + const [open, setOpen] = React.useState(false) + + return ( + +
+ + + + + + No results found. + + + + Profile + ⌘P + + + + Billing + ⌘B + + + + Settings + ⌘S + + + + + +
+
+ ) +} + +function CommandWithGroups() { + const [open, setOpen] = React.useState(false) + + return ( + +
+ + + + + + No results found. + + + + Calendar + + + + Search Emoji + + + + Calculator + + + + + + + Profile + ⌘P + + + + Billing + ⌘B + + + + Settings + ⌘S + + + + + +
+
+ ) +} + +function CommandManyItems() { + const [open, setOpen] = React.useState(false) + + return ( + +
+ + + + + + 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 ( + + + + + + + + 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 ( + + +
+ + + + + + Edit profile + + Make changes to your profile here. Click save when you're + done. Your profile will be updated immediately. + + + + + Name + + + + Username + + + + + + + + + + +
+
+
+ ) +} + +function DialogScrollableContent() { + return ( + + + + + + + + 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 ( + + + + + + + + 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 DialogNoCloseButton() { + return ( + + + + + + + + No Close Button + + This dialog doesn't have a close button in the top-right + corner. + + + + + + + + + + + ) +} + +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 + + 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 + + + + + + Accent Color + + + + + + + + Spoken Language + + + For best results, select the language you mainly + speak. If it's not listed, it may still be + supported via auto-detection. + + + + + + + Voice + + + +
+
+ + +
+ 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. + + +