{"_id":"@aide-gg/thinking-orbs","name":"@aide-gg/thinking-orbs","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.1":{"name":"@aide-gg/thinking-orbs","version":"0.1.1","description":"Dotted thought-orb loading indicators for AI & agent UIs — six tuned states, two sizes, auto dark/light. Fork of thinking-orbs by Jakub Antalik, adding an idle at-rest state and smoother transitions.","publishConfig":{"access":"public"},"type":"module","main":"dist/index.cjs","module":"dist/index.es.js","types":"dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.es.js"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"sideEffects":false,"scripts":{"dev":"vite --config vite.config.demo.ts","build":"vite build","build:demo":"vite build --config vite.config.demo.ts","typecheck":"tsc --noEmit","check:transitions":"npm run build && node scripts/check-transitions.mjs","prepare":"npm run build","prepublishOnly":"npm run build"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"devDependencies":{"@tailwindcss/vite":"^4.3.3","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@vitejs/plugin-react":"^4.2.0","clsx":"^2.1.1","react":"^18.2.0","react-dom":"^18.2.0","tailwind-merge":"^3.6.0","tailwindcss":"^4.3.3","typescript":"^5.3.0","vite":"^5.0.0","vite-plugin-dts":"^3.7.0"},"keywords":["react","loading","loader","spinner","ai","agent","llm","canvas","animation","dark-mode"],"author":{"name":"Jakub Antalik"},"contributors":[{"name":"Aidan Leuenberger"}],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Ogyeet10/thinking-orbs-animated.git"},"bugs":{"url":"https://github.com/Ogyeet10/thinking-orbs-animated/issues"},"homepage":"https://github.com/Ogyeet10/thinking-orbs-animated#readme","gitHead":"1098b039b2de4a632ed9ff68ff2c4e96b776a574","_id":"@aide-gg/thinking-orbs@0.1.1","_nodeVersion":"26.0.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-Okc0ENiYPoNaO3F0oywnYRxr9yQKD8PApkbjNZMRDvAbxUvPJx/i2AX88NpqRub+Ls7xrj1SQs1i30Yk0X9mTw==","shasum":"f7a6b939cede90a58024de883a5d8f9ace76d236","tarball":"https://registry.npmjs.org/@aide-gg/thinking-orbs/-/thinking-orbs-0.1.1.tgz","fileCount":6,"unpackedSize":53057,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCHxxTCIfVPwHvwKdPM8V2jOFN1NPIeB/qtktac5J68IwIgGmAZs7XgPxNCpsoGeJWHEbmsoF+JY66KgsPLS0qGCWY="}]},"_npmUser":{"name":"n0ct7i5","email":"N0ct7i5@proton.me"},"directories":{},"maintainers":[{"name":"n0ct7i5","email":"N0ct7i5@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/thinking-orbs_0.1.1_1785436333033_0.21445473095316947"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-30T18:32:12.863Z","0.1.1":"2026-07-30T18:32:13.155Z","modified":"2026-07-30T18:32:13.384Z"},"maintainers":[{"name":"n0ct7i5","email":"N0ct7i5@proton.me"}],"description":"Dotted thought-orb loading indicators for AI & agent UIs — six tuned states, two sizes, auto dark/light. Fork of thinking-orbs by Jakub Antalik, adding an idle at-rest state and smoother transitions.","homepage":"https://github.com/Ogyeet10/thinking-orbs-animated#readme","keywords":["react","loading","loader","spinner","ai","agent","llm","canvas","animation","dark-mode"],"repository":{"type":"git","url":"git+https://github.com/Ogyeet10/thinking-orbs-animated.git"},"contributors":[{"name":"Aidan Leuenberger"}],"author":{"name":"Jakub Antalik"},"bugs":{"url":"https://github.com/Ogyeet10/thinking-orbs-animated/issues"},"license":"MIT","readme":"# thinking-orbs\n\nDotted thought-orb loading indicators for AI & agent UIs. Seven hand-tuned animated states — one at rest, six at work — each shipped at two purpose-tuned sizes, rendered on a plain 2D canvas — no WebGL, no filters, works identically in Chrome, Safari and Firefox.\n\n[Live demo](https://orbs.jakubantalik.com) · [Repository](https://github.com/Jakubantalik/thinking-orbs) · [Report an issue](https://github.com/Jakubantalik/thinking-orbs/issues)\n\n## Install\n\n```bash\nnpm install thinking-orbs\n```\n\n## Quick start\n\n```tsx\nimport { ThinkingOrb } from 'thinking-orbs';\n\nfunction Status() {\n  return <ThinkingOrb state=\"searching\" size={64} />;\n}\n```\n\n## States\n\nOne resting state and six verbs an agent can be doing, each a distinct animation:\n\n```tsx\n<ThinkingOrb state=\"idle\" />       {/* at rest: a slow turn, dots drifting in place */}\n<ThinkingOrb state=\"working\" />    {/* particles on tilted orbits */}\n<ThinkingOrb state=\"searching\" />  {/* a scan meridian sweeps a dotted globe */}\n<ThinkingOrb state=\"solving\" />    {/* bands scramble, then click back solved */}\n<ThinkingOrb state=\"listening\" />  {/* a waveform rolls through the rings */}\n<ThinkingOrb state=\"composing\" />  {/* an undulating multi-band sash */}\n<ThinkingOrb state=\"shaping\" />    {/* dotted outline: circle → triangle → square */}\n```\n\n## Transitions\n\nChanging `state` morphs; it never cuts. Both animations keep running while every dot of the outgoing frame travels to a dot of the incoming one, so an agent going `idle` → `listening` → `searching` → `idle` reads as one continuous object changing its mind:\n\n```tsx\n<ThinkingOrb state={agent.state} />              {/* 620 ms morph (default) */}\n<ThinkingOrb state={agent.state} transition={900} />  {/* slower, dreamier */}\n<ThinkingOrb state={agent.state} transition={0} />    {/* opt out: hard swap */}\n```\n\nHow it works: the two frames are captured as dot lists, ordered by angle around the centre and paired, then each dot travels in polar space — curving around the centre rather than through it — with a slight per-dot stagger so the change sweeps around the orb. Where the two states have different dot counts, the extra dots bud out of their parent from zero radius (and merging dots shrink back into it), so the first and last frames of a morph are pixel-identical to the plain states.\n\nEverything else is continuous too:\n\n- **Interrupting** a morph is free — a new `state` mid-flight starts from exactly what is on screen, no snap-back.\n- **`speed`** warps the clock instead of resetting it, so dragging a speed slider never jumps the phase.\n- **`paused`** freezes the clock and resuming picks up where it stopped. State morphs still play while paused.\n- **Theme flips** fade the ink polarity rather than inverting on one frame.\n- `prefers-reduced-motion: reduce` skips all of it: states swap instantly on a static frame.\n\n## Sizes\n\nTwo tuned presets — separate designs, not a scale factor. `64` for chat-avatar scale, `20` for inline-text scale. Each carries its own dot count, dot size and speed tuning:\n\n```tsx\n<ThinkingOrb state=\"working\" size={64} />\n<ThinkingOrb state=\"working\" size={20} />\n```\n\n## Theme\n\nStrictly monochrome — light ink for dark backgrounds, dark ink for light backgrounds — with the mode picked automatically from the host project:\n\n```tsx\n<ThinkingOrb theme=\"auto\" />   {/* default — detects from the project */}\n<ThinkingOrb theme=\"dark\" />   {/* pin: light dots for dark backgrounds */}\n<ThinkingOrb theme=\"light\" />  {/* pin: dark dots for light backgrounds */}\n```\n\n`auto` resolves in three layers and updates live when any of them change:\n\n1. an ancestor `data-theme=\"dark|light\"` attribute or `dark`/`light` class (the Tailwind / shadcn convention), watched via `MutationObserver`;\n2. otherwise `prefers-color-scheme`, subscribed for live OS theme switches;\n3. SSR-safe — the canvas paints only on the client, after the theme has resolved.\n\n## Other props\n\n```tsx\n<ThinkingOrb\n  state=\"solving\"\n  size={20}\n  speed={1.5}          // multiplier on the preset's baked speed\n  paused={false}       // freeze on the current frame\n  transition={620}     // ms of the state-change morph; 0 swaps instantly\n  aria-label=\"Analysing repository…\"  // overrides the per-state default\n/>\n```\n\nAll other `<canvas>` props (`className`, `style`, `data-*`, …) pass through.\n\n## Accessibility & performance\n\n- `role=\"img\"` with a sensible per-state `aria-label` out of the box.\n- `prefers-reduced-motion: reduce` renders a static representative frame — no animation, no morphing — and still follows the live theme.\n- Every instance pauses automatically when scrolled offscreen (`IntersectionObserver`) or when the tab is hidden, and resumes in phase — all instances share one clock.\n- Plain 2D canvas arcs only: no `ctx.filter`, no SVG filters, no WebGL — the same pixels everywhere, cheap on low-end devices. Device-pixel-ratio capped at 2.\n- A settled orb paints exactly one mode per frame — the blending machinery only runs while a morph is in flight, and a paused, settled orb stops requesting frames entirely.\n\n## License\n\nMIT © Jakub Antalik\n","readmeFilename":"README.md","_rev":"1-b85fd6b3a4174e3b822fca88d49e2f83"}