UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

35 lines (34 loc) 2.1 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useInstance } from "../../react/useInstance.js"; import { useStore } from "../../react/useStore.js"; import { BusyStore } from "../../store/BusyStore.js"; import { isURLActive } from "../../util/index.js"; import { getLink } from "../../util/link.js"; import { LOADING } from "../misc/Loading.js"; import { requireMeta } from "../misc/MetaContext.js"; import { callNotifiedElement } from "../util/notice.js"; /** Return either a `<button>` or an `<a href="">` based on whether an `onClick` or `href` prop is provided. */ export function Clickable(props) { return props.href ? _jsx(LinkClickable, { ...props }) : _jsx(ButtonClickable, { ...props }); } /** Return an `<a href="">` element. */ export function LinkClickable({ disabled = false, href, title, target, download, children = "Go", className, }) { // Resolve `href` against the current page URL and site root so site-absolute paths (`/foo`) honour the base subfolder. const { url, root } = requireMeta(); const link = disabled ? undefined : getLink(href, url, root); const active = isURLActive(link, url); return (_jsx("a", { href: link?.href, title: title, download: download, target: target, className: className, "aria-current": active ? "page" : undefined, children: children })); } /** Return a `<button>` element. */ export function ButtonClickable({ disabled = false, onClick, title, children = "Click", className }) { // Create a `BusyStore<undefined>` to keep track of the `onClick` call and any thrown errors. const store = useInstance(BusyStore, undefined); // Track the `busy/unbusy` state of the button to show a loading spinner appropriately. const busy = useStore(store.busy).value; return (_jsx("button", { type: "button", title: title, onClick: e => { if (!store.busy.value && onClick) { const el = e.currentTarget; store.run(callNotifiedElement, el, onClick, e); } }, disabled: busy || disabled, className: className, children: busy ? LOADING : children })); }