@prokodo/ui
Version:
UI components for production-grade Next.js + Headless CMS (Strapi, Contentful, Headless WordPress) websites by prokodo – built for Core Web Vitals & SEO.
125 lines (124 loc) • 3.82 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { jsx, jsxs } from "react/jsx-runtime";
const PX = { xs: 16, sm: 24, md: 32, lg: 48, xl: 64 };
const SpinnerView = /* @__PURE__ */ __name(({
className,
style,
size = "sm",
ariaLabel = "Loading",
reducedMotion
}) => {
const s = PX[size];
const r = s / 2;
const stroke = Math.max(2, Math.round(s / 12));
const radius = r - stroke;
const arcPath = describeArc(0, 0, radius, -20, 270);
return /* @__PURE__ */ jsxs(
"svg",
{
"aria-label": ariaLabel,
className,
height: s,
role: "status",
viewBox: `0 0 ${s} ${s}`,
width: s,
style: {
display: "inline-block",
...style
},
children: [
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "ui-loading-gradient", x1: "0%", x2: "0%", y1: "0%", y2: "100%", children: [
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "1" }),
/* @__PURE__ */ jsx("stop", { offset: "50%", stopColor: "currentColor", stopOpacity: "0.4" }),
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0.1" })
] }) }),
/* @__PURE__ */ jsxs("g", { transform: `translate(${r} ${r})`, children: [
/* @__PURE__ */ jsx(
"circle",
{
fill: "none",
r: radius,
stroke: "currentColor",
strokeOpacity: "0.15",
strokeWidth: stroke
}
),
/* @__PURE__ */ jsx(
"path",
{
d: arcPath,
fill: "none",
stroke: "url(#ui-loading-gradient)",
strokeLinecap: "round",
strokeWidth: stroke,
children: !Boolean(reducedMotion) && /* @__PURE__ */ jsx(
"animateTransform",
{
attributeName: "transform",
dur: "0.9s",
from: "0 0 0",
repeatCount: "indefinite",
to: "360 0 0",
type: "rotate"
}
)
}
)
] })
]
}
);
}, "SpinnerView");
const OverlayView = /* @__PURE__ */ __name(({
className,
style,
size = "xl",
ariaLabel = "Loading",
show = true,
blur = 0,
zIndex = 9999,
reducedMotion,
resolvedBackdrop
}) => {
if (!show) return null;
const bg = resolvedBackdrop === "dark" ? "rgba(0,0,0,0.5)" : "rgba(255,255,255,0.5)";
return /* @__PURE__ */ jsx(
"div",
{
className,
role: "presentation",
style: {
position: "fixed",
inset: 0,
width: "100vw",
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: bg,
backdropFilter: blur ? `blur(${blur}px)` : void 0,
WebkitBackdropFilter: blur ? `blur(${blur}px)` : void 0,
zIndex,
...style
},
children: /* @__PURE__ */ jsx(SpinnerView, { ariaLabel, reducedMotion, size })
}
);
}, "OverlayView");
function polarToCartesian(cx, cy, r, angle) {
const rad = (angle - 90) * Math.PI / 180;
return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };
}
__name(polarToCartesian, "polarToCartesian");
function describeArc(cx, cy, r, start, end) {
const startPt = polarToCartesian(cx, cy, r, end);
const endPt = polarToCartesian(cx, cy, r, start);
const largeArcFlag = "1";
return `M ${startPt.x} ${startPt.y} A ${r} ${r} 0 ${largeArcFlag} 0 ${endPt.x} ${endPt.y}`;
}
__name(describeArc, "describeArc");
export {
OverlayView,
SpinnerView
};