'init'
This commit is contained in:
54
app/components/AnimatedButton/AnimatedButton.tsx
Normal file
54
app/components/AnimatedButton/AnimatedButton.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Button, ButtonProps } from '@mantine/core';
|
||||
import { forwardRef, useMemo, useEffect } from 'react';
|
||||
|
||||
type AnimatedButtonProps = ButtonProps & {
|
||||
animated?: [string, string];
|
||||
animationDurationMs?: number;
|
||||
onClick?: () => void;
|
||||
};
|
||||
|
||||
export const AnimatedButton = forwardRef<HTMLButtonElement, AnimatedButtonProps>(
|
||||
({ animated, animationDurationMs = 2000, style, onClick, disabled, ...rest }, ref) => {
|
||||
const animationName = useMemo(() => {
|
||||
if (!animated) return undefined;
|
||||
const safe = (s: string) => s.replace(/[^a-zA-Z0-9]/g, '');
|
||||
return `abg_${safe(animated[0])}_${safe(animated[1])}`;
|
||||
}, [animated]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!animated || !animationName) return;
|
||||
const id = `__${animationName}`;
|
||||
let styleEl = document.getElementById(id) as HTMLStyleElement | null;
|
||||
if (!styleEl) {
|
||||
styleEl = document.createElement('style');
|
||||
styleEl.id = id;
|
||||
document.head.appendChild(styleEl);
|
||||
}
|
||||
styleEl.textContent = `@keyframes ${animationName}{0%{background-position:-200% 0;}100%{background-position:200% 0;}}`;
|
||||
}, [animated, animationName]);
|
||||
|
||||
return (
|
||||
<Button
|
||||
ref={ref}
|
||||
{...rest}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
style={
|
||||
animated && animationName && !disabled
|
||||
? {
|
||||
background: animated[0],
|
||||
backgroundImage: `linear-gradient(90deg, transparent, ${animated[1]}, transparent)`,
|
||||
backgroundSize: '50% 100%',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
animation: `${animationName} ${animationDurationMs}ms linear infinite`,
|
||||
willChange: 'background-position',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
...style,
|
||||
}
|
||||
: style
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user