Files
tabler/shared/ui/Button.astro
T

111 lines
2.4 KiB
Plaintext

---
// TODO: spinner param (needs Spinner.astro).
// TODO: provider param (unused in markup).
// TODO: color=false special case — pass no color prop instead.
import Icon from './Icon.astro';
interface Props {
text?: string;
href?: string;
/** raw href + target="_blank" rel="noreferrer" */
external?: boolean;
element?: 'a' | 'button';
type?: string;
id?: string;
color?: string;
outline?: boolean;
ghost?: boolean;
/** btn-{height} right after btn */
height?: string;
size?: string;
block?: boolean;
disabled?: boolean;
square?: boolean;
loading?: boolean;
action?: boolean;
pill?: boolean;
/** btn-link */
link?: boolean;
class?: string;
icon?: string;
iconColor?: string;
iconEnd?: string;
iconOnly?: boolean;
/** animated dots after the text */
dots?: boolean;
/** data-bs-toggle="modal" data-bs-target="#modal-{modalId}" (modal-id param) */
modalId?: string;
/** data-bs-toggle="toast" data-bs-target="#toast-{toastId}" (toast-id param) */
toastId?: string;
/** data-bs-dismiss="modal" */
dismiss?: boolean;
}
const {
text = 'Button',
href,
external,
element: Element = 'a',
type,
id,
color,
outline,
ghost,
height,
size,
block,
disabled,
square,
loading,
action,
pill,
link,
class: className,
icon,
iconColor,
iconEnd,
iconOnly,
dots,
modalId,
toastId,
dismiss,
} = Astro.props;
// href defaults to '#'; internal hrefs are prefixed with '/'.
const resolvedHref = href ? (external ? href : `/${href}`) : '#';
const classes = [
'btn',
height && `btn-${height}`,
color && `btn-${outline ? 'outline-' : ghost ? 'ghost-' : ''}${color}`,
disabled && 'disabled',
square && 'btn-square',
loading && 'btn-loading',
action && 'btn-action',
pill && 'btn-pill',
size && `btn-${size}`,
className,
block && 'w-100',
link && 'btn-link',
iconOnly && 'btn-icon',
]
---
<Element
href={Element === 'a' ? resolvedHref : undefined}
type={type}
id={id}
class:list={classes}
target={external ? '_blank' : undefined}
rel={external ? 'noreferrer' : undefined}
data-bs-toggle={modalId ? 'modal' : toastId ? 'toast' : undefined}
data-bs-target={modalId ? `#modal-${modalId}` : toastId ? `#toast-${toastId}` : undefined}
aria-label={iconOnly ? text : undefined}
data-bs-dismiss={dismiss ? 'modal' : undefined}
>
{icon && <Icon name={icon} color={iconColor} />}
{!iconOnly && text}
{!iconOnly && dots && <span class="animated-dots"></span>}
{!iconOnly && iconEnd && <Icon name={iconEnd} class="icon-end" />}
</Element>