UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

193 lines (192 loc) • 4.98 kB
import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js"; import { useId as useId$1 } from "../hooks/useId.js"; import Spinner_module_css_default from "./Spinner.module.css.js"; import { useMedia } from "../hooks/useMedia.js"; import { c } from "react-compiler-runtime"; import { clsx } from "clsx"; import { jsx, jsxs } from "react/jsx-runtime"; import { useEffect, useState } from "react"; //#region src/Spinner/Spinner.tsx const ANIMATION_DURATION_MS = 1e3; const sizeMap = { small: "16px", medium: "32px", large: "64px" }; function Spinner(t0) { var _ariaLabel; const $ = c(35); let ariaLabel; let className; let props; let style; let t1; let t2; let t3; if ($[0] !== t0) { ({size: t1, srText: t2, "aria-label": ariaLabel, className, style, delay: t3, ...props} = t0); $[0] = t0; $[1] = ariaLabel; $[2] = className; $[3] = props; $[4] = style; $[5] = t1; $[6] = t2; $[7] = t3; } else { ariaLabel = $[1]; className = $[2]; props = $[3]; style = $[4]; t1 = $[5]; t2 = $[6]; t3 = $[7]; } const sizeKey = t1 === void 0 ? "medium" : t1; const srText = t2 === void 0 ? "Loading" : t2; const delay = t3 === void 0 ? false : t3; const noMotionPreference = useMedia("(prefers-reduced-motion: no-preference)", false); const size = sizeMap[sizeKey]; const hasHiddenLabel = srText !== null && ariaLabel === void 0; const labelId = useId$1(); let t4; if ($[8] !== delay) { t4 = () => ({ isVisible: !delay, syncDelay: !delay ? computeSyncDelay() : 0 }); $[8] = delay; $[9] = t4; } else t4 = $[9]; const [t5, setVisibleState] = useState(t4); const { isVisible, syncDelay } = t5; let t6; let t7; if ($[10] !== delay) { t6 = () => { if (delay) { const timeoutId = setTimeout(() => { setVisibleState({ isVisible: true, syncDelay: computeSyncDelay() }); }, typeof delay === "number" ? delay : delay === "short" ? 300 : 1e3); return () => clearTimeout(timeoutId); } }; t7 = [delay]; $[10] = delay; $[11] = t6; $[12] = t7; } else { t6 = $[11]; t7 = $[12]; } useEffect(t6, t7); if (!isVisible) return null; let t8; if ($[13] !== noMotionPreference || $[14] !== style || $[15] !== syncDelay) { t8 = noMotionPreference ? { ...style, animationDelay: `${syncDelay}ms` } : style; $[13] = noMotionPreference; $[14] = style; $[15] = syncDelay; $[16] = t8; } else t8 = $[16]; const mergedStyle = t8; const t9 = (_ariaLabel = ariaLabel) !== null && _ariaLabel !== void 0 ? _ariaLabel : void 0; const t10 = hasHiddenLabel ? labelId : void 0; let t11; if ($[17] !== className) { t11 = clsx(className, Spinner_module_css_default.SpinnerAnimation); $[17] = className; $[18] = t11; } else t11 = $[18]; let t12; let t13; if ($[19] === Symbol.for("react.memo_cache_sentinel")) { t12 = /*#__PURE__*/ jsx("circle", { cx: "8", cy: "8", r: "7", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "2", vectorEffect: "non-scaling-stroke" }); t13 = /*#__PURE__*/ jsx("path", { d: "M15 8a7.002 7.002 0 00-7-7", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", vectorEffect: "non-scaling-stroke" }); $[19] = t12; $[20] = t13; } else { t12 = $[19]; t13 = $[20]; } let t14; if ($[21] !== mergedStyle || $[22] !== props || $[23] !== size || $[24] !== t10 || $[25] !== t11 || $[26] !== t9) { t14 = /*#__PURE__*/ jsxs("svg", { height: size, width: size, viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, "aria-label": t9, "aria-labelledby": t10, className: t11, style: mergedStyle, ...props, children: [t12, t13] }); $[21] = mergedStyle; $[22] = props; $[23] = size; $[24] = t10; $[25] = t11; $[26] = t9; $[27] = t14; } else t14 = $[27]; let t15; if ($[28] !== hasHiddenLabel || $[29] !== labelId || $[30] !== srText) { t15 = hasHiddenLabel ? /*#__PURE__*/ jsx(VisuallyHidden, { id: labelId, children: srText }) : null; $[28] = hasHiddenLabel; $[29] = labelId; $[30] = srText; $[31] = t15; } else t15 = $[31]; let t16; if ($[32] !== t14 || $[33] !== t15) { t16 = /*#__PURE__*/ jsxs("span", { className: Spinner_module_css_default.Box, "data-component": "Spinner", children: [t14, t15] }); $[32] = t14; $[33] = t15; $[34] = t16; } else t16 = $[34]; return t16; } Spinner.displayName = "Spinner"; /** * Computes a negative animation-delay so all spinners land at the same * rotation angle regardless of when they mount. Because every instance * references the same clock (performance.now()), the CSS animation engine * keeps them visually in sync without any Web Animations API calls * (getAnimations, element.animate, startTime), which are significantly * slower in Safari/WebKit. */ function computeSyncDelay() { return -((typeof performance !== "undefined" ? performance.now() : 0) % ANIMATION_DURATION_MS); } //#endregion export { Spinner as default };