mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-27 21:33:41 +02:00
- Move 55 shadcn components → packages/ui/components/ui/ - Move lib/utils.ts (cn function) → packages/ui/lib/ - Move 3 DOM hooks (auto-scroll, mobile, scroll-fade) → packages/ui/hooks/ - Extract CSS design tokens (@theme + :root + .dark) → packages/ui/styles/tokens.css - Refactor 3 common components to pure-props (actor-avatar, mention-hover-card, reaction-bar) - Move 6 markdown components with renderMention slot for IssueMentionCard decoupling - Create wrapper components in apps/web/ for data-aware ActorAvatar and Markdown - Update 116 import paths across apps/web/ - Add @source directives for Tailwind to scan packages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
/**
|
|
* Spinner — 3x3 grid pulse for **active processing / execution** states.
|
|
*
|
|
* Use when the system is actively doing work or waiting for human action
|
|
* (streaming content, generating responses, awaiting approval).
|
|
* For passive content-loading states, use `<Loading />` instead.
|
|
*
|
|
* Inherits color from `currentColor` (use Tailwind `text-*`).
|
|
* Scales with font-size (use Tailwind `text-*` for size).
|
|
*/
|
|
import { cn } from "@multica/ui/lib/utils"
|
|
|
|
export interface SpinnerProps {
|
|
/** Additional className for styling (color via text-*, size via Tailwind text-*) */
|
|
className?: string
|
|
}
|
|
|
|
const DELAYS = [0.2, 0.3, 0.4, 0.1, 0.2, 0.3, 0, 0.1, 0.2]
|
|
|
|
const cubeStyle: React.CSSProperties = {
|
|
backgroundColor: "currentColor",
|
|
animation: "spinner-grid 1.3s infinite ease-in-out",
|
|
transform: "scale3d(0.5, 0.5, 1)",
|
|
}
|
|
|
|
export function Spinner({ className }: SpinnerProps) {
|
|
return (
|
|
<span
|
|
className={cn(className)}
|
|
role="status"
|
|
aria-label="Loading"
|
|
style={{
|
|
display: "inline-grid",
|
|
gridTemplateColumns: "repeat(3, 1fr)",
|
|
width: "1em",
|
|
height: "1em",
|
|
gap: "0.08em",
|
|
}}
|
|
>
|
|
{DELAYS.map((delay, i) => (
|
|
<span key={i} style={{ ...cubeStyle, animationDelay: `${delay}s` }} />
|
|
))}
|
|
|
|
<style>{`@keyframes spinner-grid{0%,70%,100%{transform:scale3d(.5,.5,1)}35%{transform:scale3d(0,0,1)}}`}</style>
|
|
</span>
|
|
)
|
|
}
|