diff --git a/public/r/action-button.json b/public/r/action-button.json new file mode 100644 index 0000000..d0d0d78 --- /dev/null +++ b/public/r/action-button.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "action-button", + "type": "registry:component", + "title": "Action Button", + "description": "A call-to-action button with animated hover effect and icon.", + "files": [ + { + "path": "registry/v3cn/action-button/action-button.tsx", + "content": "\"use client\";\nimport * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\nimport { ArrowRight } from \"lucide-react\";\n\nconst ActionButtonVariants = cva(\n \"relative overflow-hidden rounded-full text-sm font-semibold transition-all duration-300 group inline-flex items-center justify-center\",\n {\n variants: {\n size: {\n default: \"px-6 py-2 pr-12\",\n sm: \"px-4 py-1.5 pr-10 text-sm\",\n lg: \"px-8 py-3 pr-14 text-base\"\n },\n bgColor: {\n default: \"bg-yellow-500\",\n custom: \"\"\n },\n textColor: {\n default: \"text-white\",\n yellow: \"text-yellow-700\",\n red: \"text-red-500\",\n green: \"text-green-500\",\n blue: \"text-blue-500\"\n }\n },\n defaultVariants: {\n size: \"default\",\n bgColor: \"default\",\n textColor: \"default\"\n }\n }\n);\n\nexport interface ActionButtonProps\n extends React.ButtonHTMLAttributes,\n VariantProps {\n asChild?: boolean;\n text?: string;\n}\n\nconst ActionButton = React.forwardRef(\n (\n {\n className,\n size,\n bgColor,\n textColor,\n asChild = false,\n text = \"Start 14-day trial\",\n ...props\n },\n ref\n ) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n \n \n {text}\n \n\n \n\n \n \n \n \n );\n }\n);\n\nActionButton.displayName = \"TrialButton\";\n\nexport { ActionButton };", + "type": "registry:component", + "target": "components/action-button.tsx" + } + ] + } + \ No newline at end of file diff --git a/registry.json b/registry.json index 34a4cac..9015543 100644 --- a/registry.json +++ b/registry.json @@ -86,6 +86,22 @@ "target": "components/card-demo.tsx" } ] + },{ + "name": "action button", + "type": "registry:block", + "title": "Action Button", + "registryDependencies": [ + "https://v3cn.vineet.pro/r/action-button" + ], + "description": "A component for displaying Action Button.", + "files": [ + { + "path": "registry/v3cn/action-button/action-button.tsx", + "type": "registry:component", + "target": "components/actionButton.tsx" + } + ] } + ] } diff --git a/registry/v3cn/actionButton/actionButton.tsx b/registry/v3cn/actionButton/actionButton.tsx new file mode 100644 index 0000000..148883a --- /dev/null +++ b/registry/v3cn/actionButton/actionButton.tsx @@ -0,0 +1,89 @@ +"use client"; +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/lib/utils"; +import { ArrowRight } from "lucide-react"; + +const ActionButtonVariants = cva( + "relative overflow-hidden rounded-full text-sm font-semibold transition-all duration-300 group inline-flex items-center justify-center", + { + variants: { + size: { + default: "px-6 py-2 pr-12", + sm: "px-4 py-1.5 pr-10 text-sm", + lg: "px-8 py-3 pr-14 text-base", + }, + bgColor: { + default: "bg-yellow-500", + custom: "", + }, + textColor: { + default: "text-white", + yellow: "text-yellow-700", + red: "text-red-500", + green: "text-green-500", + blue: "text-blue-500", + }, + }, + defaultVariants: { + size: "default", + bgColor: "default", + textColor: "default", + }, + } +); + +export interface ActionButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; + text?: string; +} + +const ActionButton = React.forwardRef( + ( + { + className, + size, + bgColor, + textColor, + asChild = false, + text = "Start 14-day trial", + ...props + }, + ref + ) => { + const Comp = asChild ? Slot : "button"; + return ( + + {/* Text */} + + {text} + + + + + + + + + + ); + } +); + +ActionButton.displayName = "TrialButton"; + +export { ActionButton }; diff --git a/src/app/docs/components/actionbutton/page.tsx b/src/app/docs/components/actionbutton/page.tsx new file mode 100644 index 0000000..035b438 --- /dev/null +++ b/src/app/docs/components/actionbutton/page.tsx @@ -0,0 +1,189 @@ +import { AlertTriangle } from "lucide-react"; +import { CodeBlock } from "@/components/ui/code-block"; +import { ActionButton } from "@/components/demo-ui/actionbutton/demo"; +import { ActionButtonInstallationCode } from "@/components/demo-ui/actionbutton/installation"; +import { NavigationMenu } from "@/components/navigation-menu"; +import PropItem from "@/components/prop"; +import { PropTable } from "@/components/ui/prop-table"; +import { SectionWrapper } from "@/components/section-wrapper"; +import { basicUsageRawCode } from "@/components/demo-ui/actionbutton/code"; +import { codeToHtml } from "shiki/bundle/full"; +import { discordnextConfigCode } from "@/components/demo-ui/discord/installation"; + +// Define the PropDefinition type +type PropDefinition = { + prop: string; + type: string; + default?: string; + description: string; +}; + +const DiscordPresenceProps: PropDefinition[] = [ + { + prop: "userId", + type: "string", + description: "The unique identifier for the Discord user.", + }, + { + prop: "userName", + type: "string ", + description: "The display name of the Discord user.", + }, + { + prop: "activityDescriptionClass", + type: "string", + description: "CSS class for styling the activity description.", + }, + { + prop: "activityImageClassName", + type: "string", + description: "CSS class for styling the activity image.", + }, + { + prop: "activityDetailClass", + type: "string", + description: "CSS class for styling the activity details.", + }, { + prop: "progressBarClassName", + type: "string", + description: "CSS class for styling the progress bar (used for Spotify playback).", + }, + { + prop: "localTimeClass", + type: "string", + description: "CSS class for styling the local time display.", + }, +]; + + +export default async function DiscordPresencePage() { + const basicUsageCode = await codeToHtml(basicUsageRawCode, { + lang: "tsx", + theme: "min-dark", + }); + + const nextConfigCode = await codeToHtml(discordnextConfigCode, { + lang: "tsx", + theme: "min-dark", + }); + return ( + +
+
+ {/* Title */} +
+

+ Action Button +

+

+ This is a simple action button component that can be used to trigger actions or navigate to different pages. It is designed to be flexible and customizable, allowing you to easily integrate it into your application. +

+
+ + {/* Playground */} +
+

+ Playground +

+
+ +
+
+ +
+ + {/* Installation */} +
+

+ Installation +

+
+ +
+
+
+
+ +
+

+ Update your next config file +

+ +
+
+
+ +
+
+ +
+ + {/* Usage Examples */} +
+
+

+ Usage Examples +

+ + {/* Default Usage */} +
+

Default Usage

+ +
+
+
+ + + + +

+ Join this discord server to make your presence appear{" "} + + https://discord.gg/lanyard + +

+
+
+
+

+ Props +

+
+ +
+ +
+
+
+
+
+ + {/* Right-side navigation */} + +
+
+ ); +} diff --git a/src/components/demo-ui/actionbutton/code.tsx b/src/components/demo-ui/actionbutton/code.tsx new file mode 100644 index 0000000..f3af3fe --- /dev/null +++ b/src/components/demo-ui/actionbutton/code.tsx @@ -0,0 +1,33 @@ +import { ScrollArea } from "@/components/ui/scroll-area"; + +// Create a client component for rendering the code +export function CodeDisplay({ html }: { html: string }) { + return ( + +
+ + ); +} + +export const basicUsageRawCode = `"use client" +
+
+

Welcome to the Demo

+

+ Click the button below to start your free trial. +

+ + alert("Trial started!")} + /> +
+
+ ); +}`; diff --git a/src/components/demo-ui/actionbutton/demo.tsx b/src/components/demo-ui/actionbutton/demo.tsx new file mode 100644 index 0000000..c365939 --- /dev/null +++ b/src/components/demo-ui/actionbutton/demo.tsx @@ -0,0 +1,89 @@ +"use client"; +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/lib/utils"; +import { ArrowRight } from "lucide-react"; + +const ActionButtonVariants = cva( + "relative overflow-hidden rounded-full text-sm font-semibold transition-all duration-300 group inline-flex items-center justify-center", + { + variants: { + size: { + default: "px-6 py-2 pr-12", + sm: "px-4 py-1.5 pr-10 text-sm", + lg: "px-8 py-3 pr-14 text-base", + }, + bgColor: { + default: "bg-yellow-500", + custom: "", + }, + textColor: { + default: "text-white", + yellow: "text-yellow-700", + red: "text-red-500", + green: "text-green-500", + blue: "text-blue-500", + }, + }, + defaultVariants: { + size: "default", + bgColor: "default", + textColor: "default", + }, + } +); + +export interface ActionButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; + text?: string; +} + +const ActionButton = React.forwardRef( + ( + { + className, + size, + bgColor, + textColor, + asChild = false, + text = "Start 14-day trial", + ...props + }, + ref + ) => { + const Comp = asChild ? Slot : "button"; + return ( + + {/* Text */} + + {text} + + + + + + + + + + ); + } +); + +ActionButton.displayName = "TrialButton"; + +export { ActionButton }; \ No newline at end of file diff --git a/src/components/demo-ui/actionbutton/installation.tsx b/src/components/demo-ui/actionbutton/installation.tsx new file mode 100644 index 0000000..a6f095e --- /dev/null +++ b/src/components/demo-ui/actionbutton/installation.tsx @@ -0,0 +1,144 @@ +import { codeToHtml } from 'shiki'; +import { TDetails } from '@/types/types'; +import { InstallationTabs } from '@/components/installation-tabs'; + + +const actionButtonCode = `"use client"; + +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/lib/utils"; +import { ArrowRight } from "lucide-react"; + +const ActionButtonVariants = cva( + "relative overflow-hidden rounded-full text-sm font-semibold transition-all duration-300 group inline-flex items-center justify-center", + { + variants: { + size: { + default: "px-6 py-2 pr-12", + sm: "px-4 py-1.5 pr-10 text-sm", + lg: "px-8 py-3 pr-14 text-base", + }, + bgColor: { + default: "bg-yellow-500", + custom: "", + }, + textColor: { + default: "text-white", + yellow: "text-yellow-700", + red: "text-red-500", + green: "text-green-500", + blue: "text-blue-500", + }, + }, + defaultVariants: { + size: "default", + bgColor: "default", + textColor: "default", + }, + } +); + +export interface ActionButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; + text?: string; +} + +const ActionButton = React.forwardRef( + ( + { + className, + size, + bgColor, + textColor, + asChild = false, + text = "Start 14-day trial", + ...props + }, + ref + ) => { + const Comp = asChild ? Slot : "button"; + return ( + + + {text} + + + + + + + + + ); + } +); + +ActionButton.displayName = "TrialButton"; + +export { ActionButton }; +`; + +// If needed, you can reuse cnCode from before or import it again +const cnCode = `import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(...inputs)); +}`; + +export async function ActionButtonInstallationCode() { + const html = await codeToHtml(actionButtonCode, { + lang: 'tsx', + theme: 'min-dark', + }); + + const cnHtml = await codeToHtml(cnCode, { + lang: 'tsx', + theme: 'min-dark', + }); + + const buttonDetails: TDetails = { + component: 'ActionButton', + steps: [ + { + title: 'Create a `cn.ts` Utility File', + description: 'This function helps to merge Tailwind classes easily.', + html: cnHtml, + maxHeight: 100, + expandedHeight: 200, + }, + { + title: 'Add the ActionButton Component', + description: 'Add this full component code to your project.', + html: html, + maxHeight: 300, + expandedHeight: 500, + }, + ], + }; + + return ( + + ); +} diff --git a/src/components/sidebar-wrapper.tsx b/src/components/sidebar-wrapper.tsx index ce12b2a..33988b4 100644 --- a/src/components/sidebar-wrapper.tsx +++ b/src/components/sidebar-wrapper.tsx @@ -199,6 +199,12 @@ export function MySidebar({ isNew={true} label="Card" /> + } + isNew={true} + label="actionButton" + />
{/* footer */}