Add 'sge-frontend/' from commit '5fa787e054b25ac53edc7ff0275ea7960a709401'

git-subtree-dir: sge-frontend
git-subtree-mainline: 876c278ac4
git-subtree-split: 5fa787e054
This commit is contained in:
2025-08-04 00:27:23 +03:00
337 changed files with 854877 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
// ** React Imports
import { useState, useEffect } from 'react'
// ** Third Party Components
import { Button } from 'reactstrap'
import classnames from 'classnames'
// ** Styles
import './ripple-button.scss'
const RippleButton = ({ className, children, onClick, ...rest }) => {
// ** States
const [mounted, setMounted] = useState(false)
const [isRippling, setIsRippling] = useState(false)
const [coords, setCoords] = useState({ x: -1, y: -1 })
// ** Toggle mounted on mount & unmount
useEffect(() => {
setMounted(true)
return () => setMounted(false)
}, [])
// ** Check for coords and set ripple
useEffect(() => {
if (mounted) {
if (coords.x !== -1 && coords.y !== -1) {
setIsRippling(true)
setTimeout(() => setIsRippling(false), 500)
} else {
setIsRippling(false)
}
}
}, [coords])
// ** Reset Coords on ripple end
useEffect(() => {
if (mounted) {
if (!isRippling) setCoords({ x: -1, y: -1 })
}
}, [isRippling])
return (
<Button
className={classnames('waves-effect', {
[className]: className
})}
onClick={e => {
const rect = e.target.getBoundingClientRect()
setCoords({ x: e.clientX - rect.left, y: e.clientY - rect.top })
if (onClick) {
onClick(e)
}
}}
{...rest}
>
{children}
{isRippling ? (
<span
className='waves-ripple'
style={{
left: coords.x,
top: coords.y
}}
></span>
) : null}
</Button>
)
}
// ** PropTypes
RippleButton.propTypes = {
...Button.propTypes
}
Button.Ripple = RippleButton

View File

@@ -0,0 +1,36 @@
// Component: Ripple Button
// ========================================================================
@import '../../scss/base/bootstrap-extended/include';
@import '../../scss/base/components/include';
.waves-effect {
position: relative;
overflow: hidden;
.waves-ripple {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
width: 0;
height: 0;
border-radius: 50%;
background: rgba($color: $white, $alpha: 0.5);
animation: ripple-effect 0.4s ease;
}
}
@keyframes ripple-effect {
0% {
opacity: 0;
}
25% {
opacity: 1;
}
100% {
width: 200%;
padding-bottom: 200%;
opacity: 0;
}
}