npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@loyalteez/react-components

v0.6.0

Published

React components for building loyalty program interfaces with Loyalteez

Readme

@loyalteez/react-components

React components for building loyalty program interfaces with Loyalteez

npm version License: MIT CI

Overview

@loyalteez/react-components provides drop-in React components for building loyalty program interfaces. Launch polished loyalty experiences in hours instead of weeks.

Features

  • 🎮 Game-like effects — Glows, shimmers, particles, shakes, dramatic reveals
  • 🎨 Beautiful defaults — Dark theme with customizable CSS variables
  • 🎭 Tone system — 10 theme presets (arcade, casino, cyberpunk, fantasy...)
  • 🧩 Composable — Use individual components or compose your own
  • 🪝 Headless hooks — Full control when you need custom UI
  • Lightweight — Tree-shakeable, minimal dependencies
  • 📱 Responsive — Mobile-first design
  • Accessible — WCAG 2.1 AA compliant
  • 🔥 Gamification — Streaks, leaderboards, challenges, confetti!

Installation

npm install @loyalteez/react-components
# or
pnpm add @loyalteez/react-components
# or
yarn add @loyalteez/react-components

Quick Start

import { 
  BalanceDisplay, 
  TierBadge, 
  StreakCounter,
  ToastProvider,
  useToast 
} from '@loyalteez/react-components';
import '@loyalteez/react-components/styles.css';

function App() {
  return (
    <ToastProvider>
      <MyLoyaltyWidget />
    </ToastProvider>
  );
}

function MyLoyaltyWidget() {
  const { reward } = useToast();
  
  return (
    <div className="flex gap-4">
      <TierBadge tier="gold" />
      <BalanceDisplay balance={5420} showDollarValue animated />
      <StreakCounter streak={7} />
      <button onClick={() => reward({ amount: 100 })}>
        Earn Rewards!
      </button>
    </div>
  );
}

Components

Core Display

| Component | Description | |-----------|-------------| | BalanceDisplay | Display LTZ balance with animated counter and dollar value | | ProgressBar | Generic progress indicator with gradient/glow variants | | TierBadge | Bronze/Silver/Gold/Platinum/Diamond tier badges with glow effects | | Badge | Pre-styled badges: Featured, Sponsored, Premium, SoldOut, etc. |

Perk Marketplace

| Component | Description | |-----------|-------------| | PerkCard | Full perk card with image, badges, supply, price, actions | | PerkCard.Root | Composable root for custom layouts | | PerkCard.Image | Perk image with overlay badges | | PerkCard.Content | Content container | | PerkCard.Title | Perk title | | PerkCard.Brand | Brand name and logo | | PerkCard.Supply | Supply progress indicator | | PerkCard.Price | LTZ price display | | PerkCard.Actions | Claim/purchase buttons | | SupplyProgress | Supply bar with urgency indicators |

Gamification

| Component | Description | |-----------|-------------| | StreakCounter | Daily/weekly streak with animated flame, milestones | | Leaderboard | Top earners with medals, rank changes, current user highlight | | ChallengeCard | Active challenges with timer, progress, rewards |

Interactive

| Component | Description | |-----------|-------------| | ToastProvider | Toast notification system context | | useToast | Hook for showing reward/success/error toasts | | ClaimModal | Transaction flow modal (idle→processing→success/error) | | ConfettiExplosion | Canvas-based confetti celebration | | useConfetti | Hook for imperative confetti control |

Layout & Utility

| Component | Description | |-----------|-------------| | EmptyState | Flexible empty state with presets (noPerks, noFavorites, etc.) | | Skeleton | Loading skeletons for cards, lists, balance displays | | Tooltip | Smart-positioned tooltips with arrow | | FilterBar | Filter dropdowns, search, sort, view toggle |

Effects Module 🎮

| Effect | Description | |--------|-------------| | GlowEffect | Pulsing, breathing, heartbeat, flicker, rainbow glows | | ShimmerEffect | Metallic, holographic, gold, frost, fire, neon, diamond shimmers | | ParticleEffect | Coins, stars, embers, sparkles, confetti, snow, hearts | | ShakeEffect | Horizontal, vertical, rotational, impact, vibrate, earthquake | | CountEffect | Simple, slot machine, flip, cascade, scramble, typewriter | | ToneProvider | Theme system with 10 presets (arcade, casino, cyberpunk, etc.) |

Examples

Streak Counter with Flame Animation

<StreakCounter 
  streak={14} 
  bestStreak={21}
  showFlame
  showMilestones
  breakWarning={{ hoursRemaining: 4, show: true }}
/>

Leaderboard with Medals

<Leaderboard 
  entries={leaderboardData}
  currentUserId="user123"
  showMedals
  showRankChange
  showAvatars
/>

Challenge Card with Timer

<ChallengeCard 
  challenge={{
    id: '1',
    title: 'Daily Login',
    description: 'Log in 7 days in a row',
    progress: 5,
    goal: 7,
    status: 'active',
    difficulty: 'medium',
    reward: { amount: 500 },
    endTime: '2024-12-31T23:59:59Z'
  }}
  onClaim={handleClaim}
/>

Toast Notifications

function RewardButton() {
  const { reward, success, error } = useToast();
  
  const handleClaim = async () => {
    try {
      await claimReward();
      reward({ amount: 500, description: 'Daily bonus claimed!' });
    } catch (e) {
      error({ title: 'Claim failed', description: e.message });
    }
  };
  
  return <button onClick={handleClaim}>Claim</button>;
}

Claim Modal with Transaction Flow

<ClaimModal
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  item={{ id: '1', title: 'Coffee Reward', cost: 500 }}
  state={claimState}  // 'idle' | 'confirming' | 'processing' | 'success' | 'error'
  userBalance={1000}
  onConfirm={handleClaim}
  transactionHash={txHash}
  explorerUrlTemplate="https://explorer.soneium.org/tx/{hash}"
/>

Confetti Celebration

function Celebration() {
  const { fire, props } = useConfetti();
  
  return (
    <>
      <button onClick={() => fire()}>🎉 Celebrate!</button>
      <ConfettiExplosion {...props} />
    </>
  );
}

Composable PerkCard

<PerkCard.Root perk={perkData} variant="featured">
  <PerkCard.Image />
  <PerkCard.Content>
    <PerkCard.Badges />
    <PerkCard.Brand />
    <PerkCard.Title />
    <PerkCard.Tags />
    <PerkCard.Supply />
    <div className="flex justify-between items-center">
      <PerkCard.Price />
      <CustomClaimButton />
    </div>
  </PerkCard.Content>
</PerkCard.Root>

Theming

CSS Variables

:root {
  /* Brand Colors */
  --ltz-cyan: 0 224 255;
  --ltz-purple: 108 51 234;
  --ltz-pink: 255 63 164;
  --ltz-green: 166 255 0;
  
  /* Backgrounds */
  --ltz-bg-primary: 10 12 28;
  --ltz-bg-secondary: 26 29 46;
  
  /* Text */
  --ltz-text-primary: 255 255 255;
  --ltz-text-secondary: 140 140 153;
  
  /* Radius */
  --ltz-radius: 0.75rem;
}

Tailwind CSS

// tailwind.config.js
import { loyalteezPreset } from '@loyalteez/react-components/tailwind';

export default {
  presets: [loyalteezPreset],
  // ...
};

Framer Motion (Optional)

For enhanced animations, import from /motion:

import { 
  BalanceDisplayMotion,
  StreakCounterMotion,
  LeaderboardMotion,
  ChallengeCardMotion,
  AnimatedList,
  AnimatedItem
} from '@loyalteez/react-components/motion';

// Physics-based balance counter
<BalanceDisplayMotion balance={5420} showDollarValue />

// Animated flame with intensity levels
<StreakCounterMotion streak={14} showFlame />

// Staggered entry animations for leaderboards
<LeaderboardMotion entries={data} currentUserId="user123" />

// Animated progress bars and timers
<ChallengeCardMotion challenge={challengeData} onClaim={handleClaim} />

// Stagger animate any list
<AnimatedList preset="spring" staggerDelay={0.1}>
  {items.map(item => <Card key={item.id} />)}
</AnimatedList>

Motion Components

| Component | Features | |-----------|----------| | BalanceDisplayMotion | Spring-based number transitions | | StreakCounterMotion | Physics-based flame, smooth count updates | | LeaderboardMotion | Staggered entries, layout animations, rank changes | | ChallengeCardMotion | Animated progress, pulsing timers, spring physics | | AnimatedList | Generic stagger wrapper with presets (fade, slide, scale, spring, bounce) | | AnimatedItem | Individual animated item control |

Requires framer-motion as a peer dependency:

pnpm add framer-motion

Effects Module 🎮

The Effects module provides game-like visual feedback for any UI element.

Glow Effects

import { GlowEffect, PulseGlow, LegendaryGlow, RainbowGlow } from '@loyalteez/react-components';

// Pulsing cyan glow
<GlowEffect color="cyan" pattern="pulse" intensity="normal">
  <Card>Content</Card>
</GlowEffect>

// Heartbeat gold glow for rewards
<GlowEffect color="gold" pattern="heartbeat" intensity="intense">
  <Badge>Premium</Badge>
</GlowEffect>

// Legendary rainbow glow
<LegendaryGlow>
  <PerkCard perk={legendaryPerk} />
</LegendaryGlow>

Shimmer Effects

import { ShimmerEffect, HolographicShimmer, GoldShimmer } from '@loyalteez/react-components';

// Holographic on hover
<ShimmerEffect variant="holographic" trigger="hover">
  <Badge>New</Badge>
</ShimmerEffect>

// Auto gold shimmer for rewards
<GoldShimmer trigger="auto" delay={3000}>
  <RewardCard />
</GoldShimmer>

Particle Effects

import { ParticleEffect, CoinBurst, StarBurst, EmberEffect } from '@loyalteez/react-components';

// Coin collect on reward
<CoinBurst active={showReward} count={20} onComplete={hideReward} />

// Continuous ember particles
<EmberEffect active continuous emitRate={10}>
  <StreakCounter streak={14} />
</EmberEffect>

// Custom particle configuration
<ParticleEffect
  active={celebrating}
  shape="star"
  motion="burst"
  colors={['#FFD700', '#FFA500', '#FF6B35']}
  count={50}
  intensity="intense"
/>

Shake Effects

import { ShakeEffect, ErrorShake, ImpactShake, useShake } from '@loyalteez/react-components';

// Error shake on validation failure
<ErrorShake trigger={hasError}>
  <Input />
</ErrorShake>

// Impact shake on achievement unlock
<ImpactShake trigger={unlocked} intensity="intense">
  <AchievementBadge />
</ImpactShake>

// Imperative shake hook
function Component() {
  const { shake, props } = useShake({ pattern: 'earthquake' });
  return (
    <ShakeEffect {...props}>
      <button onClick={shake}>Trigger!</button>
    </ShakeEffect>
  );
}

Count Effects (Dramatic Number Reveals)

import { CountEffect, SlotCounter, ScrambleCounter, useCountUp } from '@loyalteez/react-components';

// Slot machine reveal
<SlotCounter value={jackpot} intensity="extreme" showDelta />

// Scramble then settle
<ScrambleCounter value={score} from={previousScore} easing="bounce" />

// Imperative count hook
function PointsDisplay() {
  const { countTo, props } = useCountUp();
  return (
    <>
      <CountEffect {...props} />
      <button onClick={() => countTo(1000)}>Add Points</button>
    </>
  );
}

Tone System (Theme Presets)

import { ToneProvider, useTone, TONES } from '@loyalteez/react-components';

// Wrap your app with a tone
<ToneProvider tone="arcade">
  <App />
</ToneProvider>

// Available tones:
// - default   (Loyalteez signature)
// - arcade    (bright, bouncy, retro)
// - casino    (gold, luxury, high-stakes)
// - cyberpunk (neon, glitch, dark)
// - minimal   (clean, subtle, professional)
// - playful   (rounded, colorful, fun)
// - competitive (sports/esports energy)
// - fantasy   (RPG, magical, mystical)
// - scifi     (futuristic, tech, sleek)
// - retro     (80s/90s nostalgia)

// Access current tone
function Component() {
  const { tone, toneId, setTone } = useTone();
  return <button onClick={() => setTone('cyberpunk')}>Go Cyber</button>;
}

Effect Presets

import { EFFECT_PRESETS } from '@loyalteez/react-components';

// Pre-configured effect combos:
// - coinCollect, levelUp, milestone, streak
// - success, error, warning
// - common, rare, epic, legendary, mythic

// Use with components:
<GlowEffect {...EFFECT_PRESETS.legendary.glow} />
<ParticleEffect {...EFFECT_PRESETS.coinCollect.particles} />

Utilities

import { 
  formatLTZ,           // 1500000 → "1,500,000"
  formatCompact,       // 1500000 → "1.5M"
  formatLTZAsDollars,  // 5000 → "$5.00"
  cn                   // Tailwind class merge utility
} from '@loyalteez/react-components';

Documentation

Development

# Install dependencies
pnpm install

# Start Storybook
pnpm dev

# Run tests
pnpm test

# Build library
pnpm build

# Type check
pnpm typecheck

# Lint
pnpm lint

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

MIT © Loyalteez