Spinner
Tier 0: Zero-JSAccessible indeterminate loading spinner indicator with multiple sizes and colors
$npx nnui add spinner
copy$npm install nnui-kit
copyInteractive Preview & Code
<!-- Different Sizes -->
<span data-ui="spinner" data-size="xs" aria-label="Loading"></span>
<span data-ui="spinner" data-size="sm" aria-label="Loading"></span>
<span data-ui="spinner" aria-label="Loading"></span>
<span data-ui="spinner" data-size="lg" aria-label="Loading"></span>
import React from "react";
import "nnui-kit/css";
export default function SpinnerDemo() {
return (
<div className="flex items-center gap-4">
<span data-ui="spinner" data-size="sm" aria-label="Loading" />
<span data-ui="spinner" aria-label="Loading" />
<span data-ui="spinner" data-size="lg" aria-label="Loading" />
</div>
);
}
<template>
<div style="display: flex; gap: 1rem; align-items: center;">
<span data-ui="spinner" data-size="sm" aria-label="Loading"></span>
<span data-ui="spinner" aria-label="Loading"></span>
<span data-ui="spinner" data-size="lg" aria-label="Loading"></span>
</div>
</template>
<script>
import "nnui-kit/css";
</script>
<div style="display: flex; gap: 1rem; align-items: center;">
<span data-ui="spinner" data-size="sm" aria-label="Loading"></span>
<span data-ui="spinner" aria-label="Loading"></span>
<span data-ui="spinner" data-size="lg" aria-label="Loading"></span>
</div>
How to Utilize
NNUI-KIT components live directly in the document Light DOM. You can use them via declarative HTML, with our first-class React wrapper, or platform-natively in Svelte, Vue, Astro, and HTMX:
React 18 & 19 (Next.js 15 App Router)
import 'nnui-kit/css';
import 'nnui-kit/client';
import { Spinner } from 'nnui-kit/react';
Universal Web Components (Vue 3, Svelte 5, Astro, HTMX)
<!-- Automatically registers <ui-spinner> and <nnui-spinner> -->
import 'nnui-kit/css';
import 'nnui-kit/client';
Platform Features
Zero Shadow DOM
Element lives in the Light DOM. Tailwind and global CSS apply directly.
persist="url | local"
Add declarative persistence attribute to auto-sync state with URL search params.
sync="cross-tab"
Synchronize changes across all open browser tabs via BroadcastChannel.