feat: add animated gradient border to Connect Device buttons

Pure CSS conic-gradient animation with @property --border-angle,
dynamic accent color from traffic zone, light theme + reduced motion support.
This commit is contained in:
Fringg
2026-02-25 11:18:39 +03:00
parent f474067efb
commit 70e1ed60bd
4 changed files with 67 additions and 39 deletions

View File

@@ -1,30 +1,51 @@
import React from 'react';
import { cn } from '@/lib/utils';
interface HoverBorderGradientProps extends React.HTMLAttributes<HTMLElement> {
/** Rendered HTML element. Default: 'div' */
as?: React.ElementType;
/** Hex color for the rotating gradient beam (e.g. '#00E5A0') */
accentColor?: string;
/** Full rotation duration in seconds. Default: 3 */
duration?: number;
}
/**
* Animated conic-gradient border that rotates around the element.
*
* Uses pure CSS `@property --border-angle` animation — no JS loops,
* GPU-friendly, works in Telegram Mini App WebView.
*
* Fallback: browsers without `@property` show a static gradient border.
*/
export function HoverBorderGradient({
children,
containerClassName,
className,
as: Tag = 'button',
as: Tag = 'div',
accentColor,
duration,
style,
...props
}: React.PropsWithChildren<
{
as?: React.ElementType;
containerClassName?: string;
className?: string;
} & React.HTMLAttributes<HTMLElement>
>) {
}: HoverBorderGradientProps) {
const cssVars: Record<string, string> = {};
if (accentColor) {
cssVars['--accent-color'] = accentColor;
// 30% opacity hex suffix for hover glow
cssVars['--accent-glow'] = accentColor + '4D';
}
if (duration !== undefined) {
cssVars['--border-duration'] = `${duration}s`;
}
return (
<Tag
className={cn(
'hover-border-gradient group flex items-center justify-center rounded-xl text-sm font-medium text-white',
containerClassName,
)}
className={cn('hover-border-gradient', className)}
style={{ ...cssVars, ...style } as React.CSSProperties}
{...props}
>
<span className={cn('relative z-10 flex items-center justify-center', className)}>
{children}
</span>
{children}
</Tag>
);
}