feat(web): MS15 Phase 1 — Design System & App Shell (#451)
All checks were successful
ci/woodpecker/push/web Pipeline was successful

Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #451.
This commit is contained in:
2026-02-22 20:57:06 +00:00
committed by jason.woltje
parent 9b5c15ca56
commit a5ed260fbd
15 changed files with 2451 additions and 313 deletions

View File

@@ -0,0 +1,49 @@
"use client";
import { MosaicLogo } from "./MosaicLogo";
import type { ReactElement } from "react";
export interface MosaicSpinnerProps {
/** Width and height of the logo in pixels (default: 36) */
size?: number;
/** Seconds for one full rotation (default: 20) */
spinDuration?: number;
/** Optional text label displayed below the spinner */
label?: string;
/**
* When true, wraps the spinner in a full-page centered overlay.
* When false (default), renders inline.
*/
fullPage?: boolean;
/** Additional CSS classes for the wrapper element */
className?: string;
}
/**
* MosaicSpinner wraps MosaicLogo with spinning enabled.
* It can be used as a full-page loading overlay or as an inline indicator.
*/
export function MosaicSpinner({
size = 36,
spinDuration = 20,
label,
fullPage = false,
className = "",
}: MosaicSpinnerProps): ReactElement {
const inner = (
<div className={`flex flex-col items-center gap-3 ${className}`}>
<MosaicLogo size={size} spinning spinDuration={spinDuration} />
{label !== undefined && label !== "" && (
<span className="text-sm text-gray-500">{label}</span>
)}
</div>
);
if (fullPage) {
return <div className="flex min-h-screen items-center justify-center">{inner}</div>;
}
return inner;
}
export default MosaicSpinner;