diff --git a/apps/docs/app/components/[id]/AnimationDetailPage.client.tsx b/apps/docs/app/components/[id]/AnimationDetailPage.client.tsx index 995d840..11ba460 100644 --- a/apps/docs/app/components/[id]/AnimationDetailPage.client.tsx +++ b/apps/docs/app/components/[id]/AnimationDetailPage.client.tsx @@ -573,14 +573,20 @@ export default function AnimationDetailPageClient({ ]); const installId = React.useMemo(() => { - if ( - component.category === "native" || - (component.availableIn && component.availableIn.length > 1) - ) { + const availableIn = component.availableIn || []; + const isMultiLibrary = + component.category === "native" || availableIn.length > 1; + + if (isMultiLibrary) { + // Carbon-only components should always install the carbon variant, + // even if the UI library is shadcnui/baseui. + if (availableIn.includes("carbon") && !availableIn.includes(selectedLibrary)) { + return `${component.id}-carbon`; + } return `${component.id}-${selectedLibrary}`; } return component.id; - }, [component.id, component.category, selectedLibrary]); + }, [component.id, component.category, component.availableIn, selectedLibrary]); return (
diff --git a/apps/docs/public/llms.txt b/apps/docs/public/llms.txt index 3fb15c1..07dc76b 100644 --- a/apps/docs/public/llms.txt +++ b/apps/docs/public/llms.txt @@ -2,14 +2,14 @@ > Production-ready UI components, blocks, and pages built on top of shadcn/ui and Framer Motion. -**Last Updated:** 2026-01-23T21:11:13.445Z +**Last Updated:** 2026-01-24T20:17:43.190Z ## Table of Contents -- Components (160 items) +- Components (161 items) - Blocks (74 items) - Pages (23 items) -- UI Elements (19 items) +- UI Elements (20 items) ### Components @@ -37,6 +37,8 @@ - [Glass Wallet Card](https://ui.tripled.work/components/glass-wallet-card-shadcnui): Glassmorphism crypto wallet card with balance, trend, and action buttons - [Hover Expand Card](https://ui.tripled.work/components/hover-expand-card-baseui): Card that lifts and expands on hover (Base UI) - [Hover Expand Card](https://ui.tripled.work/components/hover-expand-card-shadcnui): Card that lifts and expands on hover +- [Native User Card](https://ui.tripled.work/components/native-user-card-baseui): Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI) +- [Native User Card](https://ui.tripled.work/components/native-user-card-shadcnui): Compact user profile card with avatar, name, handle, and action button with spring animations - [Project Card](https://ui.tripled.work/components/project-card-baseui): Glassmorphism project card with links, tags, and hover effects (Base UI) - [Project Card](https://ui.tripled.work/components/project-card-shadcnui): Glassmorphism project card with links, tags, and hover effects - [Theater Ticket](https://ui.tripled.work/components/theater-ticket-baseui): Cinematic theater ticket with rip effect and barcode (Base UI) @@ -133,6 +135,7 @@ - [Wizard Form](https://ui.tripled.work/components/wizard-form-shadcnui): Multi-step wizard form with animated transitions, validation, and progress tracking - [Bottom Modal](https://ui.tripled.work/components/bottom-modal): Cute bottom-centered modal with smooth slide-up animation and glassmorphism design +- [Folder Animation](https://ui.tripled.work/components/folder-animation-carbon): Animated folder card with motion blur effect, perfect for showcasing file operations or loading states. - [Native Avatar Expand](https://ui.tripled.work/components/native-avatar-expand-baseui): Avatar component that expands to reveal the name on click with smooth animations. (Base UI) - [Native Avatar Expand](https://ui.tripled.work/components/native-avatar-expand-shadcnui): Avatar component that expands to reveal the name on click with smooth animations. - [Native Avatar With Name](https://ui.tripled.work/components/native-avatar-with-name-baseui): Avatar component that displays a name tooltip on hover with directional animations. (Base UI) @@ -188,8 +191,6 @@ - [Native Typewriter](https://ui.tripled.work/components/native-typewriter): Typewriter effect with speed control, looping, and blinking cursor. - [Native Typewriter](https://ui.tripled.work/components/native-typewriter-baseui): Typewriter effect with speed control, looping, and blinking cursor. (Base UI) - [Native Typewriter](https://ui.tripled.work/components/native-typewriter-shadcnui): Typewriter effect with speed control, looping, and blinking cursor. -- [Native User Card](https://ui.tripled.work/components/native-user-card-baseui): Compact user profile card with avatar, name, handle, and action button with spring animations. (Base UI) -- [Native User Card](https://ui.tripled.work/components/native-user-card-shadcnui): Compact user profile card with avatar, name, handle, and action button with spring animations. - [Native Verified Badge](https://ui.tripled.work/components/native-verified-badge-baseui): Verified badge component with multiple variants, sizes, and styles including outline and shield designs. (Base UI) - [Native Verified Badge](https://ui.tripled.work/components/native-verified-badge-shadcnui): Verified badge component with multiple variants, sizes, and styles including outline and shield designs. - [Social Login Button](https://ui.tripled.work/components/social-login-button-baseui): A set of animated social login buttons for major platforms (Github, Google, X, etc.) with various effects. (Base UI) @@ -341,6 +342,7 @@ - [Animated Quote Block](https://ui.tripled.work/components/animated-quote-block-shadcnui): Quote that types itself in, pauses, then subtly breathes - [Dynamic Tag Cloud](https://ui.tripled.work/components/dynamic-tag-cloud-shadcnui): Floating cluster of tags that drift and rearrange when hovered - [Floating Info Panel](https://ui.tripled.work/components/floating-info-panel-shadcnui): Info tooltip that drifts up/down while fading in/out intermittently +- [Folder Animation](https://ui.tripled.work/components/folder-animation): Animated folder card with motion blur effect, perfect for showcasing file operations or loading states - [Holographic Wall](https://ui.tripled.work/components/holographic-wall-shadcnui): Black wall with Pharaonic hieroglyphs and golden cursor light reflection - [Liquid Cursor](https://ui.tripled.work/components/liquid-cursor-shadcnui): A liquid-like cursor effect that mixes colors on movement - [Spotlight Section](https://ui.tripled.work/components/spotlight-section-shadcnui): Container where mouse creates soft radial spotlight following cursor diff --git a/apps/docs/public/md/folder-animation-carbon.md b/apps/docs/public/md/folder-animation-carbon.md new file mode 100644 index 0000000..a8f86a3 --- /dev/null +++ b/apps/docs/public/md/folder-animation-carbon.md @@ -0,0 +1,124 @@ +--- +title: Folder Animation +description: Animated folder card with motion blur effect, perfect for showcasing file operations or loading states. +component: true +--- + +```tsx +"use client" + +import * as React from "react" + +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx" + +export function FolderAnimationDemo() { + return ( + + ) +} +``` + +## Installation + + + + + CLI + Manual + + + +```bash +npx shadcn@latest add @uitripled/folder-animation-carbon +``` + + + + + + + +Copy and paste the following code into your project. + + + +Update the import paths to match your project setup. + + + + + + + +## Usage + +```tsx showLineNumbers +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx" +``` + +```tsx showLineNumbers + +``` + +## Component Details + +- **Category**: native + + +### Technical Specifications + +**Dependencies**: +- `framer-motion` +- `react` + +This component uses **Framer Motion** for animations and motion effects. + +## Customization + +This component can be customized by modifying the following: + +- **Styling**: The component uses Tailwind CSS for styling. Customize colors, spacing, and other design tokens through Tailwind classes. +- **Props**: Pass custom props to configure the component's behavior and appearance. +- **Variants**: Create custom variants by extending the component's base styles. + +## Accessibility + +The component follows accessibility best practices: + +- Proper ARIA labels and roles +- Keyboard navigation support +- Screen reader compatibility +- Focus management + +## Examples + +### Basic Example + +```tsx +"use client" + +import * as React from "react" + +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx" + +export function BasicExample() { + return ( + + ) +} +``` + +## API Reference + +This component is part of the UI TripleD component library, a collection of production-ready components built with Framer Motion, shadcn/ui, and Tailwind CSS. + +## Best Practices + +1. **Performance**: Consider lazy loading if used in large lists or below-the-fold content. +2. **Theming**: Ensure your theme configuration includes the necessary CSS variables. +3. **Testing**: Test keyboard navigation and screen reader compatibility. +4. **Customization**: Use props for configuration rather than modifying source code. + +## Related Components + +No related components. diff --git a/apps/docs/public/md/folder-animation.md b/apps/docs/public/md/folder-animation.md new file mode 100644 index 0000000..eba45a3 --- /dev/null +++ b/apps/docs/public/md/folder-animation.md @@ -0,0 +1,124 @@ +--- +title: Folder Animation +description: Animated folder card with motion blur effect, perfect for showcasing file operations or loading states +component: true +--- + +```tsx +"use client" + +import * as React from "react" + +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx" + +export function FolderAnimationDemo() { + return ( + + ) +} +``` + +## Installation + + + + + CLI + Manual + + + +```bash +npx shadcn@latest add @uitripled/folder-animation +``` + + + + + + + +Copy and paste the following code into your project. + + + +Update the import paths to match your project setup. + + + + + + + +## Usage + +```tsx showLineNumbers +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx" +``` + +```tsx showLineNumbers + +``` + +## Component Details + +- **Category**: decorative + + +### Technical Specifications + +**Dependencies**: +- `framer-motion` +- `react` + +This component uses **Framer Motion** for animations and motion effects. + +## Customization + +This component can be customized by modifying the following: + +- **Styling**: The component uses Tailwind CSS for styling. Customize colors, spacing, and other design tokens through Tailwind classes. +- **Props**: Pass custom props to configure the component's behavior and appearance. +- **Variants**: Create custom variants by extending the component's base styles. + +## Accessibility + +The component follows accessibility best practices: + +- Proper ARIA labels and roles +- Keyboard navigation support +- Screen reader compatibility +- Focus management + +## Examples + +### Basic Example + +```tsx +"use client" + +import * as React from "react" + +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx" + +export function BasicExample() { + return ( + + ) +} +``` + +## API Reference + +This component is part of the UI TripleD component library, a collection of production-ready components built with Framer Motion, shadcn/ui, and Tailwind CSS. + +## Best Practices + +1. **Performance**: Consider lazy loading if used in large lists or below-the-fold content. +2. **Theming**: Ensure your theme configuration includes the necessary CSS variables. +3. **Testing**: Test keyboard navigation and screen reader compatibility. +4. **Customization**: Use props for configuration rather than modifying source code. + +## Related Components + +No related components. diff --git a/apps/docs/public/md/native-user-card-baseui.md b/apps/docs/public/md/native-user-card-baseui.md index fe6c224..29292de 100644 --- a/apps/docs/public/md/native-user-card-baseui.md +++ b/apps/docs/public/md/native-user-card-baseui.md @@ -1,6 +1,6 @@ --- title: Native User Card -description: Compact user profile card with avatar, name, handle, and action button with spring animations. (Base UI) +description: Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI) component: true --- @@ -68,7 +68,7 @@ import { NativeUserCard } from "@uitripled/react-baseui/src/components/native/na ## Component Details -- **Category**: native +- **Category**: cards ### Technical Specifications diff --git a/apps/docs/public/md/native-user-card-shadcnui.md b/apps/docs/public/md/native-user-card-shadcnui.md index 94fda82..68009a2 100644 --- a/apps/docs/public/md/native-user-card-shadcnui.md +++ b/apps/docs/public/md/native-user-card-shadcnui.md @@ -1,6 +1,6 @@ --- title: Native User Card -description: Compact user profile card with avatar, name, handle, and action button with spring animations. +description: Compact user profile card with avatar, name, handle, and action button with spring animations component: true --- @@ -62,7 +62,7 @@ import { NativeUserCard } from "@uitripled/react-shadcn/src/components/native/na ## Component Details -- **Category**: native +- **Category**: cards ### Technical Specifications diff --git a/apps/docs/public/r/dashboard-baseui.json b/apps/docs/public/r/dashboard-baseui.json index defa0bd..ba72013 100644 --- a/apps/docs/public/r/dashboard-baseui.json +++ b/apps/docs/public/r/dashboard-baseui.json @@ -13,8 +13,8 @@ ], "files": [ { - "path": "@uitripled/react-baseui/src/components/components/stocks-dashboard/dashboard.tsx", - "content": "\"use client\";\n\nimport type React from \"react\";\n\nimport { NativeButton } from \"../../native/baseui/native-button-baseui\";\nimport { cn } from \"@/lib/utils\";\nimport { motion, type Variants } from \"framer-motion\";\nimport {\n Activity,\n BarChart3,\n ChevronRight,\n Clock,\n DollarSign,\n Download,\n Menu,\n Percent,\n Settings,\n TrendingDown,\n TrendingUp,\n Users,\n Zap,\n} from \"lucide-react\";\nimport { useState } from \"react\";\nimport {\n CartesianGrid,\n Line,\n LineChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\n\n// ============================================================================\n// TYPES & INTERFACES\n// ============================================================================\n\ninterface MetricCardProps {\n label: string;\n value: string;\n change: string;\n trend: \"up\" | \"down\";\n icon: React.ReactNode;\n}\n\ninterface ChartCardProps {\n title: string;\n description: string;\n data: Array<{ name: string; value: number }>;\n dataKey: string;\n height?: number;\n}\n\ninterface DetailItem {\n label: string;\n value: string;\n subtitle: string;\n}\n\ninterface DetailedCardProps {\n title: string;\n items: DetailItem[];\n}\n\n// ============================================================================\n// LOCAL COMPONENTS\n// ============================================================================\n\ninterface BadgeProps extends React.HTMLAttributes {\n variant?: \"default\" | \"secondary\" | \"destructive\" | \"outline\";\n}\n\nfunction Badge({ className, variant = \"default\", ...props }: BadgeProps) {\n return (\n \n );\n}\n\n// ============================================================================\n// STATIC CHART DATA - EXTENSIVE DUMMY DATA FOR PROPER RENDERING\n// ============================================================================\n\nconst USER_GROWTH_DATA = [\n { name: \"Week 1\", value: 2400 },\n { name: \"Week 2\", value: 3210 },\n { name: \"Week 3\", value: 2290 },\n { name: \"Week 4\", value: 2000 },\n { name: \"Week 5\", value: 2181 },\n { name: \"Week 6\", value: 2500 },\n { name: \"Week 7\", value: 2100 },\n { name: \"Week 8\", value: 2200 },\n { name: \"Week 9\", value: 2290 },\n { name: \"Week 10\", value: 2000 },\n { name: \"Week 11\", value: 2181 },\n { name: \"Week 12\", value: 2500 },\n { name: \"Week 13\", value: 2100 },\n];\n\nconst REVENUE_TREND_DATA = [\n { name: \"Week 1\", value: 4000 },\n { name: \"Week 2\", value: 3000 },\n { name: \"Week 3\", value: 2000 },\n { name: \"Week 4\", value: 2780 },\n { name: \"Week 5\", value: 1890 },\n { name: \"Week 6\", value: 2390 },\n { name: \"Week 7\", value: 3490 },\n { name: \"Week 8\", value: 4000 },\n { name: \"Week 9\", value: 3500 },\n { name: \"Week 10\", value: 4200 },\n { name: \"Week 11\", value: 3800 },\n { name: \"Week 12\", value: 4500 },\n { name: \"Week 13\", value: 4100 },\n];\n\n// ============================================================================\n// ANIMATION VARIANTS\n// ============================================================================\n\nconst containerVariants: Variants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n};\n\nconst itemVariants: Variants = {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.4 },\n },\n};\n\n// ============================================================================\n// COMPONENTS\n// ============================================================================\n\n// Metric Card Component\nfunction MetricCard({ label, value, change, trend, icon }: MetricCardProps) {\n const isPositive = trend === \"up\";\n const TrendIcon = isPositive ? TrendingUp : TrendingDown;\n\n return (\n \n
\n\n
\n
\n
\n {icon}\n
\n \n \n {change}\n
\n
\n\n
\n

\n {label}\n

\n

\n {value}\n

\n
\n
\n \n );\n}\n\n// Chart Card Component\nfunction ChartCard({\n title,\n description,\n data,\n dataKey,\n height = 300,\n}: ChartCardProps) {\n return (\n \n
\n\n
\n
\n
\n

\n {title}\n

\n

{description}

\n
\n \n \n \n
\n\n {/* Chart Container with proper sizing */}\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n \n );\n}\n\n// Detailed Card Component\nfunction DetailedCard({ title, items }: DetailedCardProps) {\n return (\n \n
\n\n
\n

\n {title}\n

\n\n
\n {items.map((item, index) => (\n \n
\n
\n

\n {item.label}\n

\n

{item.subtitle}

\n
\n
\n

\n {item.value}\n

\n \n
\n
\n \n ))}\n
\n
\n \n );\n}\n\n// Dashboard Navigation Component\nfunction DashboardNav() {\n const [isOpen, setIsOpen] = useState(false);\n\n const navItems = [\n { label: \"Overview\", icon: BarChart3 },\n { label: \"Activity\", icon: Activity },\n { label: \"Users\", icon: Users },\n { label: \"Analytics\", icon: TrendingUp },\n { label: \"History\", icon: Clock },\n ];\n\n return (\n \n
\n
\n
\n Dashboard\n
\n\n {/* Mobile menu button */}\n setIsOpen(!isOpen)}\n className=\"md:hidden p-2 hover:bg-background/60 rounded-lg transition-colors\"\n aria-label=\"Toggle navigation menu\"\n aria-expanded={isOpen}\n >\n \n \n\n {/* Desktop nav */}\n \n {navItems.map((item) => {\n const Icon = item.icon;\n return (\n \n \n \n {item.label}\n \n \n );\n })}\n
\n
\n\n {/* Mobile nav */}\n {isOpen && (\n \n {navItems.map((item) => {\n const Icon = item.icon;\n return (\n \n \n \n {item.label}\n \n \n );\n })}\n \n )}\n
\n \n );\n}\n\n// Dashboard Header Component\nfunction DashboardHeader() {\n return (\n \n
\n
\n \n \n Live Dashboard\n \n\n

\n Performance Overview\n

\n

\n Monitor your application metrics, user activity, and system health\n in real-time with detailed insights and historical data trends.\n

\n
\n\n \n \n \n \n \n \n \n
\n
\n \n );\n}\n\n// Main Dashboard Grid\nfunction DashboardGrid() {\n return (\n \n {/* Top KPI Row - Replaced emoji icons with lucide icons */}\n \n }\n />\n }\n />\n }\n />\n \n }\n />\n \n\n {/* Charts Row */}\n \n \n \n \n\n {/* Detailed Cards Row */}\n \n \n \n \n \n \n );\n}\n\n// ============================================================================\n// MAIN PAGE COMPONENT\n// ============================================================================\n\nexport function DashboardPage() {\n return (\n
\n {/* Glassmorphism background blobs */}\n
\n
\n
\n
\n
\n\n {/* Navigation */}\n \n\n {/* Main Content */}\n
\n
\n \n \n
\n
\n
\n );\n}\n", + "path": "@uitripled/react-baseui/src/components/stocks-dashboard/dashboard-baseui.tsx", + "content": "// Error: Could not read file @uitripled/react-baseui/src/components/stocks-dashboard/dashboard-baseui.tsx\n// File not found: @uitripled/react-baseui/src/components/stocks-dashboard/dashboard-baseui.tsx", "type": "registry:block", "target": "components/uitripled/dashboard-baseui.tsx" } diff --git a/apps/docs/public/r/folder-animation-carbon.json b/apps/docs/public/r/folder-animation-carbon.json new file mode 100644 index 0000000..0e751d7 --- /dev/null +++ b/apps/docs/public/r/folder-animation-carbon.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "folder-animation-carbon", + "type": "registry:component", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n motion,\n useAnimationControls,\n useReducedMotion,\n} from \"framer-motion\";\nimport { type ReactNode, useState, useCallback, useEffect, useRef } from \"react\";\n\ninterface FolderAnimationProps {\n /**\n * Duration of the animation cycle in seconds.\n * Default: 3\n */\n animationDuration?: number;\n /**\n * Custom folder icon to display. If not provided, a default folder icon is rendered.\n */\n folderIcon?: ReactNode;\n /**\n * Content to display in the card footer.\n */\n children?: ReactNode;\n /**\n * Additional CSS classes for the container.\n */\n className?: string;\n /**\n * Accessible label for the animation area.\n */\n ariaLabel?: string;\n}\n\nexport function FolderAnimation({\n animationDuration = 3,\n folderIcon,\n children,\n className,\n ariaLabel = \"Animated folder illustration\",\n}: FolderAnimationProps) {\n const [isHovered, setIsHovered] = useState(false);\n const prefersReducedMotion = useReducedMotion();\n const controls = useAnimationControls();\n const blurControls = useAnimationControls();\n const isAnimatingRef = useRef(false);\n const shouldStopRef = useRef(false);\n\n const handleMouseEnter = useCallback(() => setIsHovered(true), []);\n const handleMouseLeave = useCallback(() => setIsHovered(false), []);\n const handleFocus = useCallback(() => setIsHovered(true), []);\n const handleBlur = useCallback(() => setIsHovered(false), []);\n\n // Animation sequence: center → right → (wrap to left) → center → repeat\n const runAnimation = useCallback(async () => {\n if (prefersReducedMotion) return;\n\n isAnimatingRef.current = true;\n shouldStopRef.current = false;\n\n while (!shouldStopRef.current) {\n // Phase 1: Center to right (exit right with blur)\n await Promise.all([\n controls.start({\n x: \"150%\",\n opacity: [1, 1, 0],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.7, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(0px)\", \"blur(0px)\", \"blur(8px)\", \"blur(16px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.5, 0.75, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Instantly move to left (off-screen)\n await controls.set({ x: \"-150%\", opacity: 0 });\n await blurControls.set({ filter: \"blur(16px)\" });\n\n if (shouldStopRef.current) break;\n\n // Phase 2: Left to center (enter from left, deblur)\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: [0, 1, 1],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.3, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(16px)\", \"blur(8px)\", \"blur(0px)\", \"blur(0px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.25, 0.5, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Brief pause at center\n await new Promise((resolve) => setTimeout(resolve, 400));\n }\n\n isAnimatingRef.current = false;\n }, [controls, blurControls, animationDuration, prefersReducedMotion]);\n\n // Return to center smoothly\n const returnToCenter = useCallback(async () => {\n shouldStopRef.current = true;\n\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: 1,\n transition: {\n duration: 0.5,\n ease: [0.25, 0.1, 0.25, 1], // cubic-bezier for smooth deceleration\n },\n }),\n blurControls.start({\n filter: \"blur(0px)\",\n transition: {\n duration: 0.3,\n ease: \"easeOut\",\n },\n }),\n ]);\n\n isAnimatingRef.current = false;\n }, [controls, blurControls]);\n\n useEffect(() => {\n if (isHovered && !prefersReducedMotion) {\n runAnimation();\n } else {\n returnToCenter();\n }\n }, [isHovered, prefersReducedMotion, runAnimation, returnToCenter]);\n\n // Set initial position\n useEffect(() => {\n controls.set({ x: \"0%\", opacity: 1 });\n blurControls.set({ filter: \"blur(0px)\" });\n }, [controls, blurControls]);\n\n return (\n
\n {/* Card Container */}\n
\n {/* Animation Area */}\n \n {/* Animated Icon/Folder */}\n \n \n {folderIcon ? (\n
{folderIcon}
\n ) : (\n
\n {/* Folder Back */}\n
\n {/* Tab */}\n
\n\n {/* Files inside */}\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n
\n
\n
\n\n {/* Folder Front */}\n
\n
\n
\n
\n )}\n \n \n
\n\n {/* Card Footer */}\n {children &&
{children}
}\n
\n
\n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ] +} \ No newline at end of file diff --git a/apps/docs/public/r/folder-animation.json b/apps/docs/public/r/folder-animation.json new file mode 100644 index 0000000..625b74a --- /dev/null +++ b/apps/docs/public/r/folder-animation.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "folder-animation", + "type": "registry:ui", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n motion,\n useAnimationControls,\n useReducedMotion,\n} from \"framer-motion\";\nimport { type ReactNode, useState, useCallback, useEffect, useRef } from \"react\";\n\ninterface FolderAnimationProps {\n /**\n * Duration of the animation cycle in seconds.\n * Default: 3\n */\n animationDuration?: number;\n /**\n * Custom folder icon to display. If not provided, a default folder icon is rendered.\n */\n folderIcon?: ReactNode;\n /**\n * Content to display in the card footer.\n */\n children?: ReactNode;\n /**\n * Additional CSS classes for the container.\n */\n className?: string;\n /**\n * Accessible label for the animation area.\n */\n ariaLabel?: string;\n}\n\nexport function FolderAnimation({\n animationDuration = 3,\n folderIcon,\n children,\n className,\n ariaLabel = \"Animated folder illustration\",\n}: FolderAnimationProps) {\n const [isHovered, setIsHovered] = useState(false);\n const prefersReducedMotion = useReducedMotion();\n const controls = useAnimationControls();\n const blurControls = useAnimationControls();\n const isAnimatingRef = useRef(false);\n const shouldStopRef = useRef(false);\n\n const handleMouseEnter = useCallback(() => setIsHovered(true), []);\n const handleMouseLeave = useCallback(() => setIsHovered(false), []);\n const handleFocus = useCallback(() => setIsHovered(true), []);\n const handleBlur = useCallback(() => setIsHovered(false), []);\n\n // Animation sequence: center → right → (wrap to left) → center → repeat\n const runAnimation = useCallback(async () => {\n if (prefersReducedMotion) return;\n\n isAnimatingRef.current = true;\n shouldStopRef.current = false;\n\n while (!shouldStopRef.current) {\n // Phase 1: Center to right (exit right with blur)\n await Promise.all([\n controls.start({\n x: \"150%\",\n opacity: [1, 1, 0],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.7, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(0px)\", \"blur(0px)\", \"blur(8px)\", \"blur(16px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.5, 0.75, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Instantly move to left (off-screen)\n await controls.set({ x: \"-150%\", opacity: 0 });\n await blurControls.set({ filter: \"blur(16px)\" });\n\n if (shouldStopRef.current) break;\n\n // Phase 2: Left to center (enter from left, deblur)\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: [0, 1, 1],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.3, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(16px)\", \"blur(8px)\", \"blur(0px)\", \"blur(0px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.25, 0.5, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Brief pause at center\n await new Promise((resolve) => setTimeout(resolve, 400));\n }\n\n isAnimatingRef.current = false;\n }, [controls, blurControls, animationDuration, prefersReducedMotion]);\n\n // Return to center smoothly\n const returnToCenter = useCallback(async () => {\n shouldStopRef.current = true;\n\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: 1,\n transition: {\n duration: 0.5,\n ease: [0.25, 0.1, 0.25, 1], // cubic-bezier for smooth deceleration\n },\n }),\n blurControls.start({\n filter: \"blur(0px)\",\n transition: {\n duration: 0.3,\n ease: \"easeOut\",\n },\n }),\n ]);\n\n isAnimatingRef.current = false;\n }, [controls, blurControls]);\n\n useEffect(() => {\n if (isHovered && !prefersReducedMotion) {\n runAnimation();\n } else {\n returnToCenter();\n }\n }, [isHovered, prefersReducedMotion, runAnimation, returnToCenter]);\n\n // Set initial position\n useEffect(() => {\n controls.set({ x: \"0%\", opacity: 1 });\n blurControls.set({ filter: \"blur(0px)\" });\n }, [controls, blurControls]);\n\n return (\n
\n {/* Card Container */}\n
\n {/* Animation Area */}\n \n {/* Animated Icon/Folder */}\n \n \n {folderIcon ? (\n
{folderIcon}
\n ) : (\n
\n {/* Folder Back */}\n
\n {/* Tab */}\n
\n\n {/* Files inside */}\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n
\n
\n
\n\n {/* Folder Front */}\n
\n
\n
\n
\n )}\n \n \n
\n\n {/* Card Footer */}\n {children &&
{children}
}\n
\n
\n );\n}\n", + "type": "registry:ui", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ] +} \ No newline at end of file diff --git a/apps/docs/public/r/native-user-card-baseui.json b/apps/docs/public/r/native-user-card-baseui.json index 54e6d3c..0be8afb 100644 --- a/apps/docs/public/r/native-user-card-baseui.json +++ b/apps/docs/public/r/native-user-card-baseui.json @@ -3,7 +3,7 @@ "name": "native-user-card-baseui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations. (Base UI)", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI)", "registryDependencies": [ "button" ], diff --git a/apps/docs/public/r/native-user-card-shadcnui.json b/apps/docs/public/r/native-user-card-shadcnui.json index 3c71521..f77721a 100644 --- a/apps/docs/public/r/native-user-card-shadcnui.json +++ b/apps/docs/public/r/native-user-card-shadcnui.json @@ -3,7 +3,7 @@ "name": "native-user-card-shadcnui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations.", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations", "dependencies": [ "framer-motion", "react" diff --git a/apps/docs/public/r/registry.json b/apps/docs/public/r/registry.json index 59e776e..e48a1ee 100644 --- a/apps/docs/public/r/registry.json +++ b/apps/docs/public/r/registry.json @@ -1315,7 +1315,7 @@ ], "files": [ { - "path": "@uitripled/react-baseui/src/components/components/stocks-dashboard/dashboard.tsx", + "path": "@uitripled/react-baseui/src/components/stocks-dashboard/dashboard-baseui.tsx", "type": "registry:block", "target": "components/uitripled/dashboard-baseui.tsx" } @@ -1900,6 +1900,46 @@ "category": "components", "subcategory": "modal" }, + { + "name": "folder-animation", + "type": "registry:ui", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:ui", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "decorative", + "subcategory": null + }, + { + "name": "folder-animation-carbon", + "type": "registry:component", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:component", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "native", + "subcategory": null + }, { "name": "footer-block-baseui", "type": "registry:block", @@ -3652,7 +3692,7 @@ ], "files": [ { - "path": "@uitripled/react-baseui/src/components/native/native-flip-text-baseui.tsx", + "path": "@uitripled/react-carbon/src/components/native/native-flip-text-carbon-baseui.tsx", "type": "registry:component", "target": "components/uitripled/native-flip-text-baseui.tsx" } @@ -4472,7 +4512,7 @@ "name": "native-user-card-baseui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations. (Base UI)", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI)", "registryDependencies": [ "button" ], @@ -4487,14 +4527,14 @@ "target": "components/uitripled/native-user-card-baseui.tsx" } ], - "category": "native", + "category": "cards", "subcategory": null }, { "name": "native-user-card-shadcnui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations.", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations", "registryDependencies": [], "dependencies": [ "framer-motion", @@ -4507,7 +4547,7 @@ "target": "components/uitripled/native-user-card-shadcnui.tsx" } ], - "category": "native", + "category": "cards", "subcategory": null }, { diff --git a/apps/docs/registry.json b/apps/docs/registry.json index 59e776e..63b4ffc 100644 --- a/apps/docs/registry.json +++ b/apps/docs/registry.json @@ -1315,7 +1315,7 @@ ], "files": [ { - "path": "@uitripled/react-baseui/src/components/components/stocks-dashboard/dashboard.tsx", + "path": "@uitripled/react-baseui/src/components/stocks-dashboard/dashboard-baseui.tsx", "type": "registry:block", "target": "components/uitripled/dashboard-baseui.tsx" } @@ -1900,6 +1900,46 @@ "category": "components", "subcategory": "modal" }, + { + "name": "folder-animation", + "type": "registry:ui", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:ui", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "decorative", + "subcategory": null + }, + { + "name": "folder-animation-carbon", + "type": "registry:component", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:component", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "native", + "subcategory": null + }, { "name": "footer-block-baseui", "type": "registry:block", @@ -4472,7 +4512,7 @@ "name": "native-user-card-baseui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations. (Base UI)", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI)", "registryDependencies": [ "button" ], @@ -4487,14 +4527,14 @@ "target": "components/uitripled/native-user-card-baseui.tsx" } ], - "category": "native", + "category": "cards", "subcategory": null }, { "name": "native-user-card-shadcnui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations.", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations", "registryDependencies": [], "dependencies": [ "framer-motion", @@ -4507,7 +4547,7 @@ "target": "components/uitripled/native-user-card-shadcnui.tsx" } ], - "category": "native", + "category": "cards", "subcategory": null }, { diff --git a/apps/docs/scripts/sync-registry.js b/apps/docs/scripts/sync-registry.js index 3587ddc..14b3f99 100644 --- a/apps/docs/scripts/sync-registry.js +++ b/apps/docs/scripts/sync-registry.js @@ -1,25 +1,37 @@ const fs = require("fs"); const path = require("path"); +const { execSync } = require("child_process"); +const ROOT_DIR = path.join(__dirname, "../../.."); const SOURCE_REGISTRY_PATH = path.join( - __dirname, - "../../../packages/registry/registry.json" + ROOT_DIR, + "packages/registry/registry.json" ); const DEST_REGISTRY_PATH = path.join(__dirname, "../registry.json"); +function generateRegistry() { + try { + execSync("pnpm registry:generate", { + cwd: ROOT_DIR, + stdio: "inherit", + }); + } catch (error) { + console.error("❌ Failed to generate registry files:", error); + } +} + function syncRegistry() { try { console.log("🔄 Syncing registry.json from packages/registry..."); + generateRegistry(); if (!fs.existsSync(SOURCE_REGISTRY_PATH)) { console.error( `❌ Source registry file not found at: ${SOURCE_REGISTRY_PATH}` ); console.log( - "⚠️ Ensure you have run 'pnpm registry:generate' or built the registry package." + "⚠️ Ensure you have run 'pnpm registry:generate' from the repo root." ); - // Do not exit with error to avoid crashing dev server if race condition, - // but warn heavily. User might need to build registry once. return; } diff --git a/package.json b/package.json index c5591c0..0ea6794 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "dev": "turbo run dev", "lint": "turbo run lint", "type-check": "turbo run type-check", - "registry:generate": "turbo run registry:generate", - "registry:sync": "turbo run registry:sync", - "registry:validate": "turbo run registry:validate", + "registry:generate": "pnpm dlx tsx packages/scripts/src/sync-registry.ts && pnpm dlx tsx packages/scripts/src/generate-registry-files.ts", + "registry:sync": "node apps/docs/scripts/sync-registry.js", + "registry:validate": "pnpm dlx tsx packages/scripts/src/validate-registry.ts", "changeset": "changeset", "version-packages": "changeset version", "release": "turbo run build --filter=@uitripled/* && changeset publish" diff --git a/packages/components/react-carbon/src/components/native/demo/folder-animation-demo.tsx b/packages/components/react-carbon/src/components/native/demo/folder-animation-demo.tsx new file mode 100644 index 0000000..d851175 --- /dev/null +++ b/packages/components/react-carbon/src/components/native/demo/folder-animation-demo.tsx @@ -0,0 +1,163 @@ +"use client"; + +import { Button } from "@uitripled/react-shadcn/ui/button"; +import { FileText, Folder, Image, Music } from "lucide-react"; +import { FolderAnimation } from "../folder-animation-carbon"; + +const RESPONSIVE_WIDTH = "w-full max-w-md"; + +export function FolderAnimationDefault() { + return ( + +
+

Organizing Your Files

+

+ Watch as files seamlessly move through your workspace with smooth + motion blur effects. +

+
+
+ ); +} + +export function FolderAnimationFast() { + return ( + +
+

Quick Transfer

+

+ Faster animation for quick file operations. +

+
+
+ ); +} + +export function FolderAnimationSlow() { + return ( + +
+

Careful Handling

+

+ Slower animation for detailed file processing. +

+
+
+ ); +} + +export function FolderAnimationCustomIcon() { + return ( + +
+ +
+
+ } + > +
+

Document Processing

+

+ Custom icon for document-specific operations. +

+
+ + ); +} + +export function FolderAnimationImageIcon() { + return ( + +
+ +
+
+
+ } + > +
+

Image Gallery

+

+ Organizing your photos with style. +

+
+
+ ); +} + +export function FolderAnimationMusicIcon() { + return ( + +
+ +
+
+ } + animationDuration={3} + > +
+

Music Library

+

+ Your audio files in motion. +

+
+ + ); +} + +export function FolderAnimationWithActions() { + return ( + +
+
+
+ +
+
+

File Transfer in Progress

+

+ Moving 24 files to destination +

+
+
+
+ +
+
+
+ ); +} + +export function FolderAnimationNoFooter() { + return ; +} + +export function FolderAnimationDemo() { + return ( +
+
+

Default

+ +
+
+

Custom Icon

+ +
+
+

With Actions

+ +
+
+ ); +} diff --git a/packages/components/react-carbon/src/components/native/folder-animation-carbon.tsx b/packages/components/react-carbon/src/components/native/folder-animation-carbon.tsx new file mode 100644 index 0000000..bb88c70 --- /dev/null +++ b/packages/components/react-carbon/src/components/native/folder-animation-carbon.tsx @@ -0,0 +1,226 @@ +"use client"; + +import { cn } from "@uitripled/utils"; +import { + motion, + useAnimationControls, + useReducedMotion, +} from "framer-motion"; +import { type ReactNode, useState, useCallback, useEffect, useRef } from "react"; + +interface FolderAnimationProps { + /** + * Duration of the animation cycle in seconds. + * Default: 3 + */ + animationDuration?: number; + /** + * Custom folder icon to display. If not provided, a default folder icon is rendered. + */ + folderIcon?: ReactNode; + /** + * Content to display in the card footer. + */ + children?: ReactNode; + /** + * Additional CSS classes for the container. + */ + className?: string; + /** + * Accessible label for the animation area. + */ + ariaLabel?: string; +} + +export function FolderAnimation({ + animationDuration = 3, + folderIcon, + children, + className, + ariaLabel = "Animated folder illustration", +}: FolderAnimationProps) { + const [isHovered, setIsHovered] = useState(false); + const prefersReducedMotion = useReducedMotion(); + const controls = useAnimationControls(); + const blurControls = useAnimationControls(); + const isAnimatingRef = useRef(false); + const shouldStopRef = useRef(false); + + const handleMouseEnter = useCallback(() => setIsHovered(true), []); + const handleMouseLeave = useCallback(() => setIsHovered(false), []); + const handleFocus = useCallback(() => setIsHovered(true), []); + const handleBlur = useCallback(() => setIsHovered(false), []); + + // Animation sequence: center → right → (wrap to left) → center → repeat + const runAnimation = useCallback(async () => { + if (prefersReducedMotion) return; + + isAnimatingRef.current = true; + shouldStopRef.current = false; + + while (!shouldStopRef.current) { + // Phase 1: Center to right (exit right with blur) + await Promise.all([ + controls.start({ + x: "150%", + opacity: [1, 1, 0], + transition: { + duration: animationDuration / 2, + ease: "easeIn", + times: [0, 0.7, 1], + }, + }), + blurControls.start({ + filter: ["blur(0px)", "blur(0px)", "blur(8px)", "blur(16px)"], + transition: { + duration: animationDuration / 2, + ease: "easeIn", + times: [0, 0.5, 0.75, 1], + }, + }), + ]); + + if (shouldStopRef.current) break; + + // Instantly move to left (off-screen) + await controls.set({ x: "-150%", opacity: 0 }); + await blurControls.set({ filter: "blur(16px)" }); + + if (shouldStopRef.current) break; + + // Phase 2: Left to center (enter from left, deblur) + await Promise.all([ + controls.start({ + x: "0%", + opacity: [0, 1, 1], + transition: { + duration: animationDuration / 2, + ease: "easeOut", + times: [0, 0.3, 1], + }, + }), + blurControls.start({ + filter: ["blur(16px)", "blur(8px)", "blur(0px)", "blur(0px)"], + transition: { + duration: animationDuration / 2, + ease: "easeOut", + times: [0, 0.25, 0.5, 1], + }, + }), + ]); + + if (shouldStopRef.current) break; + + // Brief pause at center + await new Promise((resolve) => setTimeout(resolve, 400)); + } + + isAnimatingRef.current = false; + }, [controls, blurControls, animationDuration, prefersReducedMotion]); + + // Return to center smoothly + const returnToCenter = useCallback(async () => { + shouldStopRef.current = true; + + await Promise.all([ + controls.start({ + x: "0%", + opacity: 1, + transition: { + duration: 0.5, + ease: [0.25, 0.1, 0.25, 1], // cubic-bezier for smooth deceleration + }, + }), + blurControls.start({ + filter: "blur(0px)", + transition: { + duration: 0.3, + ease: "easeOut", + }, + }), + ]); + + isAnimatingRef.current = false; + }, [controls, blurControls]); + + useEffect(() => { + if (isHovered && !prefersReducedMotion) { + runAnimation(); + } else { + returnToCenter(); + } + }, [isHovered, prefersReducedMotion, runAnimation, returnToCenter]); + + // Set initial position + useEffect(() => { + controls.set({ x: "0%", opacity: 1 }); + blurControls.set({ filter: "blur(0px)" }); + }, [controls, blurControls]); + + return ( +
+ {/* Card Container */} +
+ {/* Animation Area */} +
+ {/* Animated Icon/Folder */} + + + {folderIcon ? ( +
{folderIcon}
+ ) : ( +
+ {/* Folder Back */} +
+ {/* Tab */} +
+ + {/* Files inside */} +
+
+
+
+
+ +
+
+
+
+
+
+
+
+ + {/* Folder Front */} +
+
+
+
+ )} + + +
+ + {/* Card Footer */} + {children &&
{children}
} +
+
+ ); +} diff --git a/packages/registry/public/r/contact-block-baseui.json b/packages/registry/public/r/contact-block-baseui.json index 26e99ef..9e6b3c3 100644 --- a/packages/registry/public/r/contact-block-baseui.json +++ b/packages/registry/public/r/contact-block-baseui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-baseui/src/components/sections/contact-block-baseui.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@base-ui/react/button\";\nimport { Input } from \"@base-ui/react/input\";\nimport { motion } from \"framer-motion\";\nimport { Mail, MapPin, Phone, Send } from \"lucide-react\";\n\nconst contactInfo = [\n {\n icon: Mail,\n label: \"Email\",\n value: \"hello@example.com\",\n href: \"mailto:hello@example.com\",\n },\n {\n icon: Phone,\n label: \"Phone\",\n value: \"+1 (555) 123-4567\",\n href: \"tel:+15551234567\",\n },\n {\n icon: MapPin,\n label: \"Location\",\n value: \"San Francisco, CA\",\n href: \"#\",\n },\n];\n\nexport function ContactBlockBaseui() {\n return (\n
\n
\n \n

\n Get In Touch\n

\n

\n Have a project in mind? Let's discuss how we can work together\n

\n \n\n
\n {/* Contact Form */}\n \n
\n
\n
\n \n Name\n \n \n
\n\n
\n \n Email\n \n \n
\n\n
\n \n Subject\n \n \n
\n\n
\n \n Message\n \n \n
\n\n \n Send Message\n \n \n \n
\n \n\n {/* Contact Info */}\n \n {contactInfo.map((info, index) => (\n \n \n \n ))}\n\n
\n

\n Working Hours\n

\n
\n
\n Monday - Friday\n 9:00 AM - 6:00 PM\n
\n
\n Saturday\n 10:00 AM - 4:00 PM\n
\n
\n Sunday\n Closed\n
\n
\n
\n \n
\n
\n
\n );\n}\n", + "content": "\"use client\";\n\nimport { Button } from \"@base-ui/react/button\";\nimport { Input } from \"@base-ui/react/input\";\nimport { motion } from \"framer-motion\";\nimport { Mail, MapPin, Phone, Send } from \"lucide-react\";\n\nconst contactInfo = [\n {\n icon: Mail,\n label: \"Email\",\n value: \"hello@example.com\",\n href: \"mailto:hello@example.com\",\n },\n {\n icon: Phone,\n label: \"Phone\",\n value: \"+1 (555) 123-4567\",\n href: \"tel:+15551234567\",\n },\n {\n icon: MapPin,\n label: \"Location\",\n value: \"San Francisco, CA\",\n href: \"#\",\n },\n];\n\nexport function ContactBlockBaseui() {\n return (\n
\n {/* Background Pattern */}\n
\n\n
\n \n

\n Get In Touch\n

\n

\n Have a project in mind? Let's discuss how we can work together\n

\n \n\n
\n {/* Contact Form */}\n \n
\n
\n
\n
\n
\n \n Name\n \n \n
\n
\n \n Email\n \n \n
\n
\n\n
\n \n Subject\n \n \n
\n\n
\n \n Message\n \n \n
\n\n \n Send Message\n \n \n \n
\n \n\n {/* Contact Info */}\n
\n
\n {contactInfo.map((info, index) => (\n \n
\n
\n \n
\n \n
\n
\n

\n {info.label}\n

\n

\n {info.value}\n

\n
\n \n
\n \n ))}\n
\n\n \n
\n

\n Working Hours\n

\n
\n
\n Monday - Friday\n \n 9:00 AM - 6:00 PM\n \n
\n
\n Saturday\n \n 10:00 AM - 4:00 PM\n \n
\n
\n Sunday\n Closed\n
\n
\n
\n \n
\n
\n
\n
\n );\n}\n", "type": "registry:block", "target": "components/uitripled/contact-block-baseui.tsx" } diff --git a/packages/registry/public/r/contact-block-shadcnui.json b/packages/registry/public/r/contact-block-shadcnui.json index 7de5277..40c46f4 100644 --- a/packages/registry/public/r/contact-block-shadcnui.json +++ b/packages/registry/public/r/contact-block-shadcnui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-shadcn/src/components/sections/contact-block.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { motion } from \"framer-motion\";\nimport { Mail, MapPin, Phone, Send } from \"lucide-react\";\n\nconst contactInfo = [\n {\n icon: Mail,\n label: \"Email\",\n value: \"hello@example.com\",\n href: \"mailto:hello@example.com\",\n },\n {\n icon: Phone,\n label: \"Phone\",\n value: \"+1 (555) 123-4567\",\n href: \"tel:+15551234567\",\n },\n {\n icon: MapPin,\n label: \"Location\",\n value: \"San Francisco, CA\",\n href: \"#\",\n },\n];\n\nexport function ContactBlock() {\n return (\n
\n
\n \n

\n Get In Touch\n

\n

\n Have a project in mind? Let's discuss how we can work together\n

\n \n\n
\n {/* Contact Form */}\n \n \n
\n
\n \n \n
\n\n
\n \n \n
\n\n
\n \n \n
\n\n
\n \n \n
\n\n \n
\n
\n \n\n {/* Contact Info */}\n \n {contactInfo.map((info, index) => (\n \n \n \n \n \n \n
\n

\n {info.label}\n

\n

{info.value}

\n
\n
\n
\n \n ))}\n\n \n

\n Working Hours\n

\n
\n
\n Monday - Friday\n 9:00 AM - 6:00 PM\n
\n
\n Saturday\n 10:00 AM - 4:00 PM\n
\n
\n Sunday\n Closed\n
\n
\n
\n \n
\n
\n
\n );\n}\n", + "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { motion } from \"framer-motion\";\nimport { Mail, MapPin, Phone, Send } from \"lucide-react\";\n\nconst contactInfo = [\n {\n icon: Mail,\n label: \"Email\",\n value: \"hello@example.com\",\n href: \"mailto:hello@example.com\",\n },\n {\n icon: Phone,\n label: \"Phone\",\n value: \"+1 (555) 123-4567\",\n href: \"tel:+15551234567\",\n },\n {\n icon: MapPin,\n label: \"Location\",\n value: \"San Francisco, CA\",\n href: \"#\",\n },\n];\n\nexport function ContactBlock() {\n return (\n
\n {/* Background Pattern */}\n
\n\n
\n \n

\n Get In Touch\n

\n

\n Have a project in mind? Let's discuss how we can work together\n

\n \n\n
\n {/* Contact Form */}\n \n \n
\n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n\n
\n \n \n
\n\n
\n \n \n
\n\n \n
\n \n \n\n {/* Contact Info */}\n
\n
\n {contactInfo.map((info, index) => (\n \n \n
\n \n
\n \n
\n
\n

\n {info.label}\n

\n

\n {info.value}\n

\n
\n \n \n \n ))}\n
\n\n \n \n

\n Working Hours\n

\n
\n
\n Monday - Friday\n \n 9:00 AM - 6:00 PM\n \n
\n
\n Saturday\n \n 10:00 AM - 4:00 PM\n \n
\n
\n Sunday\n Closed\n
\n
\n
\n \n
\n
\n
\n
\n );\n}\n", "type": "registry:block", "target": "components/uitripled/contact-block-shadcnui.tsx" } diff --git a/packages/registry/public/r/cta-banner-section-baseui.json b/packages/registry/public/r/cta-banner-section-baseui.json index b4fd804..dc90f47 100644 --- a/packages/registry/public/r/cta-banner-section-baseui.json +++ b/packages/registry/public/r/cta-banner-section-baseui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-baseui/src/components/sections/cta-banner-section-baseui.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@base-ui/react/button\";\nimport {\n motion,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { ArrowRight, Sparkles } from \"lucide-react\";\nimport { useId, useMemo, useRef } from \"react\";\n\nconst highlights = [\n { id: \"highlight-free\", label: \"Free Forever\", tone: \"bg-emerald-400\" },\n { id: \"highlight-credit\", label: \"No Credit Card\", tone: \"bg-sky-400\" },\n { id: \"highlight-oss\", label: \"Open Source\", tone: \"bg-slate-400\" },\n];\n\nexport function CTABannerSectionBaseui() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-10% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n\n const titleId = useId();\n const descriptionId = useMemo(() => `${titleId}-description`, [titleId]);\n\n const containerVariants: Variants = useMemo(\n () => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 16,\n },\n visible: {\n opacity: 1,\n y: 0,\n transition: shouldReduceMotion\n ? { duration: 0 }\n : {\n duration: 0.6,\n ease: \"easeOut\",\n staggerChildren: 0.18,\n delayChildren: 0.12,\n },\n },\n }),\n [shouldReduceMotion]\n );\n\n const itemVariants: Variants = useMemo(\n () => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 24,\n filter: shouldReduceMotion ? \"none\" : \"blur(4px)\",\n },\n visible: {\n opacity: 1,\n y: 0,\n filter: \"none\",\n transition: shouldReduceMotion\n ? { duration: 0 }\n : { type: \"spring\", stiffness: 120, damping: 18, mass: 0.9 },\n },\n }),\n [shouldReduceMotion]\n );\n\n const arrowAnimation = shouldReduceMotion\n ? {}\n : {\n animate: { x: [0, 5, 0] },\n transition: { duration: 1.6, repeat: Infinity, ease: \"easeInOut\" },\n };\n\n return (\n \n
\n \n
\n
\n \n \n
\n
\n \n \n \n \n Build fluid, glassmorphic product experiences\n \n\n \n \n Ready to ship motion-rich UIs in minutes?\n \n \n Access a curated library of glassmorphic components,\n production-grade motion recipes, and accessibility-first\n patterns. Start building products that feel alive without\n sacrificing performance.\n

\n
\n\n \n \n \n \n\n \n {highlights.map((item, index) => (\n
  • \n \n {item.label}\n
  • \n ))}\n \n\n \n Trusted by teams shipping dashboards, finance tools, and modern\n SaaS experiences.\n \n
    \n
    \n \n
    \n \n );\n}\n", + "content": "\"use client\";\n\nimport { Button } from \"@base-ui/react/button\";\nimport {\n AnimatePresence,\n motion,\n MotionConfig,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { ArrowRight, ChevronRight, Sparkles, Zap } from \"lucide-react\";\nimport { useId, useMemo, useRef, useState } from \"react\";\n\nconst motionPresets = {\n smooth: { type: \"spring\" as const, bounce: 0.3, duration: 0.4 },\n bounce: { type: \"spring\" as const, bounce: 0.5, duration: 0.35 },\n fade: { type: \"tween\" as const, ease: [0.26, 0.08, 0.25, 1] as const, duration: 0.2 },\n};\n\nconst highlights = [\n { id: \"highlight-free\", label: \"Free Forever\", icon: Zap },\n { id: \"highlight-credit\", label: \"No Credit Card\", icon: Sparkles },\n { id: \"highlight-oss\", label: \"Open Source\", icon: ChevronRight },\n];\n\ninterface CTABannerSectionBaseuiProps {\n motionPreset?: keyof typeof motionPresets;\n className?: string;\n}\n\nexport function CTABannerSectionBaseui({\n motionPreset = \"smooth\",\n className = \"\",\n}: CTABannerSectionBaseuiProps) {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-10% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n const [hoveredButton, setHoveredButton] = useState<\"primary\" | \"secondary\" | null>(null);\n\n const titleId = useId();\n const descriptionId = useMemo(() => `${titleId}-description`, [titleId]);\n\n const reducedMotionVariants: Variants = {\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n };\n\n const containerVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n },\n [shouldReduceMotion]\n );\n\n const itemVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.4 },\n },\n },\n [shouldReduceMotion]\n );\n\n // Button micro-interaction variants\n const buttonVariants: Variants = {\n idle: { y: 0 },\n hover: { y: -4 },\n tap: { y: 0, scale: 0.98 },\n };\n\n return (\n \n \n
    \n \n {/* Main CTA Card - Dashboard style */}\n \n {/* Hover gradient overlay - dashboard pattern */}\n
    \n\n
    \n {/* Status Badge - Dashboard style with live indicator */}\n \n \n \n Ready to Ship\n \n \n\n {/* Heading - Vercel style typography */}\n \n \n Ready to ship motion-rich UIs in minutes?\n \n \n Access a curated library of glassmorphic components,\n production-grade motion recipes, and accessibility-first\n patterns. Start building products that feel alive.\n

    \n
    \n\n {/* CTA Buttons - Dashboard toolbar style */}\n \n setHoveredButton(\"primary\")}\n onHoverEnd={() => setHoveredButton(null)}\n transition={{ duration: 0.2 }}\n className=\"w-full sm:w-auto\"\n >\n \n \n\n \n \n \n \n
    \n \n\n {/* Feature highlights - Dashboard metric cards style */}\n \n \n {highlights.map((item, index) => {\n const Icon = item.icon;\n return (\n \n {/* Hover gradient */}\n
    \n\n
    \n
    \n \n
    \n
    \n

    \n {item.label}\n

    \n

    \n No strings attached\n

    \n
    \n
    \n \n );\n })}\n \n \n\n {/* Trust statement - Vercel subtle footer */}\n \n Trusted by teams shipping dashboards, finance tools, and modern SaaS\n \n \n
    \n \n \n );\n}\n\n", "type": "registry:page", "target": "components/uitripled/cta-banner-section-baseui.tsx" } diff --git a/packages/registry/public/r/cta-banner-section-shadcnui.json b/packages/registry/public/r/cta-banner-section-shadcnui.json index 58a95f5..b4f7301 100644 --- a/packages/registry/public/r/cta-banner-section-shadcnui.json +++ b/packages/registry/public/r/cta-banner-section-shadcnui.json @@ -11,7 +11,7 @@ "files": [ { "path": "@uitripled/react-shadcn/src/components/sections/cta-banner-section.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport {\n motion,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { ArrowRight, Sparkles } from \"lucide-react\";\nimport { useId, useMemo, useRef } from \"react\";\n\nconst highlights = [\n { id: \"highlight-free\", label: \"Free Forever\", tone: \"bg-emerald-400\" },\n { id: \"highlight-credit\", label: \"No Credit Card\", tone: \"bg-sky-400\" },\n { id: \"highlight-oss\", label: \"Open Source\", tone: \"bg-slate-400\" },\n];\n\nexport function CTABannerSection() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-10% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n\n const titleId = useId();\n const descriptionId = useMemo(() => `${titleId}-description`, [titleId]);\n\n const containerVariants: Variants = useMemo(\n () => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 16,\n },\n visible: {\n opacity: 1,\n y: 0,\n transition: shouldReduceMotion\n ? { duration: 0 }\n : {\n duration: 0.6,\n ease: \"easeOut\",\n staggerChildren: 0.18,\n delayChildren: 0.12,\n },\n },\n }),\n [shouldReduceMotion]\n );\n\n const itemVariants: Variants = useMemo(\n () => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 24,\n filter: shouldReduceMotion ? \"none\" : \"blur(4px)\",\n },\n visible: {\n opacity: 1,\n y: 0,\n filter: \"none\",\n transition: shouldReduceMotion\n ? { duration: 0 }\n : { type: \"spring\", stiffness: 120, damping: 18, mass: 0.9 },\n },\n }),\n [shouldReduceMotion]\n );\n\n const arrowAnimation = shouldReduceMotion\n ? {}\n : {\n animate: { x: [0, 5, 0] },\n transition: { duration: 1.6, repeat: Infinity, ease: \"easeInOut\" },\n };\n\n return (\n \n
    \n \n \n
    \n \n \n
    \n \n \n \n \n \n Build fluid, glassmorphic product experiences\n \n\n \n \n Ready to ship motion-rich UIs in minutes?\n \n \n Access a curated library of glassmorphic components,\n production-grade motion recipes, and accessibility-first\n patterns. Start building products that feel alive without\n sacrificing performance.\n

    \n
    \n\n \n \n Get Started\n \n \n \n \n \n View Documentation\n \n \n\n \n {highlights.map((item, index) => (\n
  • \n \n {item.label}\n
  • \n ))}\n \n\n \n Trusted by teams shipping dashboards, finance tools, and modern\n SaaS experiences.\n \n
    \n
    \n \n
    \n \n );\n}\n", + "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n AnimatePresence,\n motion,\n MotionConfig,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { ArrowRight, ChevronRight, Sparkles, Zap } from \"lucide-react\";\nimport { useId, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst motionPresets = {\n smooth: { type: \"spring\" as const, bounce: 0.3, duration: 0.4 },\n bounce: { type: \"spring\" as const, bounce: 0.5, duration: 0.35 },\n fade: { type: \"tween\" as const, ease: [0.26, 0.08, 0.25, 1] as const, duration: 0.2 },\n};\n\n\nconst highlights = [\n { id: \"highlight-free\", label: \"Free Forever\", icon: Zap },\n { id: \"highlight-credit\", label: \"No Credit Card\", icon: Sparkles },\n { id: \"highlight-oss\", label: \"Open Source\", icon: ChevronRight },\n];\n\ninterface CTABannerSectionProps {\n motionPreset?: keyof typeof motionPresets;\n className?: string;\n}\n\nexport function CTABannerSection({\n motionPreset = \"smooth\",\n className,\n}: CTABannerSectionProps) {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-10% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n const [hoveredButton, setHoveredButton] = useState<\"primary\" | \"secondary\" | null>(null);\n\n const titleId = useId();\n const descriptionId = useMemo(() => `${titleId}-description`, [titleId]);\n\n const reducedMotionVariants: Variants = {\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n };\n\n const containerVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n },\n [shouldReduceMotion]\n );\n\n const itemVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.4 },\n },\n },\n [shouldReduceMotion]\n );\n\n // Button micro-interaction variants\n const buttonVariants: Variants = {\n idle: { y: 0 },\n hover: { y: -4 },\n tap: { y: 0, scale: 0.98 },\n };\n\n return (\n \n \n\n
    \n \n {/* Main CTA Card - Dashboard style */}\n \n {/* Hover gradient overlay - dashboard pattern */}\n
    \n\n
    \n {/* Status Badge - Dashboard style with live indicator */}\n \n \n \n Ready to Ship\n \n \n\n {/* Heading - Vercel style typography */}\n \n \n Ready to ship motion-rich UIs in minutes?\n \n \n Access a curated library of glassmorphic components,\n production-grade motion recipes, and accessibility-first\n patterns. Start building products that feel alive.\n

    \n
    \n\n {/* CTA Buttons - Dashboard toolbar style */}\n \n setHoveredButton(\"primary\")}\n onHoverEnd={() => setHoveredButton(null)}\n transition={{ duration: 0.2 }}\n className=\"w-full sm:w-auto\"\n >\n \n \n Get Started\n \n \n \n \n \n \n\n \n \n \n View Docs\n \n \n \n \n
    \n \n\n {/* Feature highlights - Dashboard metric cards style */}\n \n \n {highlights.map((item, index) => {\n const Icon = item.icon;\n return (\n \n {/* Hover gradient */}\n
    \n\n
    \n
    \n \n
    \n
    \n

    \n {item.label}\n

    \n

    \n No strings attached\n

    \n
    \n
    \n \n );\n })}\n \n \n\n {/* Trust statement - Vercel subtle footer */}\n \n Trusted by teams shipping dashboards, finance tools, and modern SaaS\n \n \n
    \n \n \n );\n}\n", "type": "registry:page", "target": "components/uitripled/cta-banner-section-shadcnui.tsx" } diff --git a/packages/registry/public/r/feature-grid-section-baseui.json b/packages/registry/public/r/feature-grid-section-baseui.json index fc54554..9e001ae 100644 --- a/packages/registry/public/r/feature-grid-section-baseui.json +++ b/packages/registry/public/r/feature-grid-section-baseui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-baseui/src/components/sections/feature-grid-section-baseui.tsx", - "content": "\"use client\";\n\nimport { motion, useInView, type Variants } from \"framer-motion\";\nimport { Code, Globe, Lock, Shield, Sparkles, Zap } from \"lucide-react\";\nimport { useRef } from \"react\";\n\nconst features = [\n {\n icon: Code,\n title: \"Developer Friendly\",\n description: \"Built with TypeScript and modern React patterns\",\n },\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description: \"Optimized animations that never lag\",\n },\n {\n icon: Shield,\n title: \"Production Ready\",\n description: \"Tested and ready for your next project\",\n },\n {\n icon: Globe,\n title: \"Responsive\",\n description: \"Works perfectly on all devices\",\n },\n {\n icon: Lock,\n title: \"Secure\",\n description: \"Built with security best practices\",\n },\n {\n icon: Sparkles,\n title: \"Modern\",\n description: \"Using the latest web technologies\",\n },\n];\n\nexport function FeatureGridSectionBaseui() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-50px\" });\n\n const containerVariants: Variants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n };\n\n const itemVariants: Variants = {\n hidden: { opacity: 0, y: 30, scale: 0.9 },\n visible: {\n opacity: 1,\n y: 0,\n scale: 1,\n transition: {\n type: \"spring\",\n stiffness: 100,\n damping: 15,\n },\n },\n };\n\n return (\n
    \n
    \n \n

    \n Why Choose Us\n

    \n

    \n Everything you need to build amazing applications\n

    \n \n\n \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n
    \n
    \n \n \n \n

    \n {feature.title}\n

    \n
    \n
    \n

    \n {feature.description}\n

    \n
    \n
    \n
    \n );\n })}\n \n
    \n
    \n );\n}\n", + "content": "\"use client\";\n\nimport { motion, useInView } from \"framer-motion\";\nimport { Code, Globe, Lock, Shield, Sparkles, Zap } from \"lucide-react\";\nimport { useRef } from \"react\";\n\nconst features = [\n {\n icon: Code,\n title: \"Developer Friendly\",\n description: \"Built with TypeScript and modern React patterns for a superior developer experience.\",\n },\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description: \"Optimized animations and code splitting that ensures your app never lags.\",\n },\n {\n icon: Shield,\n title: \"Production Ready\",\n description: \"Fully tested components that are ready for your next big project launch.\",\n },\n {\n icon: Globe,\n title: \"Responsive\",\n description: \"Layouts that adapt perfectly to any screen size, from mobile to desktop.\",\n },\n {\n icon: Lock,\n title: \"Secure By Default\",\n description: \"Implementation following best security practices to keep your data safe.\",\n },\n {\n icon: Sparkles,\n title: \"Modern Design\",\n description: \"Crafted with the latest web technologies and aesthetic trends in mind.\",\n },\n];\n\nexport function FeatureGridSectionBaseui() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-100px\" });\n\n return (\n \n {/* Background Pattern */}\n
    \n\n
    \n \n

    \n Why Choose Us\n

    \n

    \n Everything you need to build amazing applications, faster and better.\n

    \n \n\n
    \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n
    \n
    \n\n
    \n
    \n \n
    \n

    \n {feature.title}\n

    \n
    \n
    \n

    \n {feature.description}\n

    \n
    \n
    \n \n );\n })}\n
    \n
    \n \n );\n}\n", "type": "registry:page", "target": "components/uitripled/feature-grid-section-baseui.tsx" } diff --git a/packages/registry/public/r/feature-grid-section-shadcnui.json b/packages/registry/public/r/feature-grid-section-shadcnui.json index 73b5043..45d3216 100644 --- a/packages/registry/public/r/feature-grid-section-shadcnui.json +++ b/packages/registry/public/r/feature-grid-section-shadcnui.json @@ -11,7 +11,7 @@ "files": [ { "path": "@uitripled/react-shadcn/src/components/sections/feature-grid-section.tsx", - "content": "\"use client\";\n\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { motion, useInView, type Variants } from \"framer-motion\";\nimport { Code, Globe, Lock, Shield, Sparkles, Zap } from \"lucide-react\";\nimport { useRef } from \"react\";\n\nconst features = [\n {\n icon: Code,\n title: \"Developer Friendly\",\n description: \"Built with TypeScript and modern React patterns\",\n },\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description: \"Optimized animations that never lag\",\n },\n {\n icon: Shield,\n title: \"Production Ready\",\n description: \"Tested and ready for your next project\",\n },\n {\n icon: Globe,\n title: \"Responsive\",\n description: \"Works perfectly on all devices\",\n },\n {\n icon: Lock,\n title: \"Secure\",\n description: \"Built with security best practices\",\n },\n {\n icon: Sparkles,\n title: \"Modern\",\n description: \"Using the latest web technologies\",\n },\n];\n\nexport function FeatureGridSection() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-50px\" });\n\n const containerVariants: Variants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n };\n\n const itemVariants: Variants = {\n hidden: { opacity: 0, y: 30, scale: 0.9 },\n visible: {\n opacity: 1,\n y: 0,\n scale: 1,\n transition: {\n type: \"spring\",\n stiffness: 100,\n damping: 15,\n },\n },\n };\n\n return (\n
    \n
    \n \n

    \n Why Choose Us\n

    \n

    \n Everything you need to build amazing applications\n

    \n \n\n \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n \n \n \n \n \n {feature.title}\n \n \n \n {feature.description}\n \n \n \n \n );\n })}\n \n
    \n
    \n );\n}\n", + "content": "\"use client\";\n\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { motion, useInView } from \"framer-motion\";\nimport { Code, Globe, Lock, Shield, Sparkles, Zap } from \"lucide-react\";\nimport { useRef } from \"react\";\n\nconst features = [\n {\n icon: Code,\n title: \"Developer Friendly\",\n description: \"Built with TypeScript and modern React patterns for a superior developer experience.\",\n },\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description: \"Optimized animations and code splitting that ensures your app never lags.\",\n },\n {\n icon: Shield,\n title: \"Production Ready\",\n description: \"Fully tested components that are ready for your next big project launch.\",\n },\n {\n icon: Globe,\n title: \"Responsive\",\n description: \"Layouts that adapt perfectly to any screen size, from mobile to desktop.\",\n },\n {\n icon: Lock,\n title: \"Secure By Default\",\n description: \"Implementation following best security practices to keep your data safe.\",\n },\n {\n icon: Sparkles,\n title: \"Modern Design\",\n description: \"Crafted with the latest web technologies and aesthetic trends in mind.\",\n },\n];\n\nexport function FeatureGridSection() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-100px\" });\n\n return (\n \n
    \n \n

    \n Why Choose Us\n

    \n

    \n Everything you need to build amazing applications, faster and better.\n

    \n \n\n
    \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n \n
    \n\n \n
    \n \n
    \n \n {feature.title}\n \n
    \n \n \n {feature.description}\n \n \n \n \n );\n })}\n
    \n
    \n \n );\n}\n", "type": "registry:page", "target": "components/uitripled/feature-grid-section-shadcnui.tsx" } diff --git a/packages/registry/public/r/folder-animation-carbon.json b/packages/registry/public/r/folder-animation-carbon.json new file mode 100644 index 0000000..0e751d7 --- /dev/null +++ b/packages/registry/public/r/folder-animation-carbon.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "folder-animation-carbon", + "type": "registry:component", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n motion,\n useAnimationControls,\n useReducedMotion,\n} from \"framer-motion\";\nimport { type ReactNode, useState, useCallback, useEffect, useRef } from \"react\";\n\ninterface FolderAnimationProps {\n /**\n * Duration of the animation cycle in seconds.\n * Default: 3\n */\n animationDuration?: number;\n /**\n * Custom folder icon to display. If not provided, a default folder icon is rendered.\n */\n folderIcon?: ReactNode;\n /**\n * Content to display in the card footer.\n */\n children?: ReactNode;\n /**\n * Additional CSS classes for the container.\n */\n className?: string;\n /**\n * Accessible label for the animation area.\n */\n ariaLabel?: string;\n}\n\nexport function FolderAnimation({\n animationDuration = 3,\n folderIcon,\n children,\n className,\n ariaLabel = \"Animated folder illustration\",\n}: FolderAnimationProps) {\n const [isHovered, setIsHovered] = useState(false);\n const prefersReducedMotion = useReducedMotion();\n const controls = useAnimationControls();\n const blurControls = useAnimationControls();\n const isAnimatingRef = useRef(false);\n const shouldStopRef = useRef(false);\n\n const handleMouseEnter = useCallback(() => setIsHovered(true), []);\n const handleMouseLeave = useCallback(() => setIsHovered(false), []);\n const handleFocus = useCallback(() => setIsHovered(true), []);\n const handleBlur = useCallback(() => setIsHovered(false), []);\n\n // Animation sequence: center → right → (wrap to left) → center → repeat\n const runAnimation = useCallback(async () => {\n if (prefersReducedMotion) return;\n\n isAnimatingRef.current = true;\n shouldStopRef.current = false;\n\n while (!shouldStopRef.current) {\n // Phase 1: Center to right (exit right with blur)\n await Promise.all([\n controls.start({\n x: \"150%\",\n opacity: [1, 1, 0],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.7, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(0px)\", \"blur(0px)\", \"blur(8px)\", \"blur(16px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.5, 0.75, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Instantly move to left (off-screen)\n await controls.set({ x: \"-150%\", opacity: 0 });\n await blurControls.set({ filter: \"blur(16px)\" });\n\n if (shouldStopRef.current) break;\n\n // Phase 2: Left to center (enter from left, deblur)\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: [0, 1, 1],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.3, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(16px)\", \"blur(8px)\", \"blur(0px)\", \"blur(0px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.25, 0.5, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Brief pause at center\n await new Promise((resolve) => setTimeout(resolve, 400));\n }\n\n isAnimatingRef.current = false;\n }, [controls, blurControls, animationDuration, prefersReducedMotion]);\n\n // Return to center smoothly\n const returnToCenter = useCallback(async () => {\n shouldStopRef.current = true;\n\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: 1,\n transition: {\n duration: 0.5,\n ease: [0.25, 0.1, 0.25, 1], // cubic-bezier for smooth deceleration\n },\n }),\n blurControls.start({\n filter: \"blur(0px)\",\n transition: {\n duration: 0.3,\n ease: \"easeOut\",\n },\n }),\n ]);\n\n isAnimatingRef.current = false;\n }, [controls, blurControls]);\n\n useEffect(() => {\n if (isHovered && !prefersReducedMotion) {\n runAnimation();\n } else {\n returnToCenter();\n }\n }, [isHovered, prefersReducedMotion, runAnimation, returnToCenter]);\n\n // Set initial position\n useEffect(() => {\n controls.set({ x: \"0%\", opacity: 1 });\n blurControls.set({ filter: \"blur(0px)\" });\n }, [controls, blurControls]);\n\n return (\n
    \n {/* Card Container */}\n
    \n {/* Animation Area */}\n \n {/* Animated Icon/Folder */}\n \n \n {folderIcon ? (\n
    {folderIcon}
    \n ) : (\n
    \n {/* Folder Back */}\n
    \n {/* Tab */}\n
    \n\n {/* Files inside */}\n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n\n {/* Folder Front */}\n
    \n
    \n
    \n
    \n )}\n \n \n
    \n\n {/* Card Footer */}\n {children &&
    {children}
    }\n
    \n
    \n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/folder-animation.json b/packages/registry/public/r/folder-animation.json new file mode 100644 index 0000000..625b74a --- /dev/null +++ b/packages/registry/public/r/folder-animation.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "folder-animation", + "type": "registry:ui", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n motion,\n useAnimationControls,\n useReducedMotion,\n} from \"framer-motion\";\nimport { type ReactNode, useState, useCallback, useEffect, useRef } from \"react\";\n\ninterface FolderAnimationProps {\n /**\n * Duration of the animation cycle in seconds.\n * Default: 3\n */\n animationDuration?: number;\n /**\n * Custom folder icon to display. If not provided, a default folder icon is rendered.\n */\n folderIcon?: ReactNode;\n /**\n * Content to display in the card footer.\n */\n children?: ReactNode;\n /**\n * Additional CSS classes for the container.\n */\n className?: string;\n /**\n * Accessible label for the animation area.\n */\n ariaLabel?: string;\n}\n\nexport function FolderAnimation({\n animationDuration = 3,\n folderIcon,\n children,\n className,\n ariaLabel = \"Animated folder illustration\",\n}: FolderAnimationProps) {\n const [isHovered, setIsHovered] = useState(false);\n const prefersReducedMotion = useReducedMotion();\n const controls = useAnimationControls();\n const blurControls = useAnimationControls();\n const isAnimatingRef = useRef(false);\n const shouldStopRef = useRef(false);\n\n const handleMouseEnter = useCallback(() => setIsHovered(true), []);\n const handleMouseLeave = useCallback(() => setIsHovered(false), []);\n const handleFocus = useCallback(() => setIsHovered(true), []);\n const handleBlur = useCallback(() => setIsHovered(false), []);\n\n // Animation sequence: center → right → (wrap to left) → center → repeat\n const runAnimation = useCallback(async () => {\n if (prefersReducedMotion) return;\n\n isAnimatingRef.current = true;\n shouldStopRef.current = false;\n\n while (!shouldStopRef.current) {\n // Phase 1: Center to right (exit right with blur)\n await Promise.all([\n controls.start({\n x: \"150%\",\n opacity: [1, 1, 0],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.7, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(0px)\", \"blur(0px)\", \"blur(8px)\", \"blur(16px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeIn\",\n times: [0, 0.5, 0.75, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Instantly move to left (off-screen)\n await controls.set({ x: \"-150%\", opacity: 0 });\n await blurControls.set({ filter: \"blur(16px)\" });\n\n if (shouldStopRef.current) break;\n\n // Phase 2: Left to center (enter from left, deblur)\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: [0, 1, 1],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.3, 1],\n },\n }),\n blurControls.start({\n filter: [\"blur(16px)\", \"blur(8px)\", \"blur(0px)\", \"blur(0px)\"],\n transition: {\n duration: animationDuration / 2,\n ease: \"easeOut\",\n times: [0, 0.25, 0.5, 1],\n },\n }),\n ]);\n\n if (shouldStopRef.current) break;\n\n // Brief pause at center\n await new Promise((resolve) => setTimeout(resolve, 400));\n }\n\n isAnimatingRef.current = false;\n }, [controls, blurControls, animationDuration, prefersReducedMotion]);\n\n // Return to center smoothly\n const returnToCenter = useCallback(async () => {\n shouldStopRef.current = true;\n\n await Promise.all([\n controls.start({\n x: \"0%\",\n opacity: 1,\n transition: {\n duration: 0.5,\n ease: [0.25, 0.1, 0.25, 1], // cubic-bezier for smooth deceleration\n },\n }),\n blurControls.start({\n filter: \"blur(0px)\",\n transition: {\n duration: 0.3,\n ease: \"easeOut\",\n },\n }),\n ]);\n\n isAnimatingRef.current = false;\n }, [controls, blurControls]);\n\n useEffect(() => {\n if (isHovered && !prefersReducedMotion) {\n runAnimation();\n } else {\n returnToCenter();\n }\n }, [isHovered, prefersReducedMotion, runAnimation, returnToCenter]);\n\n // Set initial position\n useEffect(() => {\n controls.set({ x: \"0%\", opacity: 1 });\n blurControls.set({ filter: \"blur(0px)\" });\n }, [controls, blurControls]);\n\n return (\n
    \n {/* Card Container */}\n
    \n {/* Animation Area */}\n \n {/* Animated Icon/Folder */}\n \n \n {folderIcon ? (\n
    {folderIcon}
    \n ) : (\n
    \n {/* Folder Back */}\n
    \n {/* Tab */}\n
    \n\n {/* Files inside */}\n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n\n {/* Folder Front */}\n
    \n
    \n
    \n
    \n )}\n \n \n
    \n\n {/* Card Footer */}\n {children &&
    {children}
    }\n
    \n
    \n );\n}\n", + "type": "registry:ui", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-avatar-expand.json b/packages/registry/public/r/native-avatar-expand.json deleted file mode 100644 index a87ae8e..0000000 --- a/packages/registry/public/r/native-avatar-expand.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-avatar-expand", - "type": "registry:component", - "title": "Native Avatar Expand", - "description": "Avatar component that expands to reveal the name on click with smooth animations.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-avatar-expand-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { useState } from \"react\";\n\nexport interface NativeAvatarExpandProps {\n /**\n * URL of the avatar image\n */\n src?: string;\n /**\n * Name of the person or entity\n */\n name: string;\n /**\n * Size variant\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Additional classes for the container\n */\n className?: string;\n /**\n * Additional classes for the avatar\n */\n avatarClassName?: string;\n /**\n * Additional classes for the name text\n */\n nameClassName?: string;\n}\n\nconst sizeConfig = {\n sm: {\n avatar: \"h-10 w-10\",\n text: \"text-sm\",\n },\n md: {\n avatar: \"h-12 w-12\",\n text: \"text-base\",\n },\n lg: {\n avatar: \"h-16 w-16\",\n text: \"text-lg\",\n },\n xl: {\n avatar: \"h-20 w-20\",\n text: \"text-xl\",\n },\n};\n\nexport function NativeAvatarExpand({\n src,\n name,\n size = \"md\",\n className,\n avatarClassName,\n nameClassName,\n}: NativeAvatarExpandProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const { avatar, text } = sizeConfig[size];\n\n const getInitials = (name: string) => {\n return name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n };\n\n return (\n setIsExpanded(!isExpanded)}\n >\n \n \n \n {getInitials(name)}\n \n \n\n \n {isExpanded && (\n \n \n {name}\n \n \n )}\n \n \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-avatar-expand.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-avatar-with-name.json b/packages/registry/public/r/native-avatar-with-name.json deleted file mode 100644 index 8bfbeea..0000000 --- a/packages/registry/public/r/native-avatar-with-name.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-avatar-with-name", - "type": "registry:component", - "title": "Native Avatar With Name", - "description": "Avatar component that displays a name tooltip on hover with directional animations.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-avatar-with-name-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { useState } from \"react\";\n\nexport interface NativeAvatarProps {\n /**\n * URL of the avatar image\n */\n src?: string;\n /**\n * Name to display on hover\n */\n name: string;\n /**\n * Fallback text when image fails to load (usually initials)\n */\n fallback?: string;\n /**\n * Size variant of the avatar\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Direction from which the name appears\n * Default: \"bottom\"\n */\n direction?: \"top\" | \"bottom\" | \"left\" | \"right\";\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Additional class names for the name label\n */\n nameClassName?: string;\n /**\n * Additional class names for the motion container\n */\n motionClassName?: string;\n}\n\nconst sizeVariants = {\n sm: \"h-10 w-10\",\n md: \"h-14 w-14\",\n lg: \"h-20 w-20\",\n xl: \"h-28 w-28\",\n};\n\nconst nameSizeVariants = {\n sm: \"text-xs px-2 py-1\",\n md: \"text-sm px-3 py-1.5\",\n lg: \"text-base px-4 py-2\",\n xl: \"text-lg px-5 py-2.5\",\n};\n\nexport function NativeAvatarWithName({\n src,\n name,\n fallback,\n size = \"md\",\n direction = \"bottom\",\n className,\n nameClassName,\n motionClassName,\n}: NativeAvatarProps) {\n const [isHovered, setIsHovered] = useState(false);\n\n const getInitials = (name: string) => {\n return name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n };\n\n const directionVariants = {\n top: {\n initial: { y: 20, opacity: 0, filter: \"blur(4px)\" },\n animate: { y: -8, opacity: 1, filter: \"blur(0px)\" },\n exit: { y: 20, opacity: 0, filter: \"blur(4px)\" },\n },\n bottom: {\n initial: { y: -20, opacity: 0, filter: \"blur(4px)\" },\n animate: { y: 8, opacity: 1, filter: \"blur(0px)\" },\n exit: { y: -20, opacity: 0, filter: \"blur(4px)\" },\n },\n left: {\n initial: { x: 20, opacity: 0, filter: \"blur(4px)\" },\n animate: { x: -8, opacity: 1, filter: \"blur(0px)\" },\n exit: { x: 20, opacity: 0, filter: \"blur(4px)\" },\n },\n right: {\n initial: { x: -20, opacity: 0, filter: \"blur(4px)\" },\n animate: { x: 8, opacity: 1, filter: \"blur(0px)\" },\n exit: { x: -20, opacity: 0, filter: \"blur(4px)\" },\n },\n };\n\n const positionClasses = {\n top: \"bottom-full left-1/2 -translate-x-1/2 mb-2\",\n bottom: \"top-full left-1/2 -translate-x-1/2 mt-2\",\n left: \"right-full top-1/2 -translate-y-1/2 mr-2\",\n right: \"left-full top-1/2 -translate-y-1/2 ml-2\",\n };\n\n return (\n setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n \n \n \n \n {fallback || getInitials(name)}\n \n \n \n\n \n {isHovered && (\n \n {name}\n \n )}\n \n
    \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-avatar-with-name.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-badge.json b/packages/registry/public/r/native-badge.json index 850a1ac..c82830d 100644 --- a/packages/registry/public/r/native-badge.json +++ b/packages/registry/public/r/native-badge.json @@ -13,7 +13,7 @@ "path": "@uitripled/react-carbon/src/components/native/native-badge-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { HTMLMotionProps, motion } from \"framer-motion\";\nimport { Sparkles } from \"lucide-react\";\nimport React from \"react\";\n\nconst badgeVariants = cva(\n \"inline-flex items-center rounded-full px-3 py-1 text-xs font-medium transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"border border-primary/20 bg-primary/10 text-primary hover:bg-primary/20 hover:border-primary/40 hover:shadow-[0_0_10px_rgba(var(--primary),0.1)]\",\n neutral:\n \"border border-border/40 bg-card/50 text-muted-foreground backdrop-blur-sm hover:bg-card/80 hover:text-foreground hover:border-border/80\",\n outline:\n \"text-foreground border border-input bg-background/50 backdrop-blur-sm hover:bg-accent hover:text-accent-foreground\",\n glass:\n \"bg-white/10 dark:bg-black/10 backdrop-blur-md border border-white/20 dark:border-white/10 text-foreground shadow-sm hover:bg-white/20 dark:hover:bg-black/20\",\n glow: \"bg-primary/10 text-primary border border-primary/20 shadow-[0_0_10px_rgba(var(--primary),0.2)] hover:shadow-[0_0_20px_rgba(var(--primary),0.4)] hover:bg-primary/20 hover:scale-[1.02]\",\n animated:\n \"group gap-2 tracking-widest uppercase border border-border/60 bg-card/70 text-muted-foreground backdrop-blur hover:border-primary/60 hover:bg-primary/15 hover:text-primary transition-colors duration-300\",\n },\n size: {\n sm: \"text-[10px] px-2 py-0.5\",\n md: \"text-xs px-2.5 py-0.5\",\n lg: \"text-sm px-3.5 py-1\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n },\n }\n);\n\nexport interface NativeBadgeProps\n extends Omit, \"ref\" | \"children\">,\n VariantProps {\n /**\n * Whether to animate the badge on mount.\n * Default: true\n */\n animate?: boolean;\n /**\n * Optional label for the animated variant's secondary tag (e.g., \"new\", \"beta\").\n * Only applies when variant=\"animated\".\n */\n tag?: string;\n /**\n * Optional icon for the animated variant. Defaults to Sparkles.\n * Only applies when variant=\"animated\".\n */\n icon?: React.ReactNode;\n /**\n * Badge content.\n */\n children?: React.ReactNode;\n}\n\nfunction NativeBadge({\n className,\n variant,\n size,\n animate = true,\n tag = \"new\",\n icon,\n children,\n ...props\n}: NativeBadgeProps) {\n const isAnimated = variant === \"animated\";\n const IconElement = icon ?? ;\n\n return (\n \n {isAnimated && (\n \n {IconElement}\n \n )}\n {children}\n {isAnimated && tag && (\n \n {tag}\n \n )}\n \n );\n}\n\nexport { badgeVariants, NativeBadge };\n", "type": "registry:component", - "target": "components/uitripled/native-badge.tsx" + "target": "components/uitripled/native-badge-carbon.tsx" } ] } \ No newline at end of file diff --git a/packages/registry/public/r/native-button-baseui.json b/packages/registry/public/r/native-button-baseui.json index debebbf..ec5b621 100644 --- a/packages/registry/public/r/native-button-baseui.json +++ b/packages/registry/public/r/native-button-baseui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-baseui/src/components/native/native-button-baseui.tsx", - "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n Button,\n type ButtonProps as BaseButtonProps,\n} from \"@base-ui/react/button\";\nimport { motion } from \"framer-motion\";\nimport { Loader2 } from \"lucide-react\";\nimport * as React from \"react\";\nimport { ReactNode } from \"react\";\n\nexport interface NativeButtonProps extends Omit {\n children: ReactNode;\n loading?: boolean;\n glow?: boolean;\n variant?:\n | \"default\"\n | \"destructive\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"link\";\n size?: \"default\" | \"sm\" | \"lg\" | \"icon\";\n className?: string;\n href?: string;\n}\n\nconst NativeButton = React.forwardRef(\n (\n {\n className,\n variant = \"default\",\n size = \"lg\",\n children,\n loading = false,\n glow = false,\n disabled,\n ...props\n },\n ref\n ) => {\n const buttonContent = (\n <>\n {loading && }\n \n {children}\n \n \n );\n\n const variantStyles = {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n };\n\n const sizeStyles = {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3\",\n lg: \"h-11 rounded-md px-8\",\n icon: \"h-10 w-10\",\n };\n\n const glassmorphismClassName = cn(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n variantStyles[variant],\n sizeStyles[size],\n \"cursor-pointer h-12 rounded-md text-sm relative overflow-hidden\",\n !glow && \"shadow-md hover:shadow-lg\",\n glow &&\n \"shadow-lg shadow-primary/20 hover:shadow-primary/40 transition-all duration-300\",\n variant === \"outline\" && \"text-foreground/80 hover:bg-foreground/5\",\n (disabled || loading) && \"opacity-50 cursor-not-allowed grayscale\",\n className\n );\n\n // We remove the motion.div wrapper to prevent nested button issues when used in asChild.\n // Ideally we would use motion.button but we want to keep using Base UI Button.\n // For now, we sacrifice the scale tap/hover effect on the wrapper for correctness,\n // or we could use a different approach if critical.\n // The glow effect moves inside.\n\n if (props.href) {\n return (\n }\n className={glassmorphismClassName}\n aria-disabled={disabled || loading}\n {...(props as any)}\n >\n {glow && !disabled && !loading && (\n
    \n )}\n {buttonContent}\n \n );\n }\n\n return (\n \n {glow && !disabled && !loading && (\n
    \n )}\n {buttonContent}\n \n );\n }\n);\nNativeButton.displayName = \"NativeButton\";\n\nexport { NativeButton };\n", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n Button,\n type ButtonProps as BaseButtonProps,\n} from \"@base-ui/react/button\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Loader2 } from \"lucide-react\";\nimport * as React from \"react\";\nimport { ReactNode } from \"react\";\n\nexport interface NativeButtonProps extends Omit {\n children: ReactNode;\n loading?: boolean;\n glow?: boolean;\n variant?:\n | \"default\"\n | \"destructive\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"link\";\n size?: \"default\" | \"sm\" | \"lg\" | \"icon\";\n className?: string;\n href?: string;\n}\n\nconst NativeButton = React.forwardRef(\n (\n {\n className,\n variant = \"default\",\n size = \"lg\",\n children,\n loading = false,\n glow = false,\n disabled,\n ...props\n },\n ref\n ) => {\n const shouldReduceMotion = useReducedMotion();\n\n const buttonContent = (\n <>\n {loading && }\n \n {children}\n \n \n );\n\n const variantStyles = {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n };\n\n const sizeStyles = {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3\",\n lg: \"h-11 rounded-md px-8\",\n icon: \"h-10 w-10\",\n };\n\n const glassmorphismClassName = cn(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n variantStyles[variant],\n sizeStyles[size],\n \"cursor-pointer h-12 rounded-md text-sm relative overflow-hidden\",\n !glow && \"shadow-md hover:shadow-lg\",\n glow &&\n \"shadow-lg shadow-primary/20 hover:shadow-primary/40 transition-[box-shadow,background-color,color,opacity] duration-200\",\n variant === \"outline\" && \"text-foreground/80 hover:bg-foreground/5\",\n (disabled || loading) && \"opacity-50 cursor-not-allowed grayscale\",\n className\n );\n\n // We restore the motion.div wrapper to ensure parity with Shadcn version.\n // This allows for scale effects on hover and tap.\n\n if (props.href) {\n return (\n \n }\n className={glassmorphismClassName}\n aria-disabled={disabled || loading}\n {...(props as any)}\n >\n {glow && !disabled && !loading && (\n
    \n )}\n {buttonContent}\n \n \n );\n }\n\n return (\n \n \n {glow && !disabled && !loading && (\n
    \n )}\n {buttonContent}\n \n \n );\n }\n);\nNativeButton.displayName = \"NativeButton\";\n\nexport { NativeButton };\n", "type": "registry:component", "target": "components/uitripled/native-button-baseui.tsx" } diff --git a/packages/registry/public/r/native-button-shadcnui.json b/packages/registry/public/r/native-button-shadcnui.json index 80409ef..c1a452e 100644 --- a/packages/registry/public/r/native-button-shadcnui.json +++ b/packages/registry/public/r/native-button-shadcnui.json @@ -11,7 +11,7 @@ "files": [ { "path": "@uitripled/react-shadcn/src/components/native/native-button-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Button, ButtonProps } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport { Loader2 } from \"lucide-react\";\nimport { ReactNode } from \"react\";\n\nexport interface NativeButtonProps extends ButtonProps {\n children: ReactNode;\n loading?: boolean;\n glow?: boolean;\n}\n\nconst NativeButton = ({\n className,\n variant = \"default\",\n size = \"lg\",\n children,\n loading = false,\n glow = false,\n disabled,\n ...props\n}: NativeButtonProps) => {\n const buttonContent = (\n <>\n {loading && }\n \n {children}\n \n \n );\n\n const glassmorphismClassName = cn(\n \"cursor-pointer h-12 rounded-md px-7 text-sm uppercase relative overflow-hidden\",\n !glow && \"shadow-md hover:shadow-lg\",\n glow &&\n \"shadow-lg shadow-primary/20 hover:shadow-primary/40 transition-all duration-300\",\n variant === \"outline\" && \"text-foreground/80 hover:bg-foreground/5\",\n (disabled || loading) && \"opacity-50 cursor-not-allowed grayscale\",\n className\n );\n\n return (\n \n {glow && !disabled && !loading && (\n
    \n )}\n \n {buttonContent}\n \n \n );\n};\n\nexport { NativeButton };\n", + "content": "\"use client\";\n\nimport { Button, ButtonProps } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Loader2 } from \"lucide-react\";\nimport { ReactNode } from \"react\";\n\nexport interface NativeButtonProps extends ButtonProps {\n children: ReactNode;\n loading?: boolean;\n glow?: boolean;\n}\n\nconst NativeButton = ({\n className,\n variant = \"default\",\n size = \"lg\",\n children,\n loading = false,\n glow = false,\n disabled,\n ...props\n}: NativeButtonProps) => {\n const shouldReduceMotion = useReducedMotion();\n\n const buttonContent = (\n <>\n {loading && }\n \n {children}\n \n \n );\n\n const glassmorphismClassName = cn(\n \"cursor-pointer h-12 rounded-md px-7 text-sm relative overflow-hidden\",\n !glow && \"shadow-md hover:shadow-lg\",\n glow &&\n \"shadow-lg shadow-primary/20 hover:shadow-primary/40 transition-[box-shadow,background-color,color,opacity] duration-200\",\n variant === \"outline\" && \"text-foreground/80 hover:bg-foreground/5\",\n (disabled || loading) && \"opacity-50 cursor-not-allowed grayscale\",\n className\n );\n\n return (\n \n {glow && !disabled && !loading && (\n
    \n )}\n \n {buttonContent}\n \n \n );\n};\n\nNativeButton.displayName = \"NativeButton\";\n\nexport { NativeButton };\n", "type": "registry:component", "target": "components/uitripled/native-button-shadcnui.tsx" } diff --git a/packages/registry/public/r/native-button.json b/packages/registry/public/r/native-button.json deleted file mode 100644 index df96701..0000000 --- a/packages/registry/public/r/native-button.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-button", - "type": "registry:component", - "title": "Native Button", - "description": "Glassmorphism-inspired button component based on shadcn/ui with smooth animations and modern styling", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-button-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Button, ButtonProps } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport { Loader2 } from \"lucide-react\";\nimport { ReactNode } from \"react\";\n\nexport interface NativeButtonProps extends ButtonProps {\n children: ReactNode;\n loading?: boolean;\n glow?: boolean;\n}\n\nconst NativeButton = ({\n className,\n variant = \"default\",\n size = \"lg\",\n children,\n loading = false,\n glow = false,\n disabled,\n ...props\n}: NativeButtonProps) => {\n const buttonContent = (\n <>\n {loading && }\n \n {children}\n \n \n );\n\n const glassmorphismClassName = cn(\n \"cursor-pointer h-12 rounded-md px-7 text-sm uppercase relative overflow-hidden\",\n !glow && \"shadow-md hover:shadow-lg\",\n glow &&\n \"shadow-lg shadow-primary/20 hover:shadow-primary/40 transition-all duration-300\",\n variant === \"outline\" && \"text-foreground/80 hover:bg-foreground/5\",\n (disabled || loading) && \"opacity-50 cursor-not-allowed grayscale\",\n className\n );\n\n return (\n \n {glow && !disabled && !loading && (\n
    \n )}\n \n {buttonContent}\n \n \n );\n};\n\nexport { NativeButton };\n", - "type": "registry:component", - "target": "components/uitripled/native-button.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-counter-up.json b/packages/registry/public/r/native-counter-up.json index 16afdc3..97cf382 100644 --- a/packages/registry/public/r/native-counter-up.json +++ b/packages/registry/public/r/native-counter-up.json @@ -13,7 +13,7 @@ "path": "@uitripled/react-carbon/src/components/native/native-counter-up-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { animate, motion, useReducedMotion } from \"framer-motion\";\nimport { useEffect, useState } from \"react\";\n\nexport interface NativeCounterUpProps {\n /**\n * The target number to count up to.\n */\n value: number;\n /**\n * Duration of the animation in seconds.\n * Default: 2\n */\n duration?: number;\n /**\n * Text to display before the number (e.g., \"$\").\n */\n prefix?: string;\n /**\n * Text to display after the number (e.g., \"+\", \"%\").\n */\n suffix?: string;\n /**\n * Number of decimal places to show.\n * Default: 0\n */\n decimals?: number;\n /**\n * Accessible label describing what the counter represents.\n */\n label?: string;\n /**\n * Whether to start the animation on mount.\n * Default: true\n */\n autoStart?: boolean;\n className?: string;\n}\n\nexport function NativeCounterUp({\n value,\n duration = 2,\n prefix = \"\",\n suffix = \"\",\n decimals = 0,\n label,\n autoStart = true,\n className,\n}: NativeCounterUpProps) {\n const shouldReduceMotion = useReducedMotion();\n const [displayValue, setDisplayValue] = useState(0);\n\n useEffect(() => {\n if (!autoStart) return;\n\n // If reduced motion, just set the value immediately\n if (shouldReduceMotion) {\n setDisplayValue(value);\n return;\n }\n\n // Animate from current value to target value\n const controls = animate(0, value, {\n duration,\n ease: [0.16, 1, 0.3, 1], // Smooth expo-out easing\n onUpdate: (latest) => {\n setDisplayValue(\n decimals > 0 ? Number(latest.toFixed(decimals)) : Math.round(latest)\n );\n },\n });\n\n return () => controls.stop();\n }, [value, duration, autoStart, shouldReduceMotion, decimals]);\n\n const formattedValue = displayValue.toLocaleString(undefined, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n\n return (\n \n {prefix}\n {formattedValue}\n {suffix}\n {label && {label}}\n \n );\n}\n", "type": "registry:component", - "target": "components/uitripled/native-counter-up.tsx" + "target": "components/uitripled/native-counter-up-carbon.tsx" } ] } \ No newline at end of file diff --git a/packages/registry/public/r/native-delete-baseui.json b/packages/registry/public/r/native-delete-baseui.json index 1b8eefb..1b8cbbb 100644 --- a/packages/registry/public/r/native-delete-baseui.json +++ b/packages/registry/public/r/native-delete-baseui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-baseui/src/components/native/native-delete-baseui.tsx", - "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@base-ui/react/button\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { Trash2, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface NativeDeleteProps {\n /**\n * Callback when delete button is first clicked (shows confirmation)\n */\n onConfirm: () => void;\n /**\n * Callback when delete is confirmed\n */\n onDelete: () => void;\n /**\n * Text to show on the delete button\n * Default: \"Delete\"\n */\n buttonText?: string;\n /**\n * Text to show on the confirm button\n * Default: \"Confirm\"\n */\n confirmText?: string;\n /**\n * Size variant\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Show icon in button\n * Default: true\n */\n showIcon?: boolean;\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Disable the button\n */\n disabled?: boolean;\n}\n\nconst sizeVariants = {\n sm: \"h-8 text-xs px-3\",\n md: \"h-10 text-sm px-4\",\n lg: \"h-12 text-base px-6\",\n};\n\nconst iconSizeVariants = {\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n};\n\nexport function NativeDelete({\n onConfirm,\n onDelete,\n buttonText = \"Delete\",\n confirmText = \"Confirm\",\n size = \"md\",\n showIcon = true,\n className,\n disabled = false,\n}: NativeDeleteProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const handleDeleteClick = () => {\n if (!disabled) {\n setIsExpanded(true);\n onConfirm();\n }\n };\n\n const handleConfirm = () => {\n onDelete();\n setIsExpanded(false);\n };\n\n const handleCancel = () => {\n setIsExpanded(false);\n };\n\n return (\n
    \n \n \n \n {showIcon && !isExpanded && (\n \n )}\n {isExpanded ? confirmText : buttonText}\n \n \n \n\n \n {isExpanded && (\n \n \n \n \n \n \n \n )}\n \n
    \n );\n}\n", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@base-ui/react/button\";\nimport { AnimatePresence, motion, MotionConfig } from \"framer-motion\";\nimport { Check, Trash2, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface NativeDeleteProps {\n /**\n * Callback when delete button is first clicked (shows confirmation)\n */\n onConfirm: () => void;\n /**\n * Callback when delete is confirmed\n */\n onDelete: () => void;\n /**\n * Text to show on the delete button\n * Default: \"Delete\"\n */\n buttonText?: string;\n /**\n * Text to show on the confirm button\n * Default: \"Confirm\"\n */\n confirmText?: string;\n /**\n * Size variant\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Show icon in button\n * Default: true\n */\n showIcon?: boolean;\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Disable the button\n */\n disabled?: boolean;\n}\n\nconst sizeVariants = {\n sm: \"h-8 text-xs px-3\",\n md: \"h-10 text-sm px-4\",\n lg: \"h-12 text-base px-6\",\n};\n\nconst iconSizeVariants = {\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n};\n\nconst cancelButtonSizes = {\n sm: \"h-8 w-8\",\n md: \"h-10 w-10\",\n lg: \"h-12 w-12\",\n};\n\n// Smooth spring preset for natural feel\nconst smoothSpring = {\n type: \"spring\" as const,\n bounce: 0,\n duration: 0.35,\n};\n\nexport function NativeDelete({\n onConfirm,\n onDelete,\n buttonText = \"Delete\",\n confirmText = \"Confirm\",\n size = \"md\",\n showIcon = true,\n className,\n disabled = false,\n}: NativeDeleteProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const handleDeleteClick = () => {\n if (!disabled) {\n setIsExpanded(true);\n onConfirm();\n }\n };\n\n const handleConfirm = () => {\n onDelete();\n setIsExpanded(false);\n };\n\n const handleCancel = () => {\n setIsExpanded(false);\n };\n\n return (\n \n \n {/* Main Delete/Confirm button */}\n \n \n \n {showIcon && (\n \n {isExpanded ? (\n \n ) : (\n \n )}\n \n )}\n \n \n \n {isExpanded ? confirmText : buttonText}\n \n \n \n \n\n {/* Cancel button */}\n \n {isExpanded && (\n \n \n \n \n \n )}\n \n \n \n );\n}\n", "type": "registry:component", "target": "components/uitripled/native-delete-baseui.tsx" } diff --git a/packages/registry/public/r/native-delete-shadcnui.json b/packages/registry/public/r/native-delete-shadcnui.json index 9c4247b..738491d 100644 --- a/packages/registry/public/r/native-delete-shadcnui.json +++ b/packages/registry/public/r/native-delete-shadcnui.json @@ -11,7 +11,7 @@ "files": [ { "path": "@uitripled/react-shadcn/src/components/native/native-delete-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { Trash2, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface NativeDeleteProps {\n /**\n * Callback when delete button is first clicked (shows confirmation)\n */\n onConfirm: () => void;\n /**\n * Callback when delete is confirmed\n */\n onDelete: () => void;\n /**\n * Text to show on the delete button\n * Default: \"Delete\"\n */\n buttonText?: string;\n /**\n * Text to show on the confirm button\n * Default: \"Confirm\"\n */\n confirmText?: string;\n /**\n * Size variant\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Show icon in button\n * Default: true\n */\n showIcon?: boolean;\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Disable the button\n */\n disabled?: boolean;\n}\n\nconst sizeVariants = {\n sm: \"h-8 text-xs px-3\",\n md: \"h-10 text-sm px-4\",\n lg: \"h-12 text-base px-6\",\n};\n\nconst iconSizeVariants = {\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n};\n\nexport function NativeDelete({\n onConfirm,\n onDelete,\n buttonText = \"Delete\",\n confirmText = \"Confirm\",\n size = \"md\",\n showIcon = true,\n className,\n disabled = false,\n}: NativeDeleteProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const handleDeleteClick = () => {\n if (!disabled) {\n setIsExpanded(true);\n onConfirm();\n }\n };\n\n const handleConfirm = () => {\n onDelete();\n setIsExpanded(false);\n };\n\n const handleCancel = () => {\n setIsExpanded(false);\n };\n\n return (\n
    \n \n \n \n {showIcon && !isExpanded && (\n \n )}\n {isExpanded ? confirmText : buttonText}\n \n \n \n\n \n {isExpanded && (\n \n \n \n \n \n \n \n )}\n \n
    \n );\n}\n", + "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion, MotionConfig } from \"framer-motion\";\nimport { Check, Trash2, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface NativeDeleteProps {\n /**\n * Callback when delete button is first clicked (shows confirmation)\n */\n onConfirm: () => void;\n /**\n * Callback when delete is confirmed\n */\n onDelete: () => void;\n /**\n * Text to show on the delete button\n * Default: \"Delete\"\n */\n buttonText?: string;\n /**\n * Text to show on the confirm button\n * Default: \"Confirm\"\n */\n confirmText?: string;\n /**\n * Size variant\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Show icon in button\n * Default: true\n */\n showIcon?: boolean;\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Disable the button\n */\n disabled?: boolean;\n}\n\nconst sizeVariants = {\n sm: \"h-8 text-xs px-3\",\n md: \"h-10 text-sm px-4\",\n lg: \"h-12 text-base px-6\",\n};\n\nconst iconSizeVariants = {\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n};\n\nconst cancelButtonSizes = {\n sm: \"h-8 w-8\",\n md: \"h-10 w-10\",\n lg: \"h-12 w-12\",\n};\n\n// Smooth spring preset for natural feel\nconst smoothSpring = {\n type: \"spring\" as const,\n bounce: 0,\n duration: 0.35,\n};\n\nexport function NativeDelete({\n onConfirm,\n onDelete,\n buttonText = \"Delete\",\n confirmText = \"Confirm\",\n size = \"md\",\n showIcon = true,\n className,\n disabled = false,\n}: NativeDeleteProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const handleDeleteClick = () => {\n if (!disabled) {\n setIsExpanded(true);\n onConfirm();\n }\n };\n\n const handleConfirm = () => {\n onDelete();\n setIsExpanded(false);\n };\n\n const handleCancel = () => {\n setIsExpanded(false);\n };\n\n return (\n \n \n {/* Main Delete/Confirm button */}\n \n \n \n {showIcon && (\n \n {isExpanded ? (\n \n ) : (\n \n )}\n \n )}\n \n \n \n {isExpanded ? confirmText : buttonText}\n \n \n \n \n\n {/* Cancel button */}\n \n {isExpanded && (\n \n \n \n \n \n )}\n \n \n \n );\n}\n", "type": "registry:component", "target": "components/uitripled/native-delete-shadcnui.tsx" } diff --git a/packages/registry/public/r/native-delete.json b/packages/registry/public/r/native-delete.json deleted file mode 100644 index 5c9b608..0000000 --- a/packages/registry/public/r/native-delete.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-delete", - "type": "registry:component", - "title": "Native Delete", - "description": "Delete button that expands to show a confirmation button with smooth animations.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-delete-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { Trash2, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface NativeDeleteProps {\n /**\n * Callback when delete button is first clicked (shows confirmation)\n */\n onConfirm: () => void;\n /**\n * Callback when delete is confirmed\n */\n onDelete: () => void;\n /**\n * Text to show on the delete button\n * Default: \"Delete\"\n */\n buttonText?: string;\n /**\n * Text to show on the confirm button\n * Default: \"Confirm\"\n */\n confirmText?: string;\n /**\n * Size variant\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Show icon in button\n * Default: true\n */\n showIcon?: boolean;\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Disable the button\n */\n disabled?: boolean;\n}\n\nconst sizeVariants = {\n sm: \"h-8 text-xs px-3\",\n md: \"h-10 text-sm px-4\",\n lg: \"h-12 text-base px-6\",\n};\n\nconst iconSizeVariants = {\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n};\n\nexport function NativeDelete({\n onConfirm,\n onDelete,\n buttonText = \"Delete\",\n confirmText = \"Confirm\",\n size = \"md\",\n showIcon = true,\n className,\n disabled = false,\n}: NativeDeleteProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const handleDeleteClick = () => {\n if (!disabled) {\n setIsExpanded(true);\n onConfirm();\n }\n };\n\n const handleConfirm = () => {\n onDelete();\n setIsExpanded(false);\n };\n\n const handleCancel = () => {\n setIsExpanded(false);\n };\n\n return (\n
    \n \n \n \n {showIcon && !isExpanded && (\n \n )}\n {isExpanded ? confirmText : buttonText}\n \n \n \n\n \n {isExpanded && (\n \n \n \n \n \n \n \n )}\n \n
    \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-delete.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-dialog.json b/packages/registry/public/r/native-dialog.json deleted file mode 100644 index 42a7566..0000000 --- a/packages/registry/public/r/native-dialog.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-dialog", - "type": "registry:component", - "title": "Native Dialog", - "description": "A glassmorphism-styled dialog component with backdrop blur and smooth animations, inspired by native OS modals.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-dialog-shadcnui.tsx", - "content": "\"use client\";\n\nimport {\n DialogDescription as BaseDialogDescription,\n DialogTitle as BaseDialogTitle,\n Dialog,\n DialogClose,\n DialogFooter,\n DialogHeader,\n DialogPortal,\n DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { cn } from \"@/lib/utils\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { motion } from \"framer-motion\";\nimport { X } from \"lucide-react\";\nimport * as React from \"react\";\n\nconst NativeDialog = Dialog;\n\nconst NativeDialogTrigger = DialogTrigger;\n\nconst NativeDialogPortal = DialogPortal;\n\nconst NativeDialogClose = DialogClose;\n\nconst NativeDialogOverlay = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n));\nNativeDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst NativeDialogContent = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n \n \n \n {children}\n \n \n Close\n \n \n \n \n));\nNativeDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst NativeDialogHeader = DialogHeader;\nNativeDialogHeader.displayName = \"NativeDialogHeader\";\n\nconst NativeDialogFooter = DialogFooter;\nNativeDialogFooter.displayName = \"NativeDialogFooter\";\n\nconst NativeDialogTitle = BaseDialogTitle;\nNativeDialogTitle.displayName = \"NativeDialogTitle\";\n\nconst NativeDialogDescription = BaseDialogDescription;\nNativeDialogDescription.displayName = \"NativeDialogDescription\";\n\nexport {\n NativeDialog,\n NativeDialogClose,\n NativeDialogContent,\n NativeDialogDescription,\n NativeDialogFooter,\n NativeDialogHeader,\n NativeDialogOverlay,\n NativeDialogPortal,\n NativeDialogTitle,\n NativeDialogTrigger,\n};\n", - "type": "registry:component", - "target": "components/uitripled/native-dialog.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-flip-text-baseui.json b/packages/registry/public/r/native-flip-text-baseui.json new file mode 100644 index 0000000..0ec0326 --- /dev/null +++ b/packages/registry/public/r/native-flip-text-baseui.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-flip-text-baseui", + "type": "registry:component", + "title": "Native Flip Text", + "description": "Text that flips through words with a 3D blur transition. (Base UI)", + "registryDependencies": [ + "button" + ], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/native-flip-text-carbon-baseui.tsx", + "content": "// Error: Could not read file @uitripled/react-carbon/src/components/native/native-flip-text-carbon-baseui.tsx\n// File not found: @uitripled/react-carbon/src/components/native/native-flip-text-carbon-baseui.tsx", + "type": "registry:component", + "target": "components/uitripled/native-flip-text-baseui.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-flip-text-shadcnui.json b/packages/registry/public/r/native-flip-text-shadcnui.json new file mode 100644 index 0000000..e4449f9 --- /dev/null +++ b/packages/registry/public/r/native-flip-text-shadcnui.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-flip-text-shadcnui", + "type": "registry:component", + "title": "Native Flip Text", + "description": "Text that flips through words with a 3D blur transition.", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/native-flip-text-carbon.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { useEffect, useState } from \"react\";\n\ninterface NativeFlipTextProps {\n /**\n * Array of words to flip through.\n */\n words: string[];\n /**\n * Duration of each word display in ms.\n * Default: 2000\n */\n duration?: number;\n className?: string;\n}\n\nexport function NativeFlipText({\n words,\n duration = 2000,\n className,\n}: NativeFlipTextProps) {\n const [index, setIndex] = useState(0);\n\n useEffect(() => {\n const interval = setInterval(() => {\n setIndex((prevIndex) => (prevIndex + 1) % words.length);\n }, duration);\n\n return () => clearInterval(interval);\n }, [words.length, duration]);\n\n return (\n \n \n \n {words[index]}\n \n \n
    \n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/native-flip-text-shadcnui.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-flip-text.json b/packages/registry/public/r/native-flip-text.json index e00c090..ab146ab 100644 --- a/packages/registry/public/r/native-flip-text.json +++ b/packages/registry/public/r/native-flip-text.json @@ -13,7 +13,7 @@ "path": "@uitripled/react-carbon/src/components/native/native-flip-text-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { useEffect, useState } from \"react\";\n\ninterface NativeFlipTextProps {\n /**\n * Array of words to flip through.\n */\n words: string[];\n /**\n * Duration of each word display in ms.\n * Default: 2000\n */\n duration?: number;\n className?: string;\n}\n\nexport function NativeFlipText({\n words,\n duration = 2000,\n className,\n}: NativeFlipTextProps) {\n const [index, setIndex] = useState(0);\n\n useEffect(() => {\n const interval = setInterval(() => {\n setIndex((prevIndex) => (prevIndex + 1) % words.length);\n }, duration);\n\n return () => clearInterval(interval);\n }, [words.length, duration]);\n\n return (\n \n \n \n {words[index]}\n \n \n
    \n );\n}\n", "type": "registry:component", - "target": "components/uitripled/native-flip-text.tsx" + "target": "components/uitripled/native-flip-text-carbon.tsx" } ] } \ No newline at end of file diff --git a/packages/registry/public/r/native-hover-card.json b/packages/registry/public/r/native-hover-card.json deleted file mode 100644 index 2d06179..0000000 --- a/packages/registry/public/r/native-hover-card.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-hover-card", - "type": "registry:component", - "title": "Native Hover Card", - "description": "Avatar card that expands on hover to reveal profile information with smooth animations.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-hover-card-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { type ReactNode, useState } from \"react\";\n\nexport interface NativeHoverCardProps {\n /**\n * Image source URL\n */\n imageSrc: string;\n /**\n * Alt text for the image\n */\n imageAlt?: string;\n /**\n * Display name\n */\n name: string;\n /**\n * Username or handle\n */\n username?: string;\n /**\n * Description or bio text\n */\n description?: string;\n /**\n * Button text\n * Default: \"View Profile\"\n */\n buttonText?: string;\n /**\n * Button click handler\n */\n onButtonClick?: () => void;\n /**\n * Custom button component\n */\n buttonContent?: ReactNode;\n /**\n * Size of the image when collapsed\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Card variant style\n */\n variant?: \"default\" | \"glass\" | \"bordered\";\n}\n\nconst imageSizeVariants = {\n sm: \"w-16 h-16\",\n md: \"w-24 h-24\",\n lg: \"w-32 h-32\",\n xl: \"w-40 h-40\",\n};\n\nconst cardWidthVariants = {\n sm: \"w-56\",\n md: \"w-72\",\n lg: \"w-80\",\n xl: \"w-96\",\n};\n\nconst getInitials = (name: string) => {\n return name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n};\n\nexport function NativeHoverCard({\n imageSrc,\n imageAlt,\n name,\n username,\n description,\n buttonText = \"View Profile\",\n onButtonClick,\n buttonContent,\n size = \"md\",\n className,\n variant = \"default\",\n}: NativeHoverCardProps) {\n const [isHovered, setIsHovered] = useState(false);\n\n const getVariantStyles = () => {\n switch (variant) {\n case \"glass\":\n return \"bg-background/80 backdrop-blur-md border border-border/50\";\n case \"bordered\":\n return \"bg-card border-2 border-primary/20\";\n default:\n return \"bg-card border border-border\";\n }\n };\n\n // Avatar component - renders a fresh instance to ensure updates/animations work\n const avatarElement = (\n \n \n {getInitials(name)}\n \n );\n\n return (\n setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n initial={false}\n animate={{\n width: isHovered ? \"auto\" : \"fit-content\",\n }}\n transition={{\n type: \"spring\",\n stiffness: 300,\n damping: 30,\n }}\n >\n \n {avatarElement}\n \n\n {/* Expanded Card Content */}\n \n {isHovered && (\n \n {/* Background with gradient overlay on image */}\n
    \n \n {avatarElement}\n \n\n {/* Content Section */}\n \n {/* Name */}\n
    \n \n {name}\n \n\n {/* Username */}\n {username && (\n \n @{username}\n \n )}\n
    \n\n {/* Description */}\n {description && (\n \n {description}\n \n )}\n\n {/* Button */}\n \n {buttonContent ? (\n buttonContent\n ) : (\n \n {buttonText}\n \n )}\n \n \n
    \n \n )}\n
    \n \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-hover-card.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-image-checkbox.json b/packages/registry/public/r/native-image-checkbox.json deleted file mode 100644 index 0ea66cd..0000000 --- a/packages/registry/public/r/native-image-checkbox.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-image-checkbox", - "type": "registry:component", - "title": "Native Image Checkbox", - "description": "Image checkbox component with grayscale filter and checkmark indicator.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-image-checkbox-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport { Check } from \"lucide-react\";\n\nexport interface NativeImageCheckboxProps {\n /**\n * URL of the image\n */\n src: string;\n /**\n * Alt text for the image\n */\n alt: string;\n /**\n * Whether the checkbox is selected\n */\n selected: boolean;\n /**\n * Callback when the checkbox is clicked\n */\n onSelect: (selected: boolean) => void;\n /**\n * Size variant\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Additional classes for the container\n */\n className?: string;\n /**\n * Additional classes for the image\n */\n imageClassName?: string;\n}\n\nconst sizeConfig = {\n sm: {\n container: \"w-20 h-20\",\n check: \"h-5 w-5\",\n checkContainer: \"h-6 w-6\",\n },\n md: {\n container: \"w-28 h-28\",\n check: \"h-6 w-6\",\n checkContainer: \"h-7 w-7\",\n },\n lg: {\n container: \"w-36 h-36\",\n check: \"h-7 w-7\",\n checkContainer: \"h-8 w-8\",\n },\n xl: {\n container: \"w-44 h-44\",\n check: \"h-8 w-8\",\n checkContainer: \"h-9 w-9\",\n },\n};\n\nexport function NativeImageCheckbox({\n src,\n alt,\n selected,\n onSelect,\n size = \"md\",\n className,\n imageClassName,\n}: NativeImageCheckboxProps) {\n const { container, check, checkContainer } = sizeConfig[size];\n\n return (\n onSelect(!selected)}\n whileTap={{ scale: 0.95 }}\n transition={{\n type: \"spring\",\n stiffness: 300,\n damping: 20,\n }}\n >\n {/* Image with grayscale filter when not selected */}\n \n \n \n \n {alt.slice(0, 2).toUpperCase()}\n \n \n \n\n {/* Overlay for better check visibility */}\n \n\n {/* Check icon with green circle */}\n \n \n \n
    \n \n\n {/* Ring border when selected */}\n \n \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-image-checkbox.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-likes-counter.json b/packages/registry/public/r/native-likes-counter.json deleted file mode 100644 index ac9361e..0000000 --- a/packages/registry/public/r/native-likes-counter.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-likes-counter", - "type": "registry:component", - "title": "Native Likes Counter", - "description": "An interactive likes counter with avatar stack, popup details, and smooth animations.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-likes-counter-shadcnui.tsx", - "content": "\"use client\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { cn } from \"@/lib/utils\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Heart, Loader2 } from \"lucide-react\"\nimport { useState, useCallback, useRef } from \"react\"\n\nexport interface LikeUser {\n id: string\n name: string\n avatar?: string\n}\n\nexport interface NativeLikesCounterProps {\n count: number\n users?: LikeUser[]\n variant?: \"default\" | \"subtle\" | \"outline\" | \"ghost\"\n size?: \"sm\" | \"default\" | \"lg\"\n liked?: boolean\n onLike?: () => void\n onLoadMore?: () => Promise | LikeUser[]\n hasMore?: boolean\n maxAvatars?: number\n maxVisibleInPopup?: number\n className?: string\n}\n\nconst sizeVariants = {\n sm: {\n container: \"h-7 px-2.5 gap-1.5 text-xs\",\n icon: \"w-3.5 h-3.5\",\n avatar: \"w-4 h-4\",\n avatarStack: \"-space-x-1\",\n popup: \"p-3\",\n popupAvatar: \"w-6 h-6\",\n },\n default: {\n container: \"h-8 px-3 gap-2 text-sm\",\n icon: \"w-4 h-4\",\n avatar: \"w-5 h-5\",\n avatarStack: \"-space-x-1.5\",\n popup: \"p-3\",\n popupAvatar: \"w-7 h-7\",\n },\n lg: {\n container: \"h-9 px-3.5 gap-2 text-sm\",\n icon: \"w-[18px] h-[18px]\",\n avatar: \"w-6 h-6\",\n avatarStack: \"-space-x-2\",\n popup: \"p-3\",\n popupAvatar: \"w-8 h-8\",\n },\n}\n\nexport function NativeLikesCounter({\n count,\n users = [],\n variant = \"default\",\n size = \"default\",\n liked = false,\n onLike,\n onLoadMore,\n hasMore = false,\n maxAvatars = 5,\n maxVisibleInPopup = 5,\n className,\n}: NativeLikesCounterProps) {\n const [isHovered, setIsHovered] = useState(false)\n const [isLiked, setIsLiked] = useState(liked)\n const [localCount, setLocalCount] = useState(count)\n const [loadedUsers, setLoadedUsers] = useState(users)\n const [isLoadingMore, setIsLoadingMore] = useState(false)\n const [canLoadMore, setCanLoadMore] = useState(hasMore)\n\n const hoverTimeoutRef = useRef(null)\n\n const sizeConfig = sizeVariants[size]\n const displayUsers = loadedUsers.slice(0, maxAvatars)\n\n const handleMouseEnter = () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current)\n hoverTimeoutRef.current = null\n }\n setIsHovered(true)\n }\n\n const handleMouseLeave = () => {\n hoverTimeoutRef.current = setTimeout(() => {\n setIsHovered(false)\n }, 150) // Small delay to allow moving to popup\n }\n\n const handleLike = () => {\n setIsLiked(!isLiked)\n setLocalCount((prev) => (isLiked ? prev - 1 : prev + 1))\n onLike?.()\n }\n\n const handleLoadMore = useCallback(async () => {\n if (!onLoadMore || isLoadingMore) return\n\n setIsLoadingMore(true)\n try {\n const newUsers = await onLoadMore()\n if (newUsers.length === 0) {\n setCanLoadMore(false)\n } else {\n setLoadedUsers((prev) => [...prev, ...newUsers])\n }\n } catch (error) {\n console.error(\"Failed to load more users:\", error)\n } finally {\n setIsLoadingMore(false)\n }\n }, [onLoadMore, isLoadingMore])\n\n const getVariantStyles = () => {\n const base = \"transition-all duration-150\"\n switch (variant) {\n case \"subtle\":\n return cn(base, \"bg-accent/50 hover:bg-accent\", isLiked && \"bg-accent\")\n case \"outline\":\n return cn(\n base,\n \"bg-transparent border border-border hover:border-accent-foreground/20 hover:bg-accent/10\",\n isLiked && \"border-accent-foreground/30 bg-accent/20\",\n )\n case \"ghost\":\n return cn(base, \"bg-transparent hover:bg-accent/50\", isLiked && \"bg-accent/30\")\n default:\n return cn(\n base,\n \"bg-accent border border-border hover:bg-accent/80 hover:border-accent-foreground/20\",\n isLiked && \"border-accent-foreground/20\",\n )\n }\n }\n\n const visibleUsersInPopup = loadedUsers.slice(0, maxVisibleInPopup)\n const totalRemaining = localCount - loadedUsers.length\n\n return (\n
    \n \n {/* Heart icon */}\n \n \n \n \n \n\n \n \n {localCount.toLocaleString()}\n \n \n\n {users.length > 0 && variant !== \"ghost\" && (\n
    \n {users.slice(0, 3).map((user, index) => (\n \n \n \n \n {user.name.charAt(0).toUpperCase()}\n \n \n \n ))}\n
    \n )}\n \n\n \n {isHovered && loadedUsers.length > 0 && (\n \n {/* Header */}\n
    \n Liked by\n {localCount.toLocaleString()}\n
    \n\n
    \n
    \n {visibleUsersInPopup.map((user, index) => (\n \n \n \n \n {user.name.charAt(0).toUpperCase()}\n \n \n \n {user.name}\n \n \n ))}\n
    \n
    \n\n {(canLoadMore || totalRemaining > 0) && (\n \n {onLoadMore && canLoadMore ? (\n {\n e.stopPropagation()\n handleLoadMore()\n }}\n disabled={isLoadingMore}\n className=\"w-full flex items-center justify-center gap-1.5 py-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50\"\n >\n {isLoadingMore ? (\n <>\n \n Loading...\n \n ) : (\n Load more {totalRemaining > 0 && `(${totalRemaining.toLocaleString()} more)`}\n )}\n \n ) : totalRemaining > 0 ? (\n
    \n +{totalRemaining.toLocaleString()} others\n
    \n ) : null}\n \n )}\n \n )}\n
    \n
    \n )\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-likes-counter.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-liquid-button.json b/packages/registry/public/r/native-liquid-button.json deleted file mode 100644 index a08f092..0000000 --- a/packages/registry/public/r/native-liquid-button.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-liquid-button", - "type": "registry:component", - "title": "Native Liquid Button", - "description": "Button with animated liquid fill effect, progress tracking, and multiple visual variants for engaging interactions.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-liquid-button-shadcnui.tsx", - "content": "\"use client\";\n\nimport {\n NativeButton,\n type NativeButtonProps,\n} from \"@/components/uitripled/native-button-shadcnui\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { Loader2 } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\nexport interface NativeLiquidButtonProps\n extends Omit {\n /**\n * Progress value (0-100)\n */\n progress?: number;\n /**\n * Loading state\n */\n loading?: boolean;\n /**\n * Callback when button is clicked\n */\n onClick?: () => void | Promise;\n /**\n * Visual variant\n * Default: \"default\"\n */\n liquidVariant?: \"default\" | \"gradient\" | \"glow\" | \"wave\";\n /**\n * Liquid color\n */\n liquidColor?: string;\n /**\n * Show percentage text\n * Default: false\n */\n showPercentage?: boolean;\n /**\n * Auto-simulate loading (for demo purposes)\n */\n autoSimulate?: boolean;\n /**\n * Success state\n */\n success?: boolean;\n /**\n * Error state\n */\n error?: boolean;\n}\n\nconst sizeVariants = {\n sm: \"h-9 px-4 text-sm min-w-[100px]\",\n default: \"h-11 px-6 text-base min-w-[140px]\",\n lg: \"h-14 px-8 text-lg min-w-[180px]\",\n icon: \"h-11 px-6 text-base min-w-[140px]\",\n};\n\nexport function NativeLiquidButton({\n children,\n className,\n variant = \"default\",\n size = \"default\",\n progress = 0,\n loading = false,\n onClick,\n disabled,\n liquidVariant = \"default\",\n liquidColor,\n showPercentage = false,\n autoSimulate = false,\n success = false,\n error = false,\n ...props\n}: NativeLiquidButtonProps) {\n const [internalProgress, setInternalProgress] = useState(progress);\n const [isSimulating, setIsSimulating] = useState(false);\n\n useEffect(() => {\n setInternalProgress(progress);\n }, [progress]);\n\n useEffect(() => {\n if (autoSimulate && isSimulating) {\n const interval = setInterval(() => {\n setInternalProgress((prev) => {\n if (prev >= 100) {\n clearInterval(interval);\n setIsSimulating(false);\n return 100;\n }\n return prev + Math.random() * 10;\n });\n }, 200);\n return () => clearInterval(interval);\n }\n }, [autoSimulate, isSimulating]);\n\n const handleClick = async () => {\n if (disabled || loading) return;\n\n if (autoSimulate) {\n setIsSimulating(true);\n setInternalProgress(0);\n }\n\n if (onClick) {\n await onClick();\n }\n };\n\n const getLiquidColor = () => {\n if (success) return \"bg-green-500\";\n if (error) return \"bg-red-500\";\n if (liquidColor) return liquidColor;\n\n switch (liquidVariant) {\n case \"gradient\":\n return \"bg-gradient-to-r from-primary via-primary/80 to-primary\";\n case \"glow\":\n return \"bg-primary\";\n default:\n return \"bg-primary\";\n }\n };\n\n const clampedProgress = Math.min(Math.max(internalProgress, 0), 100);\n\n return (\n
    \n \n {/* Liquid fill effect */}\n \n {/* Bubble effects */}\n {liquidVariant === \"default\" && clampedProgress > 0 && (\n <>\n {[...Array(3)].map((_, i) => (\n \n ))}\n \n )}\n\n {/* Shimmer effect for gradient */}\n {liquidVariant === \"gradient\" && clampedProgress > 0 && (\n \n )}\n \n\n {/* Button content */}\n \n \n {loading && (\n \n \n \n )}\n \n\n \n {children}\n \n\n {showPercentage && (\n \n {Math.round(clampedProgress)}%\n \n )}\n \n\n {/* Glow effect */}\n {liquidVariant === \"glow\" && !disabled && clampedProgress > 0 && (\n \n )}\n \n
    \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-liquid-button.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-magnetic.json b/packages/registry/public/r/native-magnetic.json index 01fe057..9c79f28 100644 --- a/packages/registry/public/r/native-magnetic.json +++ b/packages/registry/public/r/native-magnetic.json @@ -13,7 +13,7 @@ "path": "@uitripled/react-carbon/src/components/native/native-magnetic-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n motion,\n Transition,\n useMotionValue,\n useSpring,\n useTransform,\n} from \"framer-motion\";\nimport { useRef, useState } from \"react\";\n\nexport interface NativeMagneticProps {\n /**\n * Content to apply the magnetic effect to.\n */\n children: React.ReactNode;\n /**\n * Strength of the magnetic pull (0-1 range recommended).\n * Default: 0.3\n */\n strength?: number;\n /**\n * Spring stiffness for the animation.\n * Default: 300\n */\n stiffness?: number;\n /**\n * Spring damping for the animation.\n * Default: 30\n */\n damping?: number;\n /**\n * Whether to scale up on hover.\n * Default: true\n */\n scaleOnHover?: boolean;\n /**\n * Wrapper element type.\n * Default: 'div'\n */\n as?: \"div\" | \"button\" | \"a\";\n /**\n * Link href (only applies when as=\"a\").\n */\n href?: string;\n /**\n * Click handler.\n */\n onClick?: () => void;\n className?: string;\n}\n\nconst springTransition: Transition = {\n type: \"spring\",\n stiffness: 400,\n damping: 25,\n};\n\nexport function NativeMagnetic({\n children,\n strength = 0.3,\n stiffness = 300,\n damping = 30,\n scaleOnHover = true,\n as = \"div\",\n href,\n onClick,\n className,\n}: NativeMagneticProps) {\n const ref = useRef(null);\n const [, setIsHovered] = useState(false);\n\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n const springConfig = { stiffness, damping };\n const springX = useSpring(x, springConfig);\n const springY = useSpring(y, springConfig);\n\n const translateX = useTransform(springX, (v) => v * strength);\n const translateY = useTransform(springY, (v) => v * strength);\n\n const handleMouseMove = (e: React.MouseEvent) => {\n if (!ref.current) return;\n\n const rect = ref.current.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n x.set(e.clientX - centerX);\n y.set(e.clientY - centerY);\n };\n\n const handleMouseLeave = () => {\n x.set(0);\n y.set(0);\n setIsHovered(false);\n };\n\n const commonProps = {\n onMouseMove: handleMouseMove,\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: handleMouseLeave,\n style: {\n x: translateX,\n y: translateY,\n },\n whileHover: scaleOnHover ? { scale: 1.05 } : undefined,\n whileTap: { scale: 0.95 },\n transition: springTransition,\n className: cn(\"inline-block cursor-pointer\", className),\n onClick,\n };\n\n if (as === \"a\" && href) {\n return (\n }\n href={href}\n {...commonProps}\n >\n {children}\n \n );\n }\n\n if (as === \"button\") {\n return (\n }\n type=\"button\"\n {...commonProps}\n >\n {children}\n \n );\n }\n\n return (\n } {...commonProps}>\n {children}\n \n );\n}\n", "type": "registry:component", - "target": "components/uitripled/native-magnetic.tsx" + "target": "components/uitripled/native-magnetic-carbon.tsx" } ] } \ No newline at end of file diff --git a/packages/registry/public/r/native-morphing-button.json b/packages/registry/public/r/native-morphing-button.json deleted file mode 100644 index e57b012..0000000 --- a/packages/registry/public/r/native-morphing-button.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-morphing-button", - "type": "registry:component", - "title": "Native Morphing Button", - "description": "Floating action button that morphs into a menu of actions.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-morphing-button-shadcnui.tsx", - "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n AnimatePresence,\n LayoutGroup,\n motion,\n Transition,\n useReducedMotion,\n} from \"framer-motion\";\nimport { Plus, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface MorphingButtonAction {\n /**\n * Display label for the action.\n */\n label: string;\n /**\n * Icon to display alongside the label.\n */\n icon: React.ReactNode;\n /**\n * Callback when action is clicked.\n */\n onClick: () => void;\n}\n\nexport interface NativeMorphingButtonProps {\n /**\n * Array of actions to display in the expanded menu.\n */\n actions: MorphingButtonAction[];\n /**\n * Position of the FAB.\n * Default: 'bottom-right'\n */\n position?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n /**\n * Whether to use fixed positioning.\n * Default: false (relative to container)\n */\n fixed?: boolean;\n /**\n * Custom icon when collapsed.\n */\n icon?: React.ReactNode;\n /**\n * Custom close icon when expanded.\n */\n closeIcon?: React.ReactNode;\n className?: string;\n}\n\nconst positionClasses = {\n \"bottom-right\": \"bottom-4 right-4\",\n \"bottom-left\": \"bottom-4 left-4\",\n \"top-right\": \"top-4 right-4\",\n \"top-left\": \"top-4 left-4\",\n};\n\nconst springTransition: Transition = {\n type: \"spring\",\n stiffness: 300,\n damping: 30,\n};\nconst reducedTransition: Transition = { duration: 0.1 };\n\nexport function NativeMorphingButton({\n actions,\n position = \"bottom-right\",\n fixed = false,\n icon,\n closeIcon,\n className,\n}: NativeMorphingButtonProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const shouldReduceMotion = useReducedMotion();\n\n const transition = shouldReduceMotion ? reducedTransition : springTransition;\n\n return (\n \n \n \n {/* Main FAB Button */}\n setIsExpanded(!isExpanded)}\n className=\"absolute right-0 bottom-0 flex h-14 w-14 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-lg transition-shadow hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n whileHover={shouldReduceMotion ? undefined : { scale: 1.05 }}\n whileTap={shouldReduceMotion ? undefined : { scale: 0.95 }}\n aria-label={isExpanded ? \"Close menu\" : \"Open menu\"}\n aria-expanded={isExpanded}\n >\n \n {isExpanded ? (\n \n {closeIcon ?? }\n \n ) : (\n \n {icon ?? }\n \n )}\n \n \n\n {/* Expanded Menu */}\n \n {isExpanded && (\n \n
    \n {actions.map((action, index) => (\n {\n action.onClick();\n setIsExpanded(false);\n }}\n className=\"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left text-sm transition-colors hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring\"\n role=\"menuitem\"\n >\n \n {action.icon}\n \n {action.label}\n \n ))}\n
    \n \n )}\n
    \n \n
    \n
    \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-morphing-button.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-nested-list.json b/packages/registry/public/r/native-nested-list-shadcnui.json similarity index 98% rename from packages/registry/public/r/native-nested-list.json rename to packages/registry/public/r/native-nested-list-shadcnui.json index 2c3a2d1..94767e1 100644 --- a/packages/registry/public/r/native-nested-list.json +++ b/packages/registry/public/r/native-nested-list-shadcnui.json @@ -1,6 +1,6 @@ { "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-nested-list", + "name": "native-nested-list-shadcnui", "type": "registry:component", "title": "Native Nested List", "description": "A nested list component with smooth expand/collapse animations, perfect for file explorers or navigation menus.", @@ -13,7 +13,7 @@ "path": "@uitripled/react-shadcn/src/components/native/native-nested-list-shadcnui.tsx", "content": "\"use client\";\n\nimport type React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { ChevronRight } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface ListItem {\n /**\n * Unique identifier for the list item\n */\n id: string;\n /**\n * Display label for the list item\n */\n label: string;\n /**\n * Optional icon component\n */\n icon?: React.ReactNode;\n /**\n * Nested children items\n */\n children?: ListItem[];\n /**\n * Additional metadata\n */\n metadata?: Record;\n /**\n * Optional URL to navigate to\n */\n href?: string;\n /**\n * Optional click handler\n */\n onClick?: (e: React.MouseEvent) => void;\n}\n\n// ... existing props interface ...\nexport interface NativeNestedListProps {\n items: ListItem[];\n activeId?: string;\n onItemClick?: (item: ListItem) => void;\n size?: \"sm\" | \"md\" | \"lg\";\n showExpandIcon?: boolean;\n defaultExpanded?: boolean;\n className?: string;\n indentSize?: number;\n}\n\nconst sizeVariants = {\n sm: \"h-8 text-xs px-2\",\n md: \"h-10 text-sm px-3\",\n lg: \"h-12 text-base px-4\",\n};\n\nconst iconSizeVariants = {\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n};\n\ninterface NestedItemProps {\n item: ListItem;\n level: number;\n activeId?: string;\n onItemClick?: (item: ListItem) => void;\n size: \"sm\" | \"md\" | \"lg\";\n showExpandIcon: boolean;\n defaultExpanded: boolean;\n indentSize: number;\n}\n\nfunction NestedItem({\n item,\n level,\n activeId,\n onItemClick,\n size,\n showExpandIcon,\n defaultExpanded,\n indentSize,\n}: NestedItemProps) {\n const [isExpanded, setIsExpanded] = useState(defaultExpanded);\n const hasChildren = item.children && item.children.length > 0;\n const isActive = activeId === item.id;\n\n const handleClick = (e: React.MouseEvent) => {\n if (hasChildren) {\n e.preventDefault();\n setIsExpanded(!isExpanded);\n }\n onItemClick?.(item);\n item.onClick?.(e);\n };\n\n const Comp = item.href ? \"a\" : \"span\";\n const props = item.href ? { href: item.href } : {};\n\n return (\n
    \n \n \n \n \n {showExpandIcon && hasChildren && (\n \n \n \n )}\n {showExpandIcon && !hasChildren && (\n
    \n )}\n {item.icon && (\n \n {item.icon}\n \n )}\n {item.label}\n \n \n \n\n \n {isActive && (\n \n )}\n \n \n\n {/* Nested children */}\n \n {hasChildren && isExpanded && (\n \n {item.children!.map((child) => (\n \n ))}\n \n )}\n \n
    \n );\n}\n\nexport function NativeNestedList({\n items,\n activeId,\n onItemClick,\n size = \"md\",\n showExpandIcon = true,\n defaultExpanded = false,\n className,\n indentSize = 16,\n}: NativeNestedListProps) {\n return (\n
    \n {items.map((item) => (\n \n ))}\n
    \n );\n}\n", "type": "registry:component", - "target": "components/uitripled/native-nested-list.tsx" + "target": "components/uitripled/native-nested-list-shadcnui.tsx" } ] } \ No newline at end of file diff --git a/packages/registry/public/r/native-notch-baseui.json b/packages/registry/public/r/native-notch-baseui.json new file mode 100644 index 0000000..f55b9e0 --- /dev/null +++ b/packages/registry/public/r/native-notch-baseui.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-notch-baseui", + "type": "registry:component", + "title": "Native Notch", + "description": "Dynamic Island-inspired notch component with smooth spring animations, draggable physics, and expandable content area (Base UI)", + "registryDependencies": [ + "button" + ], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-baseui/src/components/native/native-notch-baseui.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n AnimatePresence,\n animate,\n motion,\n useMotionValue,\n useSpring,\n useTransform,\n} from \"framer-motion\";\nimport { X } from \"lucide-react\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\n/**\n * Size variants for the notch component\n */\nexport type NotchSize = \"sm\" | \"md\" | \"lg\";\n\n/**\n * Position configuration for initial placement\n */\nexport interface NotchPosition {\n /**\n * Top offset in pixels\n */\n top?: number;\n /**\n * Bottom offset in pixels\n */\n bottom?: number;\n /**\n * Horizontal alignment\n */\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport interface NativeNotchProps {\n /**\n * Content to display when the notch is open\n */\n children?: React.ReactNode;\n /**\n * Custom content/icon to display when the notch is closed\n */\n collapsedIcon?: React.ReactNode;\n /**\n * Size variant\n * @default \"md\"\n */\n size?: NotchSize;\n /**\n * Initial position configuration\n */\n position?: NotchPosition;\n /**\n * Whether the notch is draggable\n * @default true\n */\n draggable?: boolean;\n /**\n * Default expanded state\n * @default false\n */\n defaultExpanded?: boolean;\n /**\n * Controlled expanded state\n */\n expanded?: boolean;\n /**\n * Callback when expanded state changes\n */\n onExpandedChange?: (expanded: boolean) => void;\n /**\n * Callback when notch is clicked\n */\n onClick?: (e: React.MouseEvent) => void;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\nconst sizeVariants = {\n sm: {\n collapsed: { width: 40, height: 40, radius: 20 },\n expanded: { width: 280, height: 160, radius: 24 },\n },\n md: {\n collapsed: { width: 48, height: 48, radius: 24 },\n expanded: { width: 340, height: 200, radius: 28 },\n },\n lg: {\n collapsed: { width: 56, height: 56, radius: 28 },\n expanded: { width: 400, height: 240, radius: 32 },\n },\n};\n\nconst positionStyles = {\n left: \"left-8\",\n center: \"left-1/2 -translate-x-1/2\",\n right: \"right-8\",\n};\n\nexport function NativeNotch({\n children,\n collapsedIcon,\n size = \"md\",\n position = { top: 32, align: \"center\" },\n draggable = true,\n defaultExpanded = false,\n expanded: controlledExpanded,\n onExpandedChange,\n onClick,\n className,\n}: NativeNotchProps) {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const [isDragging, setIsDragging] = useState(false);\n const notchRef = useRef(null);\n\n const isControlled = controlledExpanded !== undefined;\n const isExpanded = isControlled ? controlledExpanded : internalExpanded;\n\n const setExpanded = (value: boolean) => {\n if (!isControlled) {\n setInternalExpanded(value);\n }\n onExpandedChange?.(value);\n };\n\n const sizeConfig = sizeVariants[size];\n\n // Motion values for drag physics\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n const springConfig = { stiffness: 150, damping: 20, mass: 0.8 };\n const springX = useSpring(x, springConfig);\n const springY = useSpring(y, springConfig);\n\n // Rotation and scale based on drag velocity/position\n const rotate = useTransform(springX, [-200, 200], [-5, 5]);\n const scale = useTransform(\n [springX, springY],\n ([latestX, latestY]: number[]) => {\n const distance = Math.sqrt(latestX * latestX + latestY * latestY);\n return 1 - Math.min(distance / 1500, 0.08);\n }\n );\n\n // Motion values for dimensions\n const notchWidth = useMotionValue(sizeConfig.collapsed.width);\n const notchHeight = useMotionValue(sizeConfig.collapsed.height);\n const notchRadius = useMotionValue(sizeConfig.collapsed.radius);\n\n const springWidth = useSpring(notchWidth, { stiffness: 400, damping: 35, mass: 0.6 });\n const springHeight = useSpring(notchHeight, { stiffness: 300, damping: 30, mass: 0.8 });\n const springRadius = useSpring(notchRadius, { stiffness: 350, damping: 30, mass: 0.6 });\n\n useEffect(() => {\n if (isExpanded) {\n // Logic from user's snippet\n animate(notchWidth, sizeConfig.expanded.width, { type: \"spring\", stiffness: 400, damping: 35, mass: 0.5 });\n animate(notchRadius, sizeConfig.expanded.radius, { type: \"spring\", stiffness: 350, damping: 30, mass: 0.5 });\n const timeout = setTimeout(() => {\n animate(notchHeight, sizeConfig.expanded.height, { type: \"spring\", stiffness: 300, damping: 28, mass: 0.6 });\n }, 80);\n return () => clearTimeout(timeout);\n } else {\n animate(notchHeight, sizeConfig.collapsed.height, { type: \"spring\", stiffness: 350, damping: 30, mass: 0.5 });\n const timeout = setTimeout(() => {\n animate(notchWidth, sizeConfig.collapsed.width, { type: \"spring\", stiffness: 400, damping: 35, mass: 0.5 });\n animate(notchRadius, sizeConfig.collapsed.radius, { type: \"spring\", stiffness: 350, damping: 30, mass: 0.5 });\n }, 60);\n return () => clearTimeout(timeout);\n }\n }, [isExpanded, notchWidth, notchHeight, notchRadius, sizeConfig]);\n\n const handlePointerDown = (e: React.PointerEvent) => {\n if (isExpanded || !draggable) return;\n setIsDragging(true);\n // @ts-ignore\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n };\n\n const handlePointerMove = (e: React.PointerEvent) => {\n if (!isDragging || isExpanded || !draggable) return;\n\n const centerX = window.innerWidth / 2;\n const centerY = (position.top || 32) + 24;\n\n const newX = e.clientX - centerX;\n const newY = e.clientY - centerY;\n\n const maxX = window.innerWidth / 2 - 40;\n const maxY = window.innerHeight - 80;\n const minY = -20;\n\n x.set(Math.max(-maxX, Math.min(maxX, newX)));\n y.set(Math.max(minY, Math.min(maxY, newY)));\n };\n\n const handlePointerUp = (e: React.PointerEvent) => {\n if (!isDragging) return;\n setIsDragging(false);\n // @ts-ignore\n (e.target as HTMLElement).releasePointerCapture(e.pointerId);\n\n // Snap back\n animate(x, 0, { type: \"spring\", stiffness: 200, damping: 25 });\n animate(y, 0, { type: \"spring\", stiffness: 200, damping: 25 });\n };\n\n const handleClick = (e: React.MouseEvent) => {\n if (isDragging) return;\n if (Math.abs(x.get()) > 5 || Math.abs(y.get()) > 5) return;\n\n onClick?.(e);\n if (!isExpanded) {\n setExpanded(true);\n }\n };\n\n return (\n \n \n \n {!isExpanded ? (\n \n {collapsedIcon ||
    }\n \n ) : (\n \n
    \n {\n e.stopPropagation();\n setExpanded(false);\n }}\n className=\"p-1 rounded-full hover:bg-accent/10 transition-colors\"\n >\n \n \n
    \n \n {children}\n \n \n )}\n \n \n \n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/native-notch-baseui.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-notch-shadcnui.json b/packages/registry/public/r/native-notch-shadcnui.json new file mode 100644 index 0000000..a006861 --- /dev/null +++ b/packages/registry/public/r/native-notch-shadcnui.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-notch-shadcnui", + "type": "registry:component", + "title": "Native Notch", + "description": "Dynamic Island-inspired notch component with smooth spring animations, draggable physics, and expandable content area", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-shadcn/src/components/native/native-notch-shadcnui.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n AnimatePresence,\n animate,\n motion,\n useMotionValue,\n useSpring,\n useTransform,\n} from \"framer-motion\";\nimport { X } from \"lucide-react\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\n/**\n * Size variants for the notch component\n */\nexport type NotchSize = \"sm\" | \"md\" | \"lg\";\n\n/**\n * Position configuration for initial placement\n */\nexport interface NotchPosition {\n /**\n * Top offset in pixels\n */\n top?: number;\n /**\n * Bottom offset in pixels\n */\n bottom?: number;\n /**\n * Horizontal alignment\n */\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport interface NativeNotchProps {\n /**\n * Content to display when the notch is open\n */\n children?: React.ReactNode;\n /**\n * Custom content/icon to display when the notch is closed\n */\n collapsedIcon?: React.ReactNode;\n /**\n * Size variant\n * @default \"md\"\n */\n size?: NotchSize;\n /**\n * Initial position configuration\n */\n position?: NotchPosition;\n /**\n * Whether the notch is draggable\n * @default true\n */\n draggable?: boolean;\n /**\n * Default expanded state\n * @default false\n */\n defaultExpanded?: boolean;\n /**\n * Controlled expanded state\n */\n expanded?: boolean;\n /**\n * Callback when expanded state changes\n */\n onExpandedChange?: (expanded: boolean) => void;\n /**\n * Callback when notch is clicked\n */\n onClick?: (e: React.MouseEvent) => void;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\nconst sizeVariants = {\n sm: {\n collapsed: { width: 40, height: 40, radius: 20 },\n expanded: { width: 280, height: 160, radius: 24 },\n },\n md: {\n collapsed: { width: 48, height: 48, radius: 24 },\n expanded: { width: 340, height: 200, radius: 28 },\n },\n lg: {\n collapsed: { width: 56, height: 56, radius: 28 },\n expanded: { width: 400, height: 240, radius: 32 },\n },\n};\n\nconst positionStyles = {\n left: \"left-8\",\n center: \"left-1/2 -translate-x-1/2\",\n right: \"right-8\",\n};\n\nexport function NativeNotch({\n children,\n collapsedIcon,\n size = \"md\",\n position = { top: 32, align: \"center\" },\n draggable = true,\n defaultExpanded = false,\n expanded: controlledExpanded,\n onExpandedChange,\n onClick,\n className,\n}: NativeNotchProps) {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const [isDragging, setIsDragging] = useState(false);\n const notchRef = useRef(null);\n\n const isControlled = controlledExpanded !== undefined;\n const isExpanded = isControlled ? controlledExpanded : internalExpanded;\n\n const setExpanded = (value: boolean) => {\n if (!isControlled) {\n setInternalExpanded(value);\n }\n onExpandedChange?.(value);\n };\n\n const sizeConfig = sizeVariants[size];\n\n // Motion values for drag physics\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n const springConfig = { stiffness: 150, damping: 20, mass: 0.8 };\n const springX = useSpring(x, springConfig);\n const springY = useSpring(y, springConfig);\n\n // Rotation and scale based on drag velocity/position\n const rotate = useTransform(springX, [-200, 200], [-5, 5]);\n const scale = useTransform(\n [springX, springY],\n ([latestX, latestY]: number[]) => {\n const distance = Math.sqrt(latestX * latestX + latestY * latestY);\n return 1 - Math.min(distance / 1500, 0.08);\n }\n );\n\n // Motion values for dimensions\n const notchWidth = useMotionValue(sizeConfig.collapsed.width);\n const notchHeight = useMotionValue(sizeConfig.collapsed.height);\n const notchRadius = useMotionValue(sizeConfig.collapsed.radius);\n\n const springWidth = useSpring(notchWidth, { stiffness: 400, damping: 35, mass: 0.6 });\n const springHeight = useSpring(notchHeight, { stiffness: 300, damping: 30, mass: 0.8 });\n const springRadius = useSpring(notchRadius, { stiffness: 350, damping: 30, mass: 0.6 });\n\n useEffect(() => {\n if (isExpanded) {\n // Logic from user's snippet\n animate(notchWidth, sizeConfig.expanded.width, { type: \"spring\", stiffness: 400, damping: 35, mass: 0.5 });\n animate(notchRadius, sizeConfig.expanded.radius, { type: \"spring\", stiffness: 350, damping: 30, mass: 0.5 });\n const timeout = setTimeout(() => {\n animate(notchHeight, sizeConfig.expanded.height, { type: \"spring\", stiffness: 300, damping: 28, mass: 0.6 });\n }, 80);\n return () => clearTimeout(timeout);\n } else {\n animate(notchHeight, sizeConfig.collapsed.height, { type: \"spring\", stiffness: 350, damping: 30, mass: 0.5 });\n const timeout = setTimeout(() => {\n animate(notchWidth, sizeConfig.collapsed.width, { type: \"spring\", stiffness: 400, damping: 35, mass: 0.5 });\n animate(notchRadius, sizeConfig.collapsed.radius, { type: \"spring\", stiffness: 350, damping: 30, mass: 0.5 });\n }, 60);\n return () => clearTimeout(timeout);\n }\n }, [isExpanded, notchWidth, notchHeight, notchRadius, sizeConfig]);\n\n const handlePointerDown = (e: React.PointerEvent) => {\n if (isExpanded || !draggable) return;\n setIsDragging(true);\n // @ts-ignore\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n };\n\n const handlePointerMove = (e: React.PointerEvent) => {\n if (!isDragging || isExpanded || !draggable) return;\n\n const centerX = window.innerWidth / 2;\n const centerY = (position.top || 32) + 24;\n\n const newX = e.clientX - centerX;\n const newY = e.clientY - centerY;\n\n const maxX = window.innerWidth / 2 - 40;\n const maxY = window.innerHeight - 80;\n const minY = -20;\n\n x.set(Math.max(-maxX, Math.min(maxX, newX)));\n y.set(Math.max(minY, Math.min(maxY, newY)));\n };\n\n const handlePointerUp = (e: React.PointerEvent) => {\n if (!isDragging) return;\n setIsDragging(false);\n // @ts-ignore\n (e.target as HTMLElement).releasePointerCapture(e.pointerId);\n\n // Snap back\n animate(x, 0, { type: \"spring\", stiffness: 200, damping: 25 });\n animate(y, 0, { type: \"spring\", stiffness: 200, damping: 25 });\n };\n\n const handleClick = (e: React.MouseEvent) => {\n if (isDragging) return;\n if (Math.abs(x.get()) > 5 || Math.abs(y.get()) > 5) return;\n\n onClick?.(e);\n if (!isExpanded) {\n setExpanded(true);\n }\n };\n\n return (\n \n \n \n {!isExpanded ? (\n \n {collapsedIcon ||
    }\n \n ) : (\n \n
    \n {\n e.stopPropagation();\n setExpanded(false);\n }}\n className=\"p-1 rounded-full hover:bg-accent/10 transition-colors\"\n >\n \n \n
    \n \n {children}\n \n \n )}\n \n \n \n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/native-notch-shadcnui.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-notification-bell.json b/packages/registry/public/r/native-notification-bell.json deleted file mode 100644 index e57ed39..0000000 --- a/packages/registry/public/r/native-notification-bell.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-notification-bell", - "type": "registry:component", - "title": "Native Notification Bell", - "description": "Animated notification bell with badge and ringing effect.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-notification-bell-shadcnui.tsx", - "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useReducedMotion, type Variants } from \"framer-motion\";\nimport { Bell } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\nexport interface NativeNotificationBellProps {\n /**\n * Number of notifications to display.\n * Default: 0\n */\n count?: number;\n /**\n * Whether to show the notification badge.\n * Automatically true if count > 0.\n */\n showBadge?: boolean;\n /**\n * Callback when the bell is clicked.\n */\n onClick?: () => void;\n /**\n * Callback when the bell rings (on mount if has notifications).\n */\n onRing?: () => void;\n /**\n * Custom icon to replace the bell.\n */\n icon?: React.ReactNode;\n /**\n * Size variant.\n * Default: 'md'\n */\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nconst sizeClasses = {\n sm: \"h-8 w-8\",\n md: \"h-10 w-10\",\n lg: \"h-12 w-12\",\n};\n\nconst iconSizeClasses = {\n sm: \"h-4 w-4\",\n md: \"h-5 w-5\",\n lg: \"h-6 w-6\",\n};\n\nconst badgeSizeClasses = {\n sm: \"h-4 w-4 text-[10px]\",\n md: \"h-5 w-5 text-xs\",\n lg: \"h-6 w-6 text-sm\",\n};\n\nconst ringVariants: Variants = {\n idle: { rotate: 0 },\n ringing: {\n rotate: [0, -15, 15, -10, 10, -5, 5, 0],\n transition: {\n duration: 0.6,\n ease: \"easeInOut\",\n },\n },\n};\n\nexport function NativeNotificationBell({\n count = 0,\n showBadge,\n onClick,\n onRing,\n icon,\n size = \"md\",\n className,\n}: NativeNotificationBellProps) {\n const shouldReduceMotion = useReducedMotion();\n const [isRinging, setIsRinging] = useState(false);\n const hasNotifications = count > 0 || showBadge;\n\n useEffect(() => {\n if (hasNotifications && !shouldReduceMotion) {\n setIsRinging(true);\n const timer = setTimeout(() => setIsRinging(false), 600);\n onRing?.();\n return () => clearTimeout(timer);\n }\n }, [hasNotifications, shouldReduceMotion, onRing]);\n\n const displayCount = count > 99 ? \"99+\" : count > 9 ? \"9+\" : count;\n\n return (\n
    \n 0 ? `, ${count} unread` : \"\"}`}\n >\n {icon ?? }\n {hasNotifications && (\n \n {count > 0 ? displayCount : \"\"}\n \n )}\n \n
    \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-notification-bell.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-profile-notch.json b/packages/registry/public/r/native-profile-notch.json deleted file mode 100644 index 6ebc2e5..0000000 --- a/packages/registry/public/r/native-profile-notch.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-profile-notch", - "type": "registry:component", - "title": "Native Profile Notch", - "description": "A dynamic expanding notch component for displaying user profiles with smooth spring animations.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-profile-notch-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { ChevronRight, X } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport interface NativeProfileNotchProps {\n /**\n * Url of the user image\n */\n imageSrc: string;\n /**\n * Name of the user\n */\n name: string;\n /**\n * Handle or role of the user\n */\n username: string;\n /**\n * Custom content to show in expanded state\n */\n children?: React.ReactNode;\n /**\n * Size of the notch\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Class name for the container\n */\n className?: string;\n /**\n * Variant of the notch.\n * \"default\": expands and pushes content.\n * \"overlay\": expands over content (absolute positioning).\n * @default \"default\"\n */\n variant?: \"default\" | \"overlay\";\n}\n\nexport function NativeProfileNotch({\n imageSrc,\n name,\n username,\n children,\n size = \"md\",\n className,\n variant = \"default\",\n}: NativeProfileNotchProps) {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n \n !isOpen && setIsOpen(true)}\n >\n \n {!isOpen ? (\n \n
    \n \n \n \n {name.slice(0, 2).toUpperCase()}\n \n \n
    \n \n {name}\n \n \n @{username}\n \n
    \n \n
    \n \n ) : (\n \n {/* Close Button */}\n {\n e.stopPropagation();\n setIsOpen(false);\n }}\n className=\"absolute top-4 right-4 p-1 rounded-full bg-muted/50 hover:bg-muted transition-colors z-10\"\n aria-label=\"Close profile\"\n >\n \n \n\n {/* Scrollable Content */}\n
    \n {/* Profile Header */}\n
    \n \n \n \n\n \n {name}\n \n\n \n @{username}\n \n
    \n\n {/* Custom Content */}\n \n {children}\n \n\n {/* Bottom Action */}\n \n {\n e.stopPropagation();\n }}\n >\n View Full Profile\n \n \n
    \n \n )}\n
    \n \n
    \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-profile-notch.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-start-now.json b/packages/registry/public/r/native-start-now.json deleted file mode 100644 index de2e4ef..0000000 --- a/packages/registry/public/r/native-start-now.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-start-now", - "type": "registry:component", - "title": "Native Start Now", - "description": "Animated button with sparkle effects, loading states, and smooth transitions for starting actions.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-start-now-shadcnui.tsx", - "content": "\"use client\";\n\nimport { NativeButton } from \"@/components/uitripled/native-button-shadcnui\";\nimport { cn } from \"@/lib/utils\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { ArrowRight, Loader2, Rocket } from \"lucide-react\";\nimport { ReactNode, useState } from \"react\";\n\nexport interface NativeStartNowProps {\n /**\n * Callback when start button is clicked\n */\n onStart: () => void | Promise;\n /**\n * Text to show on the button\n * Default: \"Start Now\"\n */\n label?: string;\n /**\n * Loading text during async action\n * Default: \"Starting...\"\n */\n loadingLabel?: string;\n /**\n * Success text after completion\n * Default: \"Let's Go!\"\n */\n successLabel?: string;\n /**\n * Size variant\n * Default: \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Show sparkle animation on hover\n * Default: true\n */\n showRocket?: boolean;\n /**\n * Icon to use for Rocket and success state\n * Default: Rocket icon\n */\n icon?: ReactNode;\n /**\n * Additional class names for the container\n */\n className?: string;\n /**\n * Disable the button\n */\n disabled?: boolean;\n /**\n * Variant style\n * Default: \"gradient\"\n */\n variant?: \"gradient\" | \"solid\" | \"outline\";\n}\n\nconst sizeVariants = {\n sm: \"h-9 px-4 text-sm\",\n default: \"h-11 px-6 text-base\",\n lg: \"h-14 px-8 text-lg\",\n};\n\nconst sizeMap = {\n sm: \"sm\" as const,\n md: \"default\" as const,\n lg: \"lg\" as const,\n};\n\nconst iconSizeVariants = {\n sm: \"h-3.5 w-3.5\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n default: \"h-4 w-4\",\n};\n\nexport function NativeStartNow({\n onStart,\n label = \"Start Now\",\n loadingLabel = \"Starting...\",\n successLabel = \"Let's Go!\",\n size = \"md\",\n showRocket = true,\n icon,\n className,\n disabled = false,\n variant = \"gradient\",\n}: NativeStartNowProps) {\n const [status, setStatus] = useState<\"idle\" | \"loading\" | \"success\">(\"idle\");\n const [isHovered, setIsHovered] = useState(false);\n\n const handleClick = async () => {\n if (disabled || status !== \"idle\") return;\n\n setStatus(\"loading\");\n try {\n await onStart();\n setStatus(\"success\");\n setTimeout(() => setStatus(\"idle\"), 2000);\n } catch (error) {\n setStatus(\"idle\");\n }\n };\n\n const getButtonStyles = () => {\n const baseStyles =\n \"relative overflow-hidden font-semibold transition-all duration-300\";\n\n switch (variant) {\n case \"gradient\":\n return cn(\n baseStyles,\n \"bg-gradient-to-r from-primary via-primary/90 to-primary text-primary-foreground\",\n \"hover:shadow-lg hover:shadow-primary/50\",\n \"border-0\"\n );\n case \"solid\":\n return cn(\n baseStyles,\n \"bg-primary text-primary-foreground\",\n \"hover:bg-primary/90\"\n );\n case \"outline\":\n return cn(\n baseStyles,\n \"border-2 border-primary text-primary bg-background\",\n \"hover:bg-primary hover:text-primary-foreground\"\n );\n default:\n return baseStyles;\n }\n };\n\n return (\n setIsHovered(true)}\n onHoverEnd={() => setIsHovered(false)}\n >\n {/* Sparkle particles */}\n \n {showRocket && isHovered && status === \"idle\" && (\n <>\n {[...Array(6)].map((_, i) => (\n \n
    \n {icon || (\n \n )}\n
    \n \n ))}\n \n )}\n
    \n\n \n {/* Shimmer effect */}\n {variant === \"gradient\" && status === \"idle\" && (\n \n )}\n\n {/* Button content */}\n \n {status === \"idle\" && (\n \n {label}\n \n \n \n \n )}\n\n {status === \"loading\" && (\n \n \n {loadingLabel}\n \n )}\n\n {status === \"success\" && (\n \n \n {icon || (\n \n )}\n \n {successLabel}\n \n )}\n \n \n \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-start-now.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-tabs.json b/packages/registry/public/r/native-tabs.json deleted file mode 100644 index 5b0bef3..0000000 --- a/packages/registry/public/r/native-tabs.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-tabs", - "type": "registry:component", - "title": "Native Tabs", - "description": "A sleek tabs component with a smooth sliding background indicator using Framer Motion layout animations.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-tabs-shadcnui.tsx", - "content": "\"use client\";\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport { useState } from \"react\";\n\ninterface NativeTabsProps {\n items: {\n id: string;\n label: string;\n content: React.ReactNode;\n }[];\n defaultValue?: string;\n className?: string;\n}\n\nexport function NativeTabs({\n items,\n defaultValue,\n className,\n}: NativeTabsProps) {\n const [activeTab, setActiveTab] = useState(defaultValue || items[0].id);\n\n return (\n \n \n {items.map((tab) => {\n const isActive = activeTab === tab.id;\n return (\n \n {isActive && (\n \n )}\n {tab.label}\n \n );\n })}\n \n {items.map((item) => (\n \n \n {item.content}\n \n \n ))}\n \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-tabs.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-tooltip.json b/packages/registry/public/r/native-tooltip.json deleted file mode 100644 index 691fb9f..0000000 --- a/packages/registry/public/r/native-tooltip.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-tooltip", - "type": "registry:component", - "title": "Native Tooltip", - "description": "A glassmorphism-styled tooltip with smooth spring animations using Framer Motion.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-tooltip-shadcnui.tsx", - "content": "\"use client\";\n\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport { motion } from \"framer-motion\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst NativeTooltipProvider = ({\n delayDuration = 100,\n ...props\n}: React.ComponentProps) => (\n \n);\n\nconst NativeTooltipRoot = TooltipPrimitive.Root;\n\nconst NativeTooltipTrigger = TooltipPrimitive.Trigger;\n\nconst NativeTooltipContent = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef & {\n animation?: \"blur\" | \"scale\";\n }\n>(\n (\n { className, sideOffset = 8, children, animation = \"blur\", ...props },\n ref\n ) => {\n const animations = {\n blur: {\n initial: { opacity: 0, scale: 0.9, filter: \"blur(4px)\" },\n animate: { opacity: 1, scale: 1, filter: \"blur(0px)\" },\n transition: { type: \"spring\", duration: 0.4, bounce: 0 } as any,\n },\n scale: {\n initial: { opacity: 0, scale: 0.5, y: 10 },\n animate: { opacity: 1, scale: 1, y: 0 },\n transition: { type: \"spring\", duration: 0.4, bounce: 0.4 } as any,\n },\n };\n\n const selectedAnimation = animations[animation];\n\n return (\n \n \n \n {children}\n \n \n \n );\n }\n);\nNativeTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nconst NativeTooltip = ({\n content,\n children,\n animation,\n ...props\n}: React.ComponentProps & {\n content?: React.ReactNode;\n animation?: \"blur\" | \"scale\";\n}) => {\n if (content) {\n return (\n \n {children}\n \n {content}\n \n \n );\n }\n\n return {children};\n};\n\nexport {\n NativeTooltip,\n NativeTooltipContent,\n NativeTooltipProvider,\n NativeTooltipTrigger,\n};\n", - "type": "registry:component", - "target": "components/uitripled/native-tooltip.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/native-typewriter-shadcnui.json b/packages/registry/public/r/native-typewriter-shadcnui.json new file mode 100644 index 0000000..7a61516 --- /dev/null +++ b/packages/registry/public/r/native-typewriter-shadcnui.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-typewriter-shadcnui", + "type": "registry:component", + "title": "Native Typewriter", + "description": "Typewriter effect with speed control, looping, and blinking cursor.", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/native-typewriter-carbon.tsx", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { useEffect, useState } from \"react\";\n\ninterface NativeTypewriterProps {\n /**\n * The text content to type. Can be a string or an array of strings.\n * If an array, it will type each string in sequence (or loop if loop=true).\n */\n content: string | string[];\n /**\n * Typing speed.\n * 'slow' = 100ms, 'medium' = 50ms, 'fast' = 30ms.\n * Or pass a number in ms.\n * Default: 'medium'\n */\n speed?: \"slow\" | \"medium\" | \"fast\" | number;\n /**\n * Whether to show a blinking cursor.\n * Default: true\n */\n cursor?: boolean;\n /**\n * Whether to loop the typing animation.\n * Default: false\n */\n loop?: boolean;\n /**\n * Delay before starting animation in ms.\n * Default: 0\n */\n startDelay?: number;\n /**\n * Whether to apply a blur/morph effect to each character.\n * Default: true\n */\n morph?: boolean;\n className?: string;\n}\n\nexport function NativeTypewriter({\n content,\n speed = \"medium\",\n cursor = true,\n loop = false,\n startDelay = 0,\n morph = true,\n className,\n}: NativeTypewriterProps) {\n const shouldReduceMotion = useReducedMotion();\n const [displayedText, setDisplayedText] = useState(\"\");\n const [isStarted, setIsStarted] = useState(false);\n\n // Calculate delay calculation\n const speedMap = {\n slow: 100,\n medium: 50,\n fast: 30,\n };\n const typingSpeed = typeof speed === \"number\" ? speed : speedMap[speed];\n\n useEffect(() => {\n // If reduced motion is enabled, just show the full text immediately\n if (shouldReduceMotion) {\n setDisplayedText(Array.isArray(content) ? content.join(\" \") : content);\n return;\n }\n\n let timeoutId: NodeJS.Timeout;\n let currentIndex = 0;\n let currentStringIndex = 0;\n\n // Normalize content to array\n const textArray = Array.isArray(content) ? content : [content];\n\n // Actually, simpler logic for a first pass is often better.\n // Let's implement a robust \"Type -> Wait -> (Delete if multi/loop) -> Next\" cycle.\n\n let isDeleting = false;\n\n // Unified typing loop logic\n const runLoop = () => {\n const currentString = textArray[currentStringIndex];\n\n if (isDeleting) {\n setDisplayedText(currentString.substring(0, currentIndex));\n currentIndex--;\n if (currentIndex < 0) {\n isDeleting = false;\n currentIndex = 0;\n currentStringIndex = (currentStringIndex + 1) % textArray.length;\n if (!loop && currentStringIndex === 0) {\n return;\n }\n timeoutId = setTimeout(runLoop, 500);\n } else {\n timeoutId = setTimeout(runLoop, typingSpeed / 2);\n }\n } else {\n setDisplayedText(currentString.substring(0, currentIndex + 1));\n currentIndex++;\n if (currentIndex > currentString.length) {\n if (\n (textArray.length > 1 &&\n (loop || currentStringIndex < textArray.length - 1)) ||\n (textArray.length === 1 && loop)\n ) {\n isDeleting = true;\n currentIndex = currentString.length;\n timeoutId = setTimeout(runLoop, 2000);\n }\n } else {\n timeoutId = setTimeout(runLoop, typingSpeed);\n }\n }\n };\n\n const initialTimer = setTimeout(() => {\n setIsStarted(true);\n runLoop();\n }, startDelay);\n\n return () => {\n clearTimeout(initialTimer);\n clearTimeout(timeoutId);\n };\n }, [content, typingSpeed, loop, startDelay, shouldReduceMotion]);\n\n return (\n
    \n \n {displayedText.split(\"\").map((char, index) => (\n \n {char}\n \n ))}\n \n {cursor && (\n \n )}\n
    \n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/native-typewriter-shadcnui.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-typewriter.json b/packages/registry/public/r/native-typewriter.json index 74078e8..8b66986 100644 --- a/packages/registry/public/r/native-typewriter.json +++ b/packages/registry/public/r/native-typewriter.json @@ -13,7 +13,7 @@ "path": "@uitripled/react-carbon/src/components/native/native-typewriter-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { useEffect, useState } from \"react\";\n\ninterface NativeTypewriterProps {\n /**\n * The text content to type. Can be a string or an array of strings.\n * If an array, it will type each string in sequence (or loop if loop=true).\n */\n content: string | string[];\n /**\n * Typing speed.\n * 'slow' = 100ms, 'medium' = 50ms, 'fast' = 30ms.\n * Or pass a number in ms.\n * Default: 'medium'\n */\n speed?: \"slow\" | \"medium\" | \"fast\" | number;\n /**\n * Whether to show a blinking cursor.\n * Default: true\n */\n cursor?: boolean;\n /**\n * Whether to loop the typing animation.\n * Default: false\n */\n loop?: boolean;\n /**\n * Delay before starting animation in ms.\n * Default: 0\n */\n startDelay?: number;\n /**\n * Whether to apply a blur/morph effect to each character.\n * Default: true\n */\n morph?: boolean;\n className?: string;\n}\n\nexport function NativeTypewriter({\n content,\n speed = \"medium\",\n cursor = true,\n loop = false,\n startDelay = 0,\n morph = true,\n className,\n}: NativeTypewriterProps) {\n const shouldReduceMotion = useReducedMotion();\n const [displayedText, setDisplayedText] = useState(\"\");\n const [isStarted, setIsStarted] = useState(false);\n\n // Calculate delay calculation\n const speedMap = {\n slow: 100,\n medium: 50,\n fast: 30,\n };\n const typingSpeed = typeof speed === \"number\" ? speed : speedMap[speed];\n\n useEffect(() => {\n // If reduced motion is enabled, just show the full text immediately\n if (shouldReduceMotion) {\n setDisplayedText(Array.isArray(content) ? content.join(\" \") : content);\n return;\n }\n\n let timeoutId: NodeJS.Timeout;\n let currentIndex = 0;\n let currentStringIndex = 0;\n\n // Normalize content to array\n const textArray = Array.isArray(content) ? content : [content];\n\n // Actually, simpler logic for a first pass is often better.\n // Let's implement a robust \"Type -> Wait -> (Delete if multi/loop) -> Next\" cycle.\n\n let isDeleting = false;\n\n // Unified typing loop logic\n const runLoop = () => {\n const currentString = textArray[currentStringIndex];\n\n if (isDeleting) {\n setDisplayedText(currentString.substring(0, currentIndex));\n currentIndex--;\n if (currentIndex < 0) {\n isDeleting = false;\n currentIndex = 0;\n currentStringIndex = (currentStringIndex + 1) % textArray.length;\n if (!loop && currentStringIndex === 0) {\n return;\n }\n timeoutId = setTimeout(runLoop, 500);\n } else {\n timeoutId = setTimeout(runLoop, typingSpeed / 2);\n }\n } else {\n setDisplayedText(currentString.substring(0, currentIndex + 1));\n currentIndex++;\n if (currentIndex > currentString.length) {\n if (\n (textArray.length > 1 &&\n (loop || currentStringIndex < textArray.length - 1)) ||\n (textArray.length === 1 && loop)\n ) {\n isDeleting = true;\n currentIndex = currentString.length;\n timeoutId = setTimeout(runLoop, 2000);\n }\n } else {\n timeoutId = setTimeout(runLoop, typingSpeed);\n }\n }\n };\n\n const initialTimer = setTimeout(() => {\n setIsStarted(true);\n runLoop();\n }, startDelay);\n\n return () => {\n clearTimeout(initialTimer);\n clearTimeout(timeoutId);\n };\n }, [content, typingSpeed, loop, startDelay, shouldReduceMotion]);\n\n return (\n
    \n \n {displayedText.split(\"\").map((char, index) => (\n \n {char}\n \n ))}\n \n {cursor && (\n \n )}\n
    \n );\n}\n", "type": "registry:component", - "target": "components/uitripled/native-typewriter.tsx" + "target": "components/uitripled/native-typewriter-carbon.tsx" } ] } \ No newline at end of file diff --git a/packages/registry/public/r/native-user-card-baseui.json b/packages/registry/public/r/native-user-card-baseui.json new file mode 100644 index 0000000..0be8afb --- /dev/null +++ b/packages/registry/public/r/native-user-card-baseui.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-user-card-baseui", + "type": "registry:component", + "title": "Native User Card", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI)", + "registryDependencies": [ + "button" + ], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-baseui/src/components/native/native-user-card-baseui.tsx", + "content": "\"use client\";\n\nimport { Avatar } from \"@base-ui/react/avatar\";\nimport { Button } from \"@base-ui/react/button\";\nimport { cn } from \"@/lib/utils\";\nimport { motion, MotionConfig } from \"framer-motion\";\nimport { ArrowRight } from \"lucide-react\";\n\ninterface NativeUserCardProps {\n imageSrc: string;\n name: string;\n handle: string;\n href?: string;\n onClick?: () => void;\n className?: string;\n}\n\nconst transition = {\n type: \"spring\" as const,\n stiffness: 400,\n damping: 30,\n};\n\nexport function NativeUserCard({\n imageSrc,\n name,\n handle,\n href = \"#\",\n onClick,\n className,\n}: NativeUserCardProps) {\n const CardContent = (\n \n
    \n
    \n \n \n \n {name.charAt(0)}\n \n \n
    \n\n
    \n

    \n {name}\n

    \n

    \n {handle}\n

    \n
    \n
    \n\n
    \n \n \n \n \n \n
    \n \n );\n\n return (\n \n {onClick ? (\n \n {CardContent}\n \n ) : (\n \n {CardContent}\n \n )}\n \n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/native-user-card-baseui.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-user-card-shadcnui.json b/packages/registry/public/r/native-user-card-shadcnui.json new file mode 100644 index 0000000..f77721a --- /dev/null +++ b/packages/registry/public/r/native-user-card-shadcnui.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "native-user-card-shadcnui", + "type": "registry:component", + "title": "Native User Card", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations", + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-shadcn/src/components/native/native-user-card-shadcnui.tsx", + "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport { ArrowRight } from \"lucide-react\";\nimport Link from \"next/link\";\n\ninterface NativeUserCardProps {\n imageSrc: string;\n name: string;\n handle: string;\n href?: string;\n onClick?: () => void;\n className?: string;\n}\n\nexport function NativeUserCard({\n imageSrc,\n name,\n handle,\n href = \"#\",\n onClick,\n className,\n}: NativeUserCardProps) {\n const CardContent = (\n \n
    \n
    \n \n \n {name.charAt(0)}\n \n
    \n\n
    \n

    \n {name}\n

    \n

    \n {handle}\n

    \n
    \n
    \n\n
    \n \n \n \n \n \n
    \n \n );\n\n if (onClick) {\n return (\n \n );\n }\n\n return (\n \n {CardContent}\n \n );\n}\n", + "type": "registry:component", + "target": "components/uitripled/native-user-card-shadcnui.tsx" + } + ] +} \ No newline at end of file diff --git a/packages/registry/public/r/native-verified-badge.json b/packages/registry/public/r/native-verified-badge.json deleted file mode 100644 index 47d3987..0000000 --- a/packages/registry/public/r/native-verified-badge.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "native-verified-badge", - "type": "registry:component", - "title": "Native Verified Badge", - "description": "Verified badge component with multiple variants, sizes, and styles including outline and shield designs.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-verified-badge-shadcnui.tsx", - "content": "\"use client\";\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\nimport type { ReactNode } from \"react\";\n\ntype BadgeVariant = \"default\" | \"blue\" | \"gold\" | \"green\" | \"black\";\ntype BadgeSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxl\";\n\ninterface VerifiedBadgeProps {\n variant?: BadgeVariant;\n size?: BadgeSize;\n className?: string;\n showLabel?: boolean;\n label?: string;\n icon?: ReactNode;\n tooltip?: string;\n}\n\nconst sizeClasses: Record<\n BadgeSize,\n { container: string; icon: string; text: string }\n> = {\n sm: { container: \"size-4\", icon: \"size-2\", text: \"text-xs\" },\n md: { container: \"size-5\", icon: \"size-2.5\", text: \"text-sm\" },\n lg: { container: \"size-6\", icon: \"size-3\", text: \"text-base\" },\n xl: { container: \"size-7\", icon: \"size-4\", text: \"text-lg\" },\n xxl: { container: \"size-8\", icon: \"size-5\", text: \"text-xl\" },\n};\n\nconst variantClasses: Record<\n BadgeVariant,\n { bg: string; icon: string; shine: string }\n> = {\n default: {\n bg: \"bg-foreground\",\n icon: \"text-background\",\n shine: \"from-transparent via-white/40 to-transparent\",\n },\n blue: {\n bg: \"bg-blue-500\",\n icon: \"text-white\",\n shine: \"from-transparent via-white/50 to-transparent\",\n },\n gold: {\n bg: \"bg-amber-500\",\n icon: \"text-white\",\n shine: \"from-transparent via-white/50 to-transparent\",\n },\n green: {\n bg: \"bg-emerald-500\",\n icon: \"text-white\",\n shine: \"from-transparent via-white/50 to-transparent\",\n },\n black: {\n bg: \"bg-black\",\n icon: \"text-white\",\n shine: \"from-transparent via-white/50 to-transparent\",\n },\n};\n\nfunction CheckIcon({ className }: { className?: string }) {\n return (\n \n \n \n );\n}\n\nfunction BadgeTooltip({\n children,\n content,\n}: {\n children: ReactNode;\n content?: string;\n}) {\n if (!content) return <>{children};\n\n return (\n \n \n {children}\n \n

    {content}

    \n
    \n
    \n
    \n );\n}\n\nexport function VerifiedBadge({\n variant = \"default\",\n size = \"md\",\n className,\n showLabel = false,\n label = \"Verified\",\n icon,\n tooltip,\n}: VerifiedBadgeProps) {\n const { bg, icon: iconColor, shine } = variantClasses[variant];\n const { container, icon: iconSize, text } = sizeClasses[size];\n\n return (\n \n \n \n {/* Shine effect on hover */}\n \n\n {icon ? (\n \n {icon}\n \n ) : (\n \n )}\n \n\n {showLabel && (\n \n {label}\n \n )}\n \n \n );\n}\n\nexport function VerifiedBadgeOutline({\n variant = \"default\",\n size = \"md\",\n className,\n icon,\n tooltip,\n}: Omit) {\n const { container, icon: iconSize } = sizeClasses[size];\n\n const colorClasses: Record = {\n default: {\n stroke: \"stroke-foreground\",\n text: \"text-foreground\",\n },\n blue: {\n stroke: \"stroke-blue-500\",\n text: \"text-blue-500\",\n },\n gold: {\n stroke: \"stroke-amber-500\",\n text: \"text-amber-500\",\n },\n green: {\n stroke: \"stroke-emerald-500\",\n text: \"text-emerald-500\",\n },\n black: {\n stroke: \"stroke-black\",\n text: \"text-black\",\n },\n };\n\n const { stroke, text } = colorClasses[variant];\n\n return (\n \n \n \n \n \n \n {icon ? (\n \n {icon}\n \n ) : (\n \n )}\n \n \n );\n}\n\nexport function VerifiedShieldBadge({\n variant = \"default\",\n size = \"md\",\n className,\n icon,\n tooltip,\n}: Omit) {\n const { bg, icon: iconColor } = variantClasses[variant];\n const { icon: iconSize } = sizeClasses[size];\n\n const sizeMap: Record = {\n sm: \"size-5\",\n md: \"size-6\",\n lg: \"size-7\",\n xl: \"size-8\",\n xxl: \"size-9\",\n };\n\n return (\n \n \n \n \n \n \n \n \n {/* Shield background */}\n \n {/* Shine effect */}\n \n \n {icon ? (\n \n {icon}\n \n ) : (\n \n )}\n \n \n );\n}\n", - "type": "registry:component", - "target": "components/uitripled/native-verified-badge.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/public/r/pricing-section-baseui.json b/packages/registry/public/r/pricing-section-baseui.json index 2112083..c8d648c 100644 --- a/packages/registry/public/r/pricing-section-baseui.json +++ b/packages/registry/public/r/pricing-section-baseui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-baseui/src/components/sections/pricing-section-baseui.tsx", - "content": "\"use client\";\n\nimport { Button } from \"@base-ui/react/button\";\nimport { motion, useInView } from \"framer-motion\";\nimport { Check, Zap } from \"lucide-react\";\nimport { useRef } from \"react\";\n\nconst plans = [\n {\n name: \"Starter\",\n price: \"$0\",\n period: \"/month\",\n description: \"Perfect for personal projects\",\n features: [\n \"10 Components\",\n \"Community Support\",\n \"Basic Animations\",\n \"Documentation\",\n ],\n popular: false,\n },\n {\n name: \"Pro\",\n price: \"$29\",\n period: \"/month\",\n description: \"Best for growing businesses\",\n features: [\n \"50+ Components\",\n \"Priority Support\",\n \"Advanced Animations\",\n \"Source Code\",\n \"Custom Requests\",\n ],\n popular: true,\n },\n {\n name: \"Enterprise\",\n price: \"$99\",\n period: \"/month\",\n description: \"For large-scale applications\",\n features: [\n \"Unlimited Components\",\n \"24/7 Support\",\n \"Premium Animations\",\n \"White-label\",\n \"Dedicated Team\",\n ],\n popular: false,\n },\n];\n\nexport function PricingSectionBaseui() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true });\n\n return (\n
    \n
    \n \n

    \n Simple, Transparent Pricing\n

    \n

    \n Choose the perfect plan for your needs\n

    \n \n\n
    \n {plans.map((plan, index) => (\n \n \n {plan.popular && (\n \n \n \n Popular\n \n \n )}\n\n
    \n

    \n {plan.name}\n

    \n

    \n {plan.description}\n

    \n
    \n {plan.price}\n \n {plan.period}\n \n
    \n
    \n\n
    \n
      \n {plan.features.map((feature, featureIndex) => (\n \n \n \n \n {feature}\n \n ))}\n
    \n\n \n Get Started\n \n
    \n
    \n \n ))}\n
    \n
    \n
    \n );\n}\n", + "content": "\"use client\";\n\nimport { Button } from \"@base-ui/react/button\";\nimport { motion, useInView } from \"framer-motion\";\nimport { Check } from \"lucide-react\";\nimport { useRef } from \"react\";\n\nconst plans = [\n {\n name: \"Starter\",\n price: \"$0\",\n period: \"/month\",\n description: \"Perfect for personal projects\",\n features: [\n \"10 Components\",\n \"Community Support\",\n \"Basic Animations\",\n \"Documentation\",\n ],\n popular: false,\n },\n {\n name: \"Pro\",\n price: \"$29\",\n period: \"/month\",\n description: \"Best for growing businesses\",\n features: [\n \"50+ Components\",\n \"Priority Support\",\n \"Advanced Animations\",\n \"Source Code\",\n \"Custom Requests\",\n ],\n popular: true,\n },\n {\n name: \"Enterprise\",\n price: \"$99\",\n period: \"/month\",\n description: \"For large-scale applications\",\n features: [\n \"Unlimited Components\",\n \"24/7 Support\",\n \"Premium Animations\",\n \"White-label\",\n \"Dedicated Team\",\n ],\n popular: false,\n },\n];\n\nexport function PricingSectionBaseui() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-100px\" });\n\n return (\n \n
    \n \n \n Simple, transparent pricing\n \n

    \n Choose the plan that's right for you\n

    \n \n\n
    \n {plans.map((plan, index) => (\n \n \n {plan.popular && (\n
    \n \n Popular\n \n
    \n )}\n\n
    \n

    \n {plan.name}\n

    \n
    \n \n {plan.price}\n \n \n {plan.period}\n \n
    \n

    \n {plan.description}\n

    \n
    \n\n
    \n \n {plan.features.map((feature) => (\n \n \n \n
    \n {feature}\n \n ))}\n \n\n \n {plan.name === \"Enterprise\"\n ? \"Contact Sales\"\n : \"Get Started\"}\n \n
    \n
    \n \n ))}\n
    \n
    \n \n );\n}\n", "type": "registry:page", "target": "components/uitripled/pricing-section-baseui.tsx" } diff --git a/packages/registry/public/r/pricing-section-shadcnui.json b/packages/registry/public/r/pricing-section-shadcnui.json index 6724146..a064a24 100644 --- a/packages/registry/public/r/pricing-section-shadcnui.json +++ b/packages/registry/public/r/pricing-section-shadcnui.json @@ -11,7 +11,7 @@ "files": [ { "path": "@uitripled/react-shadcn/src/components/sections/pricing-section.tsx", - "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { motion, useInView } from \"framer-motion\";\nimport { Check, Zap } from \"lucide-react\";\nimport { useRef } from \"react\";\n\nconst plans = [\n {\n name: \"Starter\",\n price: \"$0\",\n period: \"/month\",\n description: \"Perfect for personal projects\",\n features: [\n \"10 Components\",\n \"Community Support\",\n \"Basic Animations\",\n \"Documentation\",\n ],\n popular: false,\n },\n {\n name: \"Pro\",\n price: \"$29\",\n period: \"/month\",\n description: \"Best for growing businesses\",\n features: [\n \"50+ Components\",\n \"Priority Support\",\n \"Advanced Animations\",\n \"Source Code\",\n \"Custom Requests\",\n ],\n popular: true,\n },\n {\n name: \"Enterprise\",\n price: \"$99\",\n period: \"/month\",\n description: \"For large-scale applications\",\n features: [\n \"Unlimited Components\",\n \"24/7 Support\",\n \"Premium Animations\",\n \"White-label\",\n \"Dedicated Team\",\n ],\n popular: false,\n },\n];\n\nexport function PricingSection() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true });\n\n return (\n
    \n
    \n \n

    \n Simple, Transparent Pricing\n

    \n

    \n Choose the perfect plan for your needs\n

    \n \n\n
    \n {plans.map((plan, index) => (\n \n \n {plan.popular && (\n \n \n \n Popular\n \n \n )}\n\n \n {plan.name}\n {plan.description}\n
    \n {plan.price}\n \n {plan.period}\n \n
    \n
    \n\n \n
      \n {plan.features.map((feature, featureIndex) => (\n \n \n \n \n {feature}\n \n ))}\n
    \n\n \n Get Started\n \n
    \n \n \n ))}\n
    \n
    \n
    \n );\n}\n", + "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { motion, useInView } from \"framer-motion\";\nimport { Check } from \"lucide-react\";\nimport { useRef } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst plans = [\n {\n name: \"Starter\",\n price: \"$0\",\n period: \"/month\",\n description: \"Perfect for personal projects\",\n features: [\n \"10 Components\",\n \"Community Support\",\n \"Basic Animations\",\n \"Documentation\",\n ],\n popular: false,\n },\n {\n name: \"Pro\",\n price: \"$29\",\n period: \"/month\",\n description: \"Best for growing businesses\",\n features: [\n \"50+ Components\",\n \"Priority Support\",\n \"Advanced Animations\",\n \"Source Code\",\n \"Custom Requests\",\n ],\n popular: true,\n },\n {\n name: \"Enterprise\",\n price: \"$99\",\n period: \"/month\",\n description: \"For large-scale applications\",\n features: [\n \"Unlimited Components\",\n \"24/7 Support\",\n \"Premium Animations\",\n \"White-label\",\n \"Dedicated Team\",\n ],\n popular: false,\n },\n];\n\nexport function PricingSection() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-100px\" });\n\n return (\n \n
    \n \n \n Simple, transparent pricing\n \n

    \n Choose the plan that's right for you\n

    \n \n\n
    \n {plans.map((plan, index) => (\n \n \n {plan.popular && (\n
    \n \n Popular\n \n
    \n )}\n\n \n \n {plan.name}\n \n
    \n \n {plan.price}\n \n \n {plan.period}\n \n
    \n \n {plan.description}\n \n
    \n\n \n \n {plan.features.map((feature) => (\n \n \n \n
    \n {feature}\n \n ))}\n \n\n \n {plan.name === \"Enterprise\" ? \"Contact Sales\" : \"Get Started\"}\n \n \n \n \n ))}\n
    \n
    \n \n );\n}\n", "type": "registry:page", "target": "components/uitripled/pricing-section-shadcnui.tsx" } diff --git a/packages/registry/public/r/registry.json b/packages/registry/public/r/registry.json index ebe67bc..e48a1ee 100644 --- a/packages/registry/public/r/registry.json +++ b/packages/registry/public/r/registry.json @@ -1301,6 +1301,28 @@ "category": "components", "subcategory": null }, + { + "name": "dashboard-baseui", + "type": "registry:block", + "title": "Dashboard", + "description": "Interactive stock portfolio dashboard with status cards, data table, and detailed stock information modal (Base UI)", + "registryDependencies": [ + "button" + ], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-baseui/src/components/stocks-dashboard/dashboard-baseui.tsx", + "type": "registry:block", + "target": "components/uitripled/dashboard-baseui.tsx" + } + ], + "category": "sections", + "subcategory": null + }, { "name": "dashboard-shadcnui", "type": "registry:block", @@ -1878,6 +1900,46 @@ "category": "components", "subcategory": "modal" }, + { + "name": "folder-animation", + "type": "registry:ui", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:ui", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "decorative", + "subcategory": null + }, + { + "name": "folder-animation-carbon", + "type": "registry:component", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:component", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "native", + "subcategory": null + }, { "name": "footer-block-baseui", "type": "registry:block", @@ -3306,26 +3368,6 @@ "category": "sections", "subcategory": null }, - { - "name": "native-avatar-expand", - "type": "registry:component", - "title": "Native Avatar Expand", - "description": "Avatar component that expands to reveal the name on click with smooth animations.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-avatar-expand-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-avatar-expand.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-avatar-expand-baseui", "type": "registry:component", @@ -3368,26 +3410,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-avatar-with-name", - "type": "registry:component", - "title": "Native Avatar With Name", - "description": "Avatar component that displays a name tooltip on hover with directional animations.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-avatar-with-name-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-avatar-with-name.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-avatar-with-name-baseui", "type": "registry:component", @@ -3444,7 +3466,7 @@ { "path": "@uitripled/react-carbon/src/components/native/native-badge-carbon.tsx", "type": "registry:component", - "target": "components/uitripled/native-badge.tsx" + "target": "components/uitripled/native-badge-carbon.tsx" } ], "category": "native", @@ -3470,26 +3492,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-button", - "type": "registry:component", - "title": "Native Button", - "description": "Glassmorphism-inspired button component based on shadcn/ui with smooth animations and modern styling", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-button-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-button.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-button-baseui", "type": "registry:component", @@ -3546,7 +3548,7 @@ { "path": "@uitripled/react-carbon/src/components/native/native-counter-up-carbon.tsx", "type": "registry:component", - "target": "components/uitripled/native-counter-up.tsx" + "target": "components/uitripled/native-counter-up-carbon.tsx" } ], "category": "native", @@ -3572,26 +3574,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-delete", - "type": "registry:component", - "title": "Native Delete", - "description": "Delete button that expands to show a confirmation button with smooth animations.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-delete-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-delete.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-delete-baseui", "type": "registry:component", @@ -3634,26 +3616,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-dialog", - "type": "registry:component", - "title": "Native Dialog", - "description": "A glassmorphism-styled dialog component with backdrop blur and smooth animations, inspired by native OS modals.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-dialog-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-dialog.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-dialog-baseui", "type": "registry:component", @@ -3710,7 +3672,29 @@ { "path": "@uitripled/react-carbon/src/components/native/native-flip-text-carbon.tsx", "type": "registry:component", - "target": "components/uitripled/native-flip-text.tsx" + "target": "components/uitripled/native-flip-text-carbon.tsx" + } + ], + "category": "native", + "subcategory": null + }, + { + "name": "native-flip-text-baseui", + "type": "registry:component", + "title": "Native Flip Text", + "description": "Text that flips through words with a 3D blur transition. (Base UI)", + "registryDependencies": [ + "button" + ], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/native-flip-text-carbon-baseui.tsx", + "type": "registry:component", + "target": "components/uitripled/native-flip-text-baseui.tsx" } ], "category": "native", @@ -3736,6 +3720,26 @@ "category": "native", "subcategory": null }, + { + "name": "native-flip-text-shadcnui", + "type": "registry:component", + "title": "Native Flip Text", + "description": "Text that flips through words with a 3D blur transition.", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/native-flip-text-carbon.tsx", + "type": "registry:component", + "target": "components/uitripled/native-flip-text-shadcnui.tsx" + } + ], + "category": "native", + "subcategory": null + }, { "name": "native-follow-cursor", "type": "registry:component", @@ -3776,26 +3780,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-hover-card", - "type": "registry:component", - "title": "Native Hover Card", - "description": "Avatar card that expands on hover to reveal profile information with smooth animations.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-hover-card-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-hover-card.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-hover-card-baseui", "type": "registry:component", @@ -3838,26 +3822,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-image-checkbox", - "type": "registry:component", - "title": "Native Image Checkbox", - "description": "Image checkbox component with grayscale filter and checkmark indicator.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-image-checkbox-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-image-checkbox.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-image-checkbox-baseui", "type": "registry:component", @@ -3920,26 +3884,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-likes-counter", - "type": "registry:component", - "title": "Native Likes Counter", - "description": "An interactive likes counter with avatar stack, popup details, and smooth animations.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-likes-counter-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-likes-counter.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-likes-counter-baseui", "type": "registry:component", @@ -3982,26 +3926,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-liquid-button", - "type": "registry:component", - "title": "Native Liquid Button", - "description": "Button with animated liquid fill effect, progress tracking, and multiple visual variants for engaging interactions.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-liquid-button-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-liquid-button.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-liquid-button-baseui", "type": "registry:component", @@ -4058,7 +3982,7 @@ { "path": "@uitripled/react-carbon/src/components/native/native-magnetic-carbon.tsx", "type": "registry:component", - "target": "components/uitripled/native-magnetic.tsx" + "target": "components/uitripled/native-magnetic-carbon.tsx" } ], "category": "native", @@ -4126,26 +4050,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-morphing-button", - "type": "registry:component", - "title": "Native Morphing Button", - "description": "Floating action button that morphs into a menu of actions.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-morphing-button-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-morphing-button.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-morphing-button-baseui", "type": "registry:component", @@ -4208,26 +4112,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-nested-list", - "type": "registry:component", - "title": "Native Nested List", - "description": "A nested list component with smooth expand/collapse animations, perfect for file explorers or navigation menus.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-nested-list-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-nested-list.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-nested-list-baseui", "type": "registry:component", @@ -4251,10 +4135,10 @@ "subcategory": null }, { - "name": "native-notification-bell", + "name": "native-nested-list-shadcnui", "type": "registry:component", - "title": "Native Notification Bell", - "description": "Animated notification bell with badge and ringing effect.", + "title": "Native Nested List", + "description": "A nested list component with smooth expand/collapse animations, perfect for file explorers or navigation menus.", "registryDependencies": [], "dependencies": [ "framer-motion", @@ -4262,9 +4146,51 @@ ], "files": [ { - "path": "@uitripled/react-shadcn/src/components/native/native-notification-bell-shadcnui.tsx", + "path": "@uitripled/react-shadcn/src/components/native/native-nested-list-shadcnui.tsx", "type": "registry:component", - "target": "components/uitripled/native-notification-bell.tsx" + "target": "components/uitripled/native-nested-list-shadcnui.tsx" + } + ], + "category": "native", + "subcategory": null + }, + { + "name": "native-notch-baseui", + "type": "registry:component", + "title": "Native Notch", + "description": "Dynamic Island-inspired notch component with smooth spring animations, draggable physics, and expandable content area (Base UI)", + "registryDependencies": [ + "button" + ], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-baseui/src/components/native/native-notch-baseui.tsx", + "type": "registry:component", + "target": "components/uitripled/native-notch-baseui.tsx" + } + ], + "category": "native", + "subcategory": null + }, + { + "name": "native-notch-shadcnui", + "type": "registry:component", + "title": "Native Notch", + "description": "Dynamic Island-inspired notch component with smooth spring animations, draggable physics, and expandable content area", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-shadcn/src/components/native/native-notch-shadcnui.tsx", + "type": "registry:component", + "target": "components/uitripled/native-notch-shadcnui.tsx" } ], "category": "native", @@ -4332,26 +4258,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-profile-notch", - "type": "registry:component", - "title": "Native Profile Notch", - "description": "A dynamic expanding notch component for displaying user profiles with smooth spring animations.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-profile-notch-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-profile-notch.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-profile-notch-baseui", "type": "registry:component", @@ -4394,26 +4300,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-start-now", - "type": "registry:component", - "title": "Native Start Now", - "description": "Animated button with sparkle effects, loading states, and smooth transitions for starting actions.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-start-now-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-start-now.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-start-now-baseui", "type": "registry:component", @@ -4456,26 +4342,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-tabs", - "type": "registry:component", - "title": "Native Tabs", - "description": "A sleek tabs component with a smooth sliding background indicator using Framer Motion layout animations.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-tabs-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-tabs.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-tabs-baseui", "type": "registry:component", @@ -4538,26 +4404,6 @@ "category": "native", "subcategory": null }, - { - "name": "native-tooltip", - "type": "registry:component", - "title": "Native Tooltip", - "description": "A glassmorphism-styled tooltip with smooth spring animations using Framer Motion.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/native-tooltip-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/native-tooltip.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "native-tooltip-baseui", "type": "registry:component", @@ -4614,7 +4460,7 @@ { "path": "@uitripled/react-carbon/src/components/native/native-typewriter-carbon.tsx", "type": "registry:component", - "target": "components/uitripled/native-typewriter.tsx" + "target": "components/uitripled/native-typewriter-carbon.tsx" } ], "category": "native", @@ -4643,10 +4489,10 @@ "subcategory": null }, { - "name": "native-verified-badge", + "name": "native-typewriter-shadcnui", "type": "registry:component", - "title": "Native Verified Badge", - "description": "Verified badge component with multiple variants, sizes, and styles including outline and shield designs.", + "title": "Native Typewriter", + "description": "Typewriter effect with speed control, looping, and blinking cursor.", "registryDependencies": [], "dependencies": [ "framer-motion", @@ -4654,14 +4500,56 @@ ], "files": [ { - "path": "@uitripled/react-shadcn/src/components/native/native-verified-badge-shadcnui.tsx", + "path": "@uitripled/react-carbon/src/components/native/native-typewriter-carbon.tsx", "type": "registry:component", - "target": "components/uitripled/native-verified-badge.tsx" + "target": "components/uitripled/native-typewriter-shadcnui.tsx" } ], "category": "native", "subcategory": null }, + { + "name": "native-user-card-baseui", + "type": "registry:component", + "title": "Native User Card", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI)", + "registryDependencies": [ + "button" + ], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-baseui/src/components/native/native-user-card-baseui.tsx", + "type": "registry:component", + "target": "components/uitripled/native-user-card-baseui.tsx" + } + ], + "category": "cards", + "subcategory": null + }, + { + "name": "native-user-card-shadcnui", + "type": "registry:component", + "title": "Native User Card", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-shadcn/src/components/native/native-user-card-shadcnui.tsx", + "type": "registry:component", + "target": "components/uitripled/native-user-card-shadcnui.tsx" + } + ], + "category": "cards", + "subcategory": null + }, { "name": "native-verified-badge-baseui", "type": "registry:component", @@ -5429,26 +5317,6 @@ "category": "components", "subcategory": null }, - { - "name": "social-login-button", - "type": "registry:component", - "title": "Social Login Button", - "description": "A set of animated social login buttons for major platforms (Github, Google, X, etc.) with various effects.", - "registryDependencies": [], - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/social-login-button-shadcnui.tsx", - "type": "registry:component", - "target": "components/uitripled/social-login-button.tsx" - } - ], - "category": "native", - "subcategory": null - }, { "name": "social-login-button-baseui", "type": "registry:component", diff --git a/packages/registry/public/r/scroll-reveal-baseui.json b/packages/registry/public/r/scroll-reveal-baseui.json index 3fc2dd3..334bcee 100644 --- a/packages/registry/public/r/scroll-reveal-baseui.json +++ b/packages/registry/public/r/scroll-reveal-baseui.json @@ -14,7 +14,7 @@ "files": [ { "path": "@uitripled/react-baseui/src/components/sections/scroll-reveal-baseui.tsx", - "content": "\"use client\";\n\nimport {\n motion,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { Rocket, Shield, Zap } from \"lucide-react\";\nimport { useId, useMemo, useRef } from \"react\";\n\nconst features = [\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description:\n \"GPU-accelerated pipelines and finely tuned transitions keep every interaction responsive.\",\n },\n {\n icon: Shield,\n title: \"Secure by Default\",\n description:\n \"Enterprise-grade auth, encryption, and auditability woven through every flow.\",\n },\n {\n icon: Rocket,\n title: \"Effortlessly Scalable\",\n description:\n \"Composable primitives that adapt across teams, products, and global rollouts.\",\n },\n];\n\nexport function ScrollRevealBaseui() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-15% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n\n const headingId = useId();\n const descriptionId = useMemo(() => `${headingId}-description`, [headingId]);\n\n const containerVariants: Variants = useMemo(\n (): Variants => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 24,\n },\n visible: {\n opacity: 1,\n y: 0,\n transition: shouldReduceMotion\n ? { duration: 0 }\n : {\n duration: 0.6,\n ease: \"easeOut\",\n staggerChildren: 0.14,\n delayChildren: 0.12,\n },\n },\n }),\n [shouldReduceMotion]\n );\n\n const cardVariants: Variants = useMemo(\n () => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 28,\n filter: shouldReduceMotion ? \"none\" : \"blur(6px)\",\n },\n visible: {\n opacity: 1,\n y: 0,\n filter: \"none\",\n transition: shouldReduceMotion\n ? { duration: 0 }\n : { type: \"spring\", stiffness: 160, damping: 22, mass: 0.8 },\n },\n }),\n [shouldReduceMotion]\n );\n\n const iconVariants: Variants = useMemo(\n () => ({\n hidden: {\n scale: shouldReduceMotion ? 1 : 0.6,\n opacity: shouldReduceMotion ? 1 : 0,\n },\n visible: {\n scale: 1,\n opacity: 1,\n transition: shouldReduceMotion\n ? { duration: 0 }\n : { duration: 0.45, ease: [0.18, 0.89, 0.32, 1.28] },\n },\n }),\n [shouldReduceMotion]\n );\n\n return (\n \n \n \n \n
    \n\n \n \n \n Core System\n \n \n \n Features that elevate every launch\n \n \n A glassmorphic toolkit engineered for motion-rich dashboards,\n glowing handoffs, and resilient product experiences at scale.\n \n \n\n \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n \n \n
    \n \n \n \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n \n );\n })}\n \n \n \n );\n}\n", + "content": "\"use client\";\n\nimport {\n AnimatePresence,\n motion,\n MotionConfig,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { Rocket, Shield, Zap } from \"lucide-react\";\nimport { useId, useMemo, useRef } from \"react\";\n\nconst motionPresets = {\n smooth: { type: \"spring\" as const, bounce: 0.3, duration: 0.4 },\n bounce: { type: \"spring\" as const, bounce: 0.5, duration: 0.35 },\n fade: { type: \"tween\" as const, ease: [0.26, 0.08, 0.25, 1] as const, duration: 0.2 },\n};\n\nconst features = [\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description:\n \"GPU-accelerated pipelines and finely tuned transitions keep every interaction responsive.\",\n },\n {\n icon: Shield,\n title: \"Secure by Default\",\n description:\n \"Enterprise-grade auth, encryption, and auditability woven through every flow.\",\n },\n {\n icon: Rocket,\n title: \"Effortlessly Scalable\",\n description:\n \"Composable primitives that adapt across teams, products, and global rollouts.\",\n },\n];\n\ninterface ScrollRevealBaseuiProps {\n motionPreset?: keyof typeof motionPresets;\n className?: string;\n}\n\nexport function ScrollRevealBaseui({\n motionPreset = \"smooth\",\n className = \"\",\n}: ScrollRevealBaseuiProps) {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-15% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n\n const headingId = useId();\n const descriptionId = useMemo(() => `${headingId}-description`, [headingId]);\n\n const reducedMotionVariants: Variants = {\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n };\n\n const containerVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n },\n [shouldReduceMotion]\n );\n\n const itemVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.4 },\n },\n },\n [shouldReduceMotion]\n );\n\n const cardVariants: Variants = {\n idle: { y: 0 },\n hover: { y: -4 },\n };\n\n const iconVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { scale: 0.6, opacity: 0 },\n visible: {\n scale: 1,\n opacity: 1,\n transition: { duration: 0.4, ease: [0.18, 0.89, 0.32, 1.28] },\n },\n },\n [shouldReduceMotion]\n );\n\n return (\n \n \n \n {/* Header section */}\n \n \n Core System\n \n \n \n Features that elevate every launch\n \n \n A glassmorphic toolkit engineered for motion-rich dashboards,\n glowing handoffs, and resilient product experiences at scale.\n \n \n\n {/* Feature cards grid */}\n \n \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n {/* Hover gradient overlay */}\n
    \n\n {/* Icon container */}\n \n \n \n\n {/* Content */}\n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n \n );\n })}\n \n \n \n \n \n );\n}\n\n", "type": "registry:page", "target": "components/uitripled/scroll-reveal-baseui.tsx" } diff --git a/packages/registry/public/r/scroll-reveal-shadcnui.json b/packages/registry/public/r/scroll-reveal-shadcnui.json index 2ba0279..3826311 100644 --- a/packages/registry/public/r/scroll-reveal-shadcnui.json +++ b/packages/registry/public/r/scroll-reveal-shadcnui.json @@ -11,7 +11,7 @@ "files": [ { "path": "@uitripled/react-shadcn/src/components/sections/scroll-reveal.tsx", - "content": "\"use client\";\n\nimport {\n motion,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { Rocket, Shield, Zap } from \"lucide-react\";\nimport { useId, useMemo, useRef } from \"react\";\n\nconst features = [\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description:\n \"GPU-accelerated pipelines and finely tuned transitions keep every interaction responsive.\",\n },\n {\n icon: Shield,\n title: \"Secure by Default\",\n description:\n \"Enterprise-grade auth, encryption, and auditability woven through every flow.\",\n },\n {\n icon: Rocket,\n title: \"Effortlessly Scalable\",\n description:\n \"Composable primitives that adapt across teams, products, and global rollouts.\",\n },\n];\n\nexport function ScrollReveal() {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-15% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n\n const headingId = useId();\n const descriptionId = useMemo(() => `${headingId}-description`, [headingId]);\n\n const containerVariants: Variants = useMemo(\n (): Variants => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 24,\n },\n visible: {\n opacity: 1,\n y: 0,\n transition: shouldReduceMotion\n ? { duration: 0 }\n : {\n duration: 0.6,\n ease: \"easeOut\",\n staggerChildren: 0.14,\n delayChildren: 0.12,\n },\n },\n }),\n [shouldReduceMotion]\n );\n\n const cardVariants: Variants = useMemo(\n () => ({\n hidden: {\n opacity: shouldReduceMotion ? 1 : 0,\n y: shouldReduceMotion ? 0 : 28,\n filter: shouldReduceMotion ? \"none\" : \"blur(6px)\",\n },\n visible: {\n opacity: 1,\n y: 0,\n filter: \"none\",\n transition: shouldReduceMotion\n ? { duration: 0 }\n : { type: \"spring\", stiffness: 160, damping: 22, mass: 0.8 },\n },\n }),\n [shouldReduceMotion]\n );\n\n const iconVariants: Variants = useMemo(\n () => ({\n hidden: {\n scale: shouldReduceMotion ? 1 : 0.6,\n opacity: shouldReduceMotion ? 1 : 0,\n },\n visible: {\n scale: 1,\n opacity: 1,\n transition: shouldReduceMotion\n ? { duration: 0 }\n : { duration: 0.45, ease: [0.18, 0.89, 0.32, 1.28] },\n },\n }),\n [shouldReduceMotion]\n );\n\n return (\n \n \n \n \n
    \n\n \n \n \n Core System\n \n \n \n Features that elevate every launch\n \n \n A glassmorphic toolkit engineered for motion-rich dashboards,\n glowing handoffs, and resilient product experiences at scale.\n \n \n\n \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n \n \n
    \n \n \n \n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n \n );\n })}\n \n \n \n );\n}\n", + "content": "\"use client\";\n\nimport {\n AnimatePresence,\n motion,\n MotionConfig,\n useInView,\n useReducedMotion,\n type Variants,\n} from \"framer-motion\";\nimport { Rocket, Shield, Zap } from \"lucide-react\";\nimport { useId, useMemo, useRef } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst motionPresets = {\n smooth: { type: \"spring\" as const, bounce: 0.3, duration: 0.4 },\n bounce: { type: \"spring\" as const, bounce: 0.5, duration: 0.35 },\n fade: { type: \"tween\" as const, ease: [0.26, 0.08, 0.25, 1] as const, duration: 0.2 },\n};\n\nconst features = [\n {\n icon: Zap,\n title: \"Lightning Fast\",\n description:\n \"GPU-accelerated pipelines and finely tuned transitions keep every interaction responsive.\",\n },\n {\n icon: Shield,\n title: \"Secure by Default\",\n description:\n \"Enterprise-grade auth, encryption, and auditability woven through every flow.\",\n },\n {\n icon: Rocket,\n title: \"Effortlessly Scalable\",\n description:\n \"Composable primitives that adapt across teams, products, and global rollouts.\",\n },\n];\n\ninterface ScrollRevealProps {\n motionPreset?: keyof typeof motionPresets;\n className?: string;\n}\n\nexport function ScrollReveal({\n motionPreset = \"smooth\",\n className,\n}: ScrollRevealProps) {\n const ref = useRef(null);\n const isInView = useInView(ref, { once: true, margin: \"-15% 0px\" });\n const shouldReduceMotion = useReducedMotion();\n\n const headingId = useId();\n const descriptionId = useMemo(() => `${headingId}-description`, [headingId]);\n\n const reducedMotionVariants: Variants = {\n hidden: { opacity: 0 },\n visible: { opacity: 1 },\n };\n\n const containerVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n },\n [shouldReduceMotion]\n );\n\n const itemVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.4 },\n },\n },\n [shouldReduceMotion]\n );\n\n const cardVariants: Variants = {\n idle: { y: 0 },\n hover: { y: -4 },\n };\n\n const iconVariants: Variants = useMemo(\n () =>\n shouldReduceMotion\n ? reducedMotionVariants\n : {\n hidden: { scale: 0.6, opacity: 0 },\n visible: {\n scale: 1,\n opacity: 1,\n transition: { duration: 0.4, ease: [0.18, 0.89, 0.32, 1.28] },\n },\n },\n [shouldReduceMotion]\n );\n\n return (\n \n \n \n {/* Header section */}\n \n \n Core System\n \n \n \n Features that elevate every launch\n \n \n A glassmorphic toolkit engineered for motion-rich dashboards,\n glowing handoffs, and resilient product experiences at scale.\n \n \n\n {/* Feature cards grid */}\n \n \n {features.map((feature, index) => {\n const Icon = feature.icon;\n return (\n \n {/* Hover gradient overlay */}\n
    \n\n {/* Icon container */}\n \n \n \n\n {/* Content */}\n
    \n

    \n {feature.title}\n

    \n

    \n {feature.description}\n

    \n
    \n \n );\n })}\n \n \n \n \n \n );\n}\n\n", "type": "registry:page", "target": "components/uitripled/scroll-reveal-shadcnui.tsx" } diff --git a/packages/registry/public/r/social-login-button.json b/packages/registry/public/r/social-login-button.json deleted file mode 100644 index 4c7488e..0000000 --- a/packages/registry/public/r/social-login-button.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema/registry-item.json", - "name": "social-login-button", - "type": "registry:component", - "title": "Social Login Button", - "description": "A set of animated social login buttons for major platforms (Github, Google, X, etc.) with various effects.", - "dependencies": [ - "framer-motion", - "react" - ], - "files": [ - { - "path": "@uitripled/react-shadcn/src/components/native/social-login-button-shadcnui.tsx", - "content": "import { Button, ButtonProps } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport { Chrome, Github, Linkedin, Triangle, Twitter } from \"lucide-react\";\nimport { ReactNode } from \"react\";\n\nexport type SocialProvider = \"github\" | \"google\" | \"x\" | \"vercel\" | \"linkedin\";\nexport type SocialAnimation = \"slide\" | \"scale\" | \"glow\" | \"shine\" | \"none\";\n\nexport interface SocialLoginButtonProps extends ButtonProps {\n provider: SocialProvider;\n animation?: SocialAnimation;\n children?: ReactNode; // Optional, defaults to \"Continue with [Provider]\"\n}\n\nconst providerConfig: Record<\n SocialProvider,\n {\n icon: React.ComponentType<{ className?: string }>;\n label: string;\n bgClass: string;\n textClass?: string;\n }\n> = {\n github: {\n icon: Github,\n label: \"Verify with Github\",\n bgClass:\n \"bg-black text-white hover:bg-black/90 dark:bg-white dark:text-black dark:hover:bg-white/90\",\n },\n google: {\n icon: Chrome,\n label: \"Continue with Google\",\n bgClass:\n \"bg-white text-black border border-input hover:bg-accent hover:text-accent-foreground dark:bg-neutral-900 dark:text-white dark:border-neutral-800\",\n },\n x: {\n icon: Twitter,\n label: \"Sign in with X\",\n bgClass:\n \"bg-black text-white hover:bg-black/90 dark:bg-white dark:text-black dark:hover:bg-white/90\",\n },\n vercel: {\n icon: Triangle,\n label: \"Continue with Vercel\",\n bgClass:\n \"bg-black text-white hover:bg-black/90 dark:bg-white dark:text-black dark:hover:bg-white/90\",\n },\n linkedin: {\n icon: Linkedin,\n label: \"Connect with LinkedIn\",\n bgClass:\n \"bg-black text-white hover:bg-black/90 dark:bg-white dark:text-black dark:hover:bg-white/90\",\n },\n};\n\nconst SocialLoginButton = ({\n className,\n provider,\n animation = \"none\",\n children,\n ...props\n}: SocialLoginButtonProps) => {\n const config = providerConfig[provider];\n const Icon = config.icon;\n\n const baseStyles = cn(\n \"cursor-pointer relative h-12 rounded-md px-8 text-sm font-medium transition-all w-full md:w-auto min-w-[240px]\",\n config.bgClass,\n className\n );\n\n // Animation variants\n const getAnimationProps = () => {\n switch (animation) {\n case \"scale\":\n return {\n whileHover: { scale: 1.02 },\n whileTap: { scale: 0.98 },\n };\n case \"slide\":\n return {}; // Handled via CSS/State inside\n default:\n return {\n whileTap: { scale: 0.98 },\n };\n }\n };\n\n return (\n \n {/* Glow Effect */}\n {animation === \"glow\" && (\n
    \n )}\n\n \n \n );\n};\n\nexport { SocialLoginButton };\n", - "type": "registry:component", - "target": "components/uitripled/social-login-button.tsx" - } - ] -} \ No newline at end of file diff --git a/packages/registry/registry.json b/packages/registry/registry.json index 59e776e..63b4ffc 100644 --- a/packages/registry/registry.json +++ b/packages/registry/registry.json @@ -1315,7 +1315,7 @@ ], "files": [ { - "path": "@uitripled/react-baseui/src/components/components/stocks-dashboard/dashboard.tsx", + "path": "@uitripled/react-baseui/src/components/stocks-dashboard/dashboard-baseui.tsx", "type": "registry:block", "target": "components/uitripled/dashboard-baseui.tsx" } @@ -1900,6 +1900,46 @@ "category": "components", "subcategory": "modal" }, + { + "name": "folder-animation", + "type": "registry:ui", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:ui", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "decorative", + "subcategory": null + }, + { + "name": "folder-animation-carbon", + "type": "registry:component", + "title": "Folder Animation", + "description": "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + "registryDependencies": [], + "dependencies": [ + "framer-motion", + "react" + ], + "files": [ + { + "path": "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + "type": "registry:component", + "target": "components/uitripled/folder-animation-carbon.tsx" + } + ], + "category": "native", + "subcategory": null + }, { "name": "footer-block-baseui", "type": "registry:block", @@ -4472,7 +4512,7 @@ "name": "native-user-card-baseui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations. (Base UI)", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations (Base UI)", "registryDependencies": [ "button" ], @@ -4487,14 +4527,14 @@ "target": "components/uitripled/native-user-card-baseui.tsx" } ], - "category": "native", + "category": "cards", "subcategory": null }, { "name": "native-user-card-shadcnui", "type": "registry:component", "title": "Native User Card", - "description": "Compact user profile card with avatar, name, handle, and action button with spring animations.", + "description": "Compact user profile card with avatar, name, handle, and action button with spring animations", "registryDependencies": [], "dependencies": [ "framer-motion", @@ -4507,7 +4547,7 @@ "target": "components/uitripled/native-user-card-shadcnui.tsx" } ], - "category": "native", + "category": "cards", "subcategory": null }, { diff --git a/packages/registry/src/registry/native.tsx b/packages/registry/src/registry/native.tsx index 84877d5..c5c6801 100644 --- a/packages/registry/src/registry/native.tsx +++ b/packages/registry/src/registry/native.tsx @@ -77,6 +77,17 @@ import { NativeFlipTextColored, NativeFlipTextDefault, } from "@uitripled/react-carbon/src/components/native/carbon/demo/native-flip-text-demo"; +import { + FolderAnimationCustomIcon, + FolderAnimationDefault, + FolderAnimationFast, + FolderAnimationImageIcon, + FolderAnimationMusicIcon, + FolderAnimationNoFooter, + FolderAnimationSlow, + FolderAnimationWithActions, +} from "@uitripled/react-carbon/src/components/native/demo/folder-animation-demo"; +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon"; import { NativeHoverCardBordered, NativeHoverCardCustomButton, @@ -2697,4 +2708,171 @@ export const nativeComponents: Component[] = [ display: true, availableIn: ["shadcnui", "baseui"], }, + { + id: "folder-animation", + name: "Folder Animation", + description: + "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + category: "native", + tags: ["folder", "animation", "motion", "blur", "card", "file", "native"], + component: FolderAnimation, + variants: [ + { + id: "default", + name: "Default", + description: "Standard folder animation with footer content", + component: FolderAnimationDefault, + code: ` +
    +

    Organizing Your Files

    +

    + Watch as files seamlessly move through your workspace. +

    +
    +
    `, + }, + { + id: "fast", + name: "Fast", + description: "Faster animation cycle (2 seconds)", + component: FolderAnimationFast, + code: ` +
    +

    Quick Transfer

    +

    + Faster animation for quick file operations. +

    +
    +
    `, + }, + { + id: "slow", + name: "Slow", + description: "Slower animation cycle (6 seconds)", + component: FolderAnimationSlow, + code: ` +
    +

    Careful Handling

    +

    + Slower animation for detailed file processing. +

    +
    +
    `, + }, + { + id: "custom-icon", + name: "Custom (Doc)", + description: "Custom document icon", + component: FolderAnimationCustomIcon, + code: ` + +
    + } +> +
    +

    Document Processing

    +

    + Custom icon for document-specific operations. +

    +
    +`, + }, + { + id: "image-icon", + name: "Custom (Image)", + description: "Custom image gallery icon", + component: FolderAnimationImageIcon, + code: ` + +
    + } +> +
    +

    Image Gallery

    +

    + Organizing your photos with style. +

    +
    +`, + }, + { + id: "music-icon", + name: "Custom (Music)", + description: "Custom music library icon with circular shape", + component: FolderAnimationMusicIcon, + code: ` + +
    + } + animationDuration={3} +> +
    +

    Music Library

    +

    + Your audio files in motion. +

    +
    +`, + }, + { + id: "with-actions", + name: "With Actions", + description: "Animation card with action buttons in footer", + component: FolderAnimationWithActions, + code: ` +
    +
    +
    + +
    +
    +

    File Transfer in Progress

    +

    + Moving 24 files to destination +

    +
    +
    +
    + + +
    +
    +
    `, + }, + { + id: "no-footer", + name: "No Footer", + description: "Animation without footer content", + component: FolderAnimationNoFooter, + code: ``, + }, + ], + codePath: "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + duration: "4000ms", + easing: "easeInOut", + display: true, + availableIn: ["carbon"], + }, + { + id: "folder-animation-carbon", + name: "Folder Animation", + description: + "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states.", + category: "native", + tags: [], + component: FolderAnimation, + codePath: "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + display: false, + availableIn: ["carbon"], + }, ]; diff --git a/packages/registry/src/registry/ui.tsx b/packages/registry/src/registry/ui.tsx index a87d434..868fcd0 100644 --- a/packages/registry/src/registry/ui.tsx +++ b/packages/registry/src/registry/ui.tsx @@ -173,6 +173,7 @@ import { VolumeComponent } from "@uitripled/react-shadcn/src/components/componen import { LiquidCursor } from "@uitripled/react-shadcn/src/components/liquid-cursor"; import { BrowseFolder } from "@uitripled/react-shadcn/src/components/sections/browse-folder"; import { GlowyWavesHero } from "@uitripled/react-shadcn/src/components/sections/glowy-waves-hero"; +import { FolderAnimation } from "@uitripled/react-carbon/src/components/native/folder-animation-carbon"; import { WebPerformancePage } from "@uitripled/react-shadcn/src/components/web-performance/web-performance-page"; export const uiComponents: Component[] = [ @@ -2380,4 +2381,18 @@ export const uiComponents: Component[] = [ display: true, availableIn: ["shadcnui", "baseui"], }, + { + id: "folder-animation", + name: "Folder Animation", + description: + "Animated folder card with motion blur effect, perfect for showcasing file operations or loading states", + category: "decorative", + tags: ["folder", "animation", "motion", "blur", "card", "file"], + component: FolderAnimation, + codePath: "@uitripled/react-carbon/src/components/native/folder-animation-carbon.tsx", + duration: "4000ms", + easing: "easeInOut", + display: true, + availableIn: ["carbon"], + }, ];