67 lines
2.6 KiB
TypeScript
67 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import { ny } from '@/lib/utils'
|
|
|
|
type TColorProp = `#${string}` | `#${string}`[]
|
|
interface ShineBorderProps {
|
|
borderRadius?: number
|
|
borderWidth?: number
|
|
duration?: number
|
|
color?: TColorProp
|
|
className?: string
|
|
children: React.ReactNode
|
|
}
|
|
|
|
/**
|
|
* @name Shine Border
|
|
* @description It is an animated background border effect component with easy to use and configurable props.
|
|
* @param borderRadius defines the radius of the border.
|
|
* @param borderWidth defines the width of the border.
|
|
* @param duration defines the animation duration to be applied on the shining border
|
|
* @param color a string or string array to define border color.
|
|
* @param className defines the class name to be applied to the component
|
|
* @param children contains react node elements.
|
|
*/
|
|
export default function ShineBorder({
|
|
borderRadius = 8,
|
|
borderWidth = 1,
|
|
duration = 14,
|
|
color = '#fff',
|
|
className,
|
|
children,
|
|
}: ShineBorderProps) {
|
|
return (
|
|
<div
|
|
style={
|
|
{
|
|
'--border-radius': `${borderRadius}px`,
|
|
} as React.CSSProperties
|
|
}
|
|
className={ny(
|
|
'relative grid min-h-[60px] w-fit min-w-[300px] place-items-center rounded-[--border-radius] bg-white p-3 text-black dark:bg-black dark:text-white',
|
|
className,
|
|
)}
|
|
>
|
|
<div
|
|
style={
|
|
{
|
|
'--border-width': `${borderWidth}px`,
|
|
'--border-radius': `${borderRadius}px`,
|
|
'--border-radius-child': `${borderRadius * 0.2}px`,
|
|
'--shine-pulse-duration': `${duration}s`,
|
|
'--mask-linear-gradient': `linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)`,
|
|
'--background-radial-gradient': `radial-gradient(transparent,transparent, ${
|
|
!Array.isArray(color) ? color : color.join(',')
|
|
},transparent,transparent)`,
|
|
} as React.CSSProperties
|
|
}
|
|
className={`before:bg-shine-size before:absolute before:inset-[0] before:aspect-square before:h-full before:w-full before:rounded-[--border-radius] before:p-[--border-width] before:will-change-[background-position] before:content-[""] before:![-webkit-mask-composite:xor] before:![mask-composite:exclude] before:[background-image:var(--background-radial-gradient)] before:[background-size:300%_300%] before:[mask:var(--mask-linear-gradient)] motion-safe:before:animate-[shine-pulse_var(--shine-pulse-duration)_infinite_linear]`}
|
|
>
|
|
</div>
|
|
<div className="z-[1] h-full w-full rounded-[--border-radius-child]">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|