- TypeScript 93.6%
- CSS 6.1%
- HTML 0.3%
|
|
||
|---|---|---|
| dev | ||
| dist | ||
| src | ||
| .gitignore | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
| vite.config.ts | ||
🔫 VALORANT-UI
Valorant-inspired component library for React + shadcn/ui
Angular clip-paths · Scan-line effects · Glitch animations · Red / Cyan / Gold palette
✨ Features
- 🎨 20+ components — Buttons, Cards, Tables, Modals, Alerts, Badges, Inputs, Toggles, Tabs, Tooltips, Toasts, and more
- 🔷 Angular clip-paths — Skewed buttons, cut-corner cards, Valorant-style UI shapes
- 📺 Scan effects — CRT scan-lines overlay + periodic scan beam
- ⚡ Glitch text — Randomized glitch distortion with cyan/red offsets
- 🌈 Full color system — Red, Cyan, Gold, Green, Purple — all as CSS variables
- 🔤 Typography — Rajdhani (display), Barlow Condensed (labels), Barlow (body)
- 📱 Responsive — Mobile-first with drawer nav, breakpoint hook, adaptive grids
- 🧩 shadcn/ui compatible — CSS variables map directly to shadcn tokens
- 🌳 Tree-shakeable — Import only what you need
- 📦 Zero runtime dependencies — Only
reactandreact-domas peer deps - 🔑 Fully typed — TypeScript with exported types for every component
📦 Installation
# npm
npm install valorant-ui
# yarn
yarn add valorant-ui
# pnpm
pnpm add valorant-ui
# bun
bun add valorant-ui
Peer dependencies:
react >= 18.0.0andreact-dom >= 18.0.0
🚀 Quick Start
1. Import the global styles
Add the Valorant CSS variables and keyframes to your app. If you're using shadcn/ui, place this before your main CSS:
/* app/globals.css (or tailwind.css) */
/* Option A: Import the full theme file */
@import "valorant-ui/styles";
/* Option B: Copy-paste the :root block from src/styles/globals.css */
2. Use components
import {
Btn,
Badge,
Card,
Alert,
Modal,
Input,
Toggle,
ProgressBar,
Table,
AgentCard,
Section,
GlitchText,
ScanLines,
ScanBeam,
ToastContainer,
useToast,
} from "valorant-ui";
function App() {
const { toasts, add, dismiss } = useToast();
return (
<>
{/* Ambient effects */}
<ScanLines />
<ScanBeam />
{/* Toast notifications */}
<ToastContainer toasts={toasts} dismiss={dismiss} />
<div style={{ padding: 32 }}>
<GlitchText size={48} color="#FF4655">
DEFUSE THE SITE
</GlitchText>
<div style={{ display: "flex", gap: 10, marginTop: 16 }}>
<Btn variant="primary" onClick={() =>
add({ title: "MATCH FOUND", message: "10/10 accepted", variant: "success" })
}>
FIND MATCH
</Btn>
<Btn variant="outline">VIEW DETAILS</Btn>
<Btn variant="ghost">CANCEL</Btn>
</div>
<Badge variant="green" dot pulse style={{ marginTop: 16 }}>ONLINE</Badge>
</div>
</>
);
}
🧩 Components
Atoms
| Component | Description |
|---|---|
VLabel |
Small uppercase label (Barlow Condensed) |
VTitle |
Bold uppercase heading (Rajdhani) |
Divider |
Horizontal separator line |
Glow |
Radial glow effect for backgrounds |
Effects
| Component | Description |
|---|---|
GlitchText |
Text with periodic glitch distortion |
ScanLines |
CRT-style scan-line overlay |
ScanBeam |
Periodic vertical cyan scan beam |
UI
| Component | Description |
|---|---|
Btn |
Button with 7 variants + 4 sizes + shimmer hover |
Badge |
Status pill with 7 color variants + dot + pulse |
Input |
Text input with focus glow, icon, error state |
Select |
Custom dropdown with animated open state |
Tooltip |
Hover tooltip (top/bottom/right) |
Toggle |
Animated switch with glow |
Checkbox |
Checkbox with glow on checked |
ProgressBar |
Animated bar with glow tip |
Tabs |
Tab switcher (line / pill variants) |
Feedback
| Component | Description |
|---|---|
Modal |
Dialog with cut-corner shape + Escape dismiss |
Alert |
Alert banner (error/warning/success/info) |
ToastContainer + useToast() |
Toast notification system (auto-dismiss 4s) |
Layout
| Component | Description |
|---|---|
Card |
Content card with colored accent + hover glow |
Stat |
Stat card with value, delta %, label |
Table |
Sortable data table with hover highlight |
AgentCard |
Compact agent card with avatar + selection |
Section |
Section wrapper with accent bar + divider |
Navigation
| Component | Description |
|---|---|
DrawerNav |
Mobile slide-in drawer navigation |
Hooks
| Hook | Description |
|---|---|
useBreakpoint() |
Returns { w, isMobile, isTablet, isDesktop } |
useToast() |
Returns { toasts, add, dismiss } for toast notifications |
🎨 Design Tokens
All tokens are available as CSS variables (for shadcn/ui) and as JS constants:
import { colors, clip, clipCard, shadows, ease } from "valorant-ui";
// Colors
colors.red // "#FF4655"
colors.cyan // "#00D4FF"
colors.gold // "#C89B3C"
colors.surface // "#152230"
colors.border // "#243B52"
// Clip-paths
clip(8) // "polygon(8px 0%, 100% 0%, calc(100% - 8px) 100%, 0% 100%)"
clipCard(14) // "polygon(0 0, calc(100% - 14px) 0, 100% 14px, ...)"
// Shadows
shadows.red // "0 0 20px hsl(354 100% 63% / 0.3)"
// Easing
ease.val // "cubic-bezier(0.16, 1, 0.3, 1)"
CSS Variables (for shadcn/ui)
:root {
--primary: 354 100% 63%; /* Valorant Red #FF4655 */
--secondary: 193 100% 50%; /* Valorant Cyan #00D4FF */
--accent: 40 56% 51%; /* Gold #C89B3C */
--success: 159 100% 45%; /* Green #00E5A0 */
--destructive: 354 100% 63%;
--background: 210 35% 8%;
--foreground: 200 20% 93%;
--card: 210 40% 14%;
--border: 210 38% 24%;
--radius: 0px; /* Angular! No rounded corners */
--font-display: 'Rajdhani', sans-serif;
--font-label: 'Barlow Condensed', sans-serif;
--font-body: 'Barlow', sans-serif;
--clip-md: polygon(8px 0%, 100% 0%, calc(100% - 8px) 100%, 0% 100%);
--clip-card: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px));
--ease-val: cubic-bezier(0.16, 1, 0.3, 1);
}
📖 API Reference
<Btn>
<Btn
variant="primary" // "primary" | "outline" | "ghost" | "cyan" | "gold" | "danger" | "success"
size="md" // "sm" | "md" | "lg" | "xl"
disabled={false}
fullWidth={false}
icon={<span>▶</span>}
onClick={() => {}}
>
FIND MATCH
</Btn>
<Badge>
<Badge variant="red" dot pulse>LIVE</Badge>
// variant: "red" | "cyan" | "gold" | "green" | "purple" | "muted" | "white"
<Modal>
const [open, setOpen] = useState(false);
<Modal
open={open}
onClose={() => setOpen(false)}
title="FIND MATCH"
footer={
<>
<Btn variant="ghost" onClick={() => setOpen(false)}>CANCEL</Btn>
<Btn onClick={() => setOpen(false)}>CONFIRM</Btn>
</>
}
>
<p>Modal content here</p>
</Modal>
<Alert>
<Alert
variant="error" // "error" | "warning" | "success" | "info"
title="Connection Lost"
message="Reconnecting to server..."
dismissible
onDismiss={() => {}}
/>
<Table>
<Table
columns={[
{ key: "map", label: "Map", sortable: true },
{ key: "result", label: "Result", render: (row) => <Badge variant="green">{row.result}</Badge> },
{ key: "score", label: "Score", align: "center" },
]}
rows={[
{ map: "ASCENT", result: "WIN", score: "13-7" },
{ map: "HAVEN", result: "LOSS", score: "9-13" },
]}
/>
<AgentCard>
<AgentCard
name="JETT"
role="Duelist"
rank="S-TIER"
color="#00D4FF"
initials="JT"
selected={true}
onClick={() => {}}
/>
useToast()
const { toasts, add, dismiss } = useToast();
add({ title: "MATCH FOUND", message: "10 players accepted", variant: "success" });
add({ title: "ERROR", variant: "error" });
useBreakpoint()
const { w, isMobile, isTablet, isDesktop } = useBreakpoint();
// isMobile → w < 640
// isTablet → w >= 640 && w < 1024
// isDesktop → w >= 1024
🎬 Animations
All keyframes are included in the CSS and ready to use:
| Animation | Usage |
|---|---|
val-scan |
Scan beam vertical sweep |
val-glitch |
Glitch text distortion (layer 1) |
val-glitch2 |
Glitch text distortion (layer 2) |
val-ping |
Pulsing dot (badge dot) |
val-slide-in |
Slide from right (toasts, alerts) |
val-fade-up |
Fade + translate up (dropdowns, modals) |
val-shimmer |
Shimmer sweep (button hover) |
val-drawer-in |
Slide from left (drawer nav) |
.your-element {
animation: val-fade-up 0.2s ease forwards;
}
🏗️ Project Structure
valorant-ui/
├── src/
│ ├── components/
│ │ ├── atoms/ # VLabel, VTitle, Divider, Glow
│ │ ├── effects/ # GlitchText, ScanLines, ScanBeam
│ │ ├── ui/ # Btn, Badge, Input, Select, Tooltip, Toggle, Checkbox, ProgressBar, Tabs
│ │ ├── feedback/ # Modal, Alert, ToastContainer, useToast
│ │ ├── layout/ # Card, Stat, Table, AgentCard, Section
│ │ └── navigation/ # DrawerNav
│ ├── hooks/ # useBreakpoint
│ ├── styles/
│ │ └── globals.css # CSS variables + keyframes + reset
│ ├── tokens/
│ │ └── index.ts # JS color tokens + clip-path helpers
│ ├── types/
│ │ └── index.ts # TypeScript interfaces for all props
│ └── index.ts # Barrel export
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── LICENSE
└── README.md
🛠️ Development
# Install dependencies
npm install
# Watch mode (rebuild on change)
npm run dev
# Production build
npm run build
# Lint
npm run lint
🔧 Integration with shadcn/ui
This library is designed to work alongside shadcn/ui. The CSS variables follow the same naming convention:
- Import
valorant-ui/stylesin yourglobals.css - The
:rootvariables will override shadcn/ui defaults - shadcn/ui components automatically inherit the Valorant theme
/* your app/globals.css */
@import "valorant-ui/styles";
@tailwind base;
@tailwind components;
@tailwind utilities;
Note: Valorant UI uses
--radius: 0pxfor angular shapes. If you want rounded corners on specific shadcn components, override locally.
📄 License
MIT — Free for personal and commercial use.
⚠️ Disclaimer
This project is not affiliated with, endorsed by, or connected to Riot Games. Valorant and all related assets are trademarks of Riot Games, Inc. This is a fan-made design system for educational and creative purposes.