shelving
Version:
Toolkit for using data in JavaScript.
35 lines (34 loc) • 2.1 kB
JavaScript
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 }));
}