fluid-functionalism
A shadcn/ui registry of animated React components with a shared motion system, including a hover highlight that glides between items. Useful for building interactive frontend interfaces.
What 8bitcn-ui runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.
Claude Code
$ npx -y skills add theorcdev/8bitcn-ui --agent claude-code
Cursor
Cursor also runs Claude Code hooks from .claude/settings.json, so copy these hooks there to use them in Cursor.
Where it lives
import { useLayoutEffect, useRef } from "react";
function centerActiveSidebarItem(
viewport: HTMLDivElement,
activeItem: HTMLAnchorElement
): boolean {
if (viewport.clientHeight === 0) {
return false;
}
const viewportRect = viewport.getBoundingClientRect();
const activeItemRect = activeItem.getBoundingClientRect();
const centeredScrollTop =
viewport.scrollTop +
activeItemRect.top -
viewportRect.top -
(viewport.clientHeight - activeItemRect.height) / 2;
const maximumScrollTop = Math.max(
viewport.scrollHeight - viewport.clientHeight,
0
);
viewport.scrollTop = Math.min(
Math.max(centeredScrollTop, 0),
maximumScrollTop
);
return true;
}
function useCenterActiveSidebarItem(pathname: string) {
const activeItemRef = useRef<HTMLAnchorElement>(null);
const viewportRef = useRef<HTMLDivElement>(null);
// biome-ignore lint/correctness/useExhaustiveDependencies: Re-center whenever the active route changes.
useLayoutEffect(() => {
const activeItem = activeItemRef.current;
const viewport = viewportRef.current;
if (!(activeItem && viewport)) {
return;
}
if (centerActiveSidebarItem(viewport, activeItem)) {
return;
}
const resizeObserver = new ResizeObserver(() => {
if (centerActiveSidebarItem(viewport, activeItem)) {
resizeObserver.disconnect();
}
});
resizeObserver.observe(viewport);
return () => resizeObserver.disconnect();
}, [pathname]);
return { activeItemRef, viewportRef };
}
export { useCenterActiveSidebarItem };
import * as React from "react";
const MOBILE_BREAKPOINT = 768;
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener("change", onChange);
}, []);
return !!isMobile;
}
"use client";
import { useEffect, useRef, useState } from "react";
export function useNearViewport<T extends Element = HTMLDivElement>(
rootMargin: string
) {
const ref = useRef<T>(null);
const [isNearViewport, setIsNearViewport] = useState(false);
useEffect(() => {
const element = ref.current;
if (!element || isNearViewport) {
return;
}
if (typeof window.IntersectionObserver === "undefined") {
setIsNearViewport(true);
return;
}
let isDisconnected = false;
const disconnect = () => {
if (!isDisconnected) {
observer.disconnect();
isDisconnected = true;
}
};
const observer = new IntersectionObserver(
([entry]) => {
if (entry?.isIntersecting) {
setIsNearViewport(true);
disconnect();
}
},
{ rootMargin }
);
observer.observe(element);
return disconnect;
}, [isNearViewport, rootMargin]);
return { isNearViewport, ref };
}
"use client";
import { useEffect } from "react";
export function useShowcaseScrollGuard(enabled = true) {
useEffect(() => {
if (!enabled) {
return;
}
const original = Element.prototype.scrollIntoView;
Element.prototype.scrollIntoView = () => {
// Intentionally suppress mount-time focus scrolling from showcase widgets.
};
const animationFrame = requestAnimationFrame(() => {
if (window.scrollY > 0 && !window.location.hash) {
window.scrollTo(0, 0);
}
});
const timer = setTimeout(() => {
Element.prototype.scrollIntoView = original;
}, 600);
return () => {
cancelAnimationFrame(animationFrame);
clearTimeout(timer);
Element.prototype.scrollIntoView = original;
};
}, [enabled]);
}
Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.
Accessible retro components that you can copy and paste into your apps.Free. Open Source. Built on shadcn/ui. Documentation · Components · Blocks · Themes · Discord
A shadcn/ui registry of animated React components with a shared motion system, including a hover highlight that glides between items. Useful for building interactive frontend interfaces.