2021-02-18 05:53:57 +01:00
|
|
|
import { h, Fragment } from 'preact';
|
|
|
|
import Tooltip from './Tooltip';
|
|
|
|
import { useCallback, useRef, useState } from 'preact/hooks';
|
2021-01-09 18:26:46 +01:00
|
|
|
|
2021-02-02 05:28:25 +01:00
|
|
|
const ButtonColors = {
|
|
|
|
blue: {
|
|
|
|
contained: 'bg-blue-500 focus:bg-blue-400 active:bg-blue-600 ring-blue-300',
|
2021-02-04 19:36:46 +01:00
|
|
|
outlined:
|
|
|
|
'text-blue-500 border-2 border-blue-500 hover:bg-blue-500 hover:bg-opacity-20 focus:bg-blue-500 focus:bg-opacity-40 active:bg-blue-500 active:bg-opacity-40',
|
2021-02-02 05:28:25 +01:00
|
|
|
text:
|
|
|
|
'text-blue-500 hover:bg-blue-500 hover:bg-opacity-20 focus:bg-blue-500 focus:bg-opacity-40 active:bg-blue-500 active:bg-opacity-40',
|
|
|
|
},
|
|
|
|
red: {
|
|
|
|
contained: 'bg-red-500 focus:bg-red-400 active:bg-red-600 ring-red-300',
|
2021-02-04 19:36:46 +01:00
|
|
|
outlined:
|
|
|
|
'text-red-500 border-2 border-red-500 hover:bg-red-500 hover:bg-opacity-20 focus:bg-red-500 focus:bg-opacity-40 active:bg-red-500 active:bg-opacity-40',
|
|
|
|
text:
|
|
|
|
'text-red-500 hover:bg-red-500 hover:bg-opacity-20 focus:bg-red-500 focus:bg-opacity-40 active:bg-red-500 active:bg-opacity-40',
|
2021-02-02 05:28:25 +01:00
|
|
|
},
|
|
|
|
green: {
|
|
|
|
contained: 'bg-green-500 focus:bg-green-400 active:bg-green-600 ring-green-300',
|
2021-02-04 19:36:46 +01:00
|
|
|
outlined:
|
|
|
|
'text-green-500 border-2 border-green-500 hover:bg-green-500 hover:bg-opacity-20 focus:bg-green-500 focus:bg-opacity-40 active:bg-green-500 active:bg-opacity-40',
|
|
|
|
text:
|
|
|
|
'text-green-500 hover:bg-green-500 hover:bg-opacity-20 focus:bg-green-500 focus:bg-opacity-40 active:bg-green-500 active:bg-opacity-40',
|
2021-02-02 05:28:25 +01:00
|
|
|
},
|
2021-02-18 05:53:57 +01:00
|
|
|
gray: {
|
|
|
|
contained: 'bg-gray-500 focus:bg-gray-400 active:bg-gray-600 ring-gray-300',
|
|
|
|
outlined:
|
|
|
|
'text-gray-500 border-2 border-gray-500 hover:bg-gray-500 hover:bg-opacity-20 focus:bg-gray-500 focus:bg-opacity-40 active:bg-gray-500 active:bg-opacity-40',
|
|
|
|
text:
|
|
|
|
'text-gray-500 hover:bg-gray-500 hover:bg-opacity-20 focus:bg-gray-500 focus:bg-opacity-40 active:bg-gray-500 active:bg-opacity-40',
|
|
|
|
},
|
2021-02-02 05:28:25 +01:00
|
|
|
disabled: {
|
|
|
|
contained: 'bg-gray-400',
|
2021-02-04 19:36:46 +01:00
|
|
|
outlined:
|
|
|
|
'text-gray-500 border-2 border-gray-500 hover:bg-gray-500 hover:bg-opacity-20 focus:bg-gray-500 focus:bg-opacity-40 active:bg-gray-500 active:bg-opacity-40',
|
|
|
|
text:
|
|
|
|
'text-gray-500 hover:bg-gray-500 hover:bg-opacity-20 focus:bg-gray-500 focus:bg-opacity-40 active:bg-gray-500 active:bg-opacity-40',
|
2021-02-02 05:28:25 +01:00
|
|
|
},
|
2021-02-04 00:43:24 +01:00
|
|
|
black: {
|
|
|
|
contained: '',
|
|
|
|
outlined: '',
|
|
|
|
text: 'text-black dark:text-white',
|
|
|
|
},
|
2021-01-18 18:31:06 +01:00
|
|
|
};
|
|
|
|
|
2021-02-02 05:28:25 +01:00
|
|
|
const ButtonTypes = {
|
|
|
|
contained: 'text-white shadow focus:shadow-xl hover:shadow-md',
|
|
|
|
outlined: '',
|
|
|
|
text: 'transition-opacity',
|
|
|
|
};
|
|
|
|
|
|
|
|
export default function Button({
|
|
|
|
children,
|
|
|
|
className = '',
|
|
|
|
color = 'blue',
|
|
|
|
disabled = false,
|
|
|
|
href,
|
|
|
|
size,
|
|
|
|
type = 'contained',
|
|
|
|
...attrs
|
|
|
|
}) {
|
2021-02-18 05:53:57 +01:00
|
|
|
const [hovered, setHovered] = useState(false);
|
|
|
|
const ref = useRef();
|
|
|
|
|
2021-02-05 00:19:47 +01:00
|
|
|
let classes = `whitespace-nowrap flex items-center space-x-1 ${className} ${ButtonTypes[type]} ${
|
2021-02-02 05:28:25 +01:00
|
|
|
ButtonColors[disabled ? 'disabled' : color][type]
|
2021-05-28 19:13:48 +02:00
|
|
|
} font-sans inline-flex font-bold uppercase text-xs px-1.5 md:px-2 py-2 rounded outline-none focus:outline-none ring-opacity-50 transition-shadow transition-colors ${
|
2021-02-02 05:28:25 +01:00
|
|
|
disabled ? 'cursor-not-allowed' : 'focus:ring-2 cursor-pointer'
|
|
|
|
}`;
|
|
|
|
|
|
|
|
if (disabled) {
|
|
|
|
classes = classes.replace(/(?:focus|active|hover):[^ ]+/g, '');
|
|
|
|
}
|
|
|
|
|
2021-02-18 05:53:57 +01:00
|
|
|
const handleMousenter = useCallback((event) => {
|
|
|
|
setHovered(true);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
const handleMouseleave = useCallback((event) => {
|
|
|
|
setHovered(false);
|
|
|
|
}, []);
|
|
|
|
|
2021-02-02 05:28:25 +01:00
|
|
|
const Element = href ? 'a' : 'div';
|
|
|
|
|
2021-01-09 18:26:46 +01:00
|
|
|
return (
|
2021-02-18 05:53:57 +01:00
|
|
|
<Fragment>
|
|
|
|
<Element
|
|
|
|
role="button"
|
|
|
|
aria-disabled={disabled ? 'true' : 'false'}
|
|
|
|
tabindex="0"
|
|
|
|
className={classes}
|
|
|
|
href={href}
|
|
|
|
ref={ref}
|
|
|
|
onmouseenter={handleMousenter}
|
|
|
|
onmouseleave={handleMouseleave}
|
|
|
|
{...attrs}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</Element>
|
|
|
|
{hovered && attrs['aria-label'] ? <Tooltip text={attrs['aria-label']} relativeTo={ref} /> : null}
|
|
|
|
</Fragment>
|
2021-01-09 18:26:46 +01:00
|
|
|
);
|
|
|
|
}
|