forked from asgardeo/thunder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGradientBorderButton.tsx
More file actions
93 lines (86 loc) · 2.62 KB
/
GradientBorderButton.tsx
File metadata and controls
93 lines (86 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {styled, keyframes, Button, type ButtonProps} from '@wso2/oxygen-ui';
import {forwardRef} from 'react';
const spin = keyframes`
0% {
--gradient-angle: 0deg;
}
100% {
--gradient-angle: 360deg;
}
`;
// Register CSS @property for animatable custom property
if (typeof window !== 'undefined' && 'CSS' in window && 'registerProperty' in CSS) {
try {
CSS.registerProperty({
name: '--gradient-angle',
syntax: '<angle>',
initialValue: '0deg',
inherits: false,
});
} catch {
// Property already registered
}
}
const StyledGradientButton = styled(Button)(() => ({
position: 'relative',
display: 'inline-flex',
borderRadius: '8px',
padding: '8px 16px',
border: '2px solid transparent',
background: 'transparent',
color: 'var(--mui-palette-text-primary)',
fontWeight: 500,
backgroundClip: 'padding-box',
isolation: 'isolate',
'&::before': {
content: '""',
position: 'absolute',
inset: 0,
borderRadius: '8px',
padding: '2px',
background: 'conic-gradient(from var(--gradient-angle), #667eea, #764ba2, #f093fb, #4facfe, #00f2fe, #667eea)',
WebkitMask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
WebkitMaskComposite: 'xor',
maskComposite: 'exclude',
animation: `${spin} 4s linear infinite`,
zIndex: -1,
},
'&:hover': {
background: 'var(--mui-palette-action-hover)',
'&::before': {
animationPlayState: 'paused',
},
},
'&.Mui-disabled': {
'&::before': {
animationPlayState: 'paused',
opacity: 0.6,
},
},
}));
/**
* A button component with an animated gradient border effect.
* Based on the MUI documentation "Edit in Chat" button implementation.
*/
const GradientBorderButton = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => (
<StyledGradientButton ref={ref} variant="text" disableRipple disableFocusRipple {...props} />
));
GradientBorderButton.displayName = 'GradientBorderButton';
export default GradientBorderButton;