Skip to content

About

React components for the member-facing side of loyalty and gamification programs. Server-authoritative, token-themed, accessible. MIT.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

Loyalty Patterns

React components for the customer-facing side of loyalty and gamification programs. Scratch cards, spin wheels, stamp cards, coupons, points counters, streaks, missions, reward catalogs, referrals, tier ladders — the surfaces a member actually touches.

Free and MIT licensed. Not an admin panel, and not a design system: it assumes you have one.

Docs, live demos and the playground → mrcl.st/loyalty-patterns

What this repository is

A source you copy from, not an app you clone and run.

There is no package to install, no dependency to add, no dev server and no build step. The repository contains the components, their framework-free engines, their stylesheets and their documentation — and nothing else. Copy a folder into your project and it is yours to edit.

That is why the demos live on the site rather than here: seeing a scratch card work requires an app around it, and the playground is that app. It runs every component live, lets you tune it, and hands you back the code with your settings applied.

Install

git clone https://github.com/mrcl-st/loyalty-patterns.git

Take two things:

  1. registry/tokens.css — the token defaults. Once, for the project.
  2. registry/<component>/ — the folder for each component you want.

Import the tokens near your global styles, then the component and its stylesheet:

import "./tokens.css";

import "@/components/scratch-card/styles.css";
import { ScratchCard } from "@/components/scratch-card/scratch-card";

Both stylesheets are plain CSS, so any bundler that handles a CSS import will do — Next.js, Vite, Remix and CRA all qualify. React 18 or later is the only runtime requirement.

You do not get updates by bumping a version. What you get instead is a component you can change without fighting a maintainer's abstraction, which for UI this brand-specific is the better trade.

Three rules, and breaking one is a bug rather than a preference

  • Outcomes are decided by your server, never in the browser. A scratch card reveals a result; it does not compute one. Prize logic reachable from the client bundle is a compliance incident a curious DevTools user will find.
  • Every gesture has a non-gesture equivalent. Scratching and flicking are path-based gestures, and WCAG 2.5.1 (Level A) requires a single-pointer alternative — which serves tremor and dexterity users, not only keyboard ones. Results announce; focus is managed.
  • All copy arrives as props. A required labels object per component, screen-reader announcements included. No hardcoded strings anywhere, so the type doubles as an inventory of every state the component has.

Components

Ten, each with its own README in its folder — that same file is the component's documentation page on the site, so what you read is what ships beside the code.

Component Mechanic
Scratch card Scratch-to-reveal over a server-decided outcome
Spin wheel Spin-to-reveal, aimed at the segment the server chose
Stamp card The punch card. A record, not an affordance
Coupon card A code to carry to a till, with the clipboard as a fallible dependency
Points counter A balance that moves, announced once at the destination
Streak tracker Consecutive days, where "today" is an input rather than a guess
Missions list Tasks with their own states inside a campaign with its own
Reward catalog What the points are for. Affordability is never computed client-side
Referral widget Share, then copy, then select it yourself — each step the previous one's failure state
Tier progress Where a member stands between named states, without promoting them in pixels

registry/_template/ is the shape a new component starts from, if you write one in the same style.

Theming

Components read --lk-* CSS custom properties and nothing else. No provider, no config file, no class-name convention, no second styling system.

:root {
  --lk-brand: #4f46e5;
  --lk-surface: #ffffff;
  --lk-radius: 12px;
}

That is the whole integration surface, which is why MUI, shadcn, Base UI and plain CSS all bridge in with about twenty lines of token mapping. Compose a theme in the playground and it exports the block for you.

Not on React?

Every component also emits a portable specification — a prompt you hand to a coding agent, carrying the behaviour contract, the state machine, the accessibility requirements and the compliance rules, each with its reasoning attached so the agent knows which parts it may not trade away. It separates the platform-neutral invariants from the React and canvas notes it should adapt rather than copy, and it ends in acceptance checks phrased as testable statements.

The component is the reference implementation; the specification is what travels to Vue, Svelte, SwiftUI or Flutter. Generate one, with your settings applied, from any component's page in the playground.

Licence

MIT. Use it commercially, fork it, ship it. Attribution appreciated and not required.

Feedback

Issues and pull requests are welcome against the component files. Bear in mind there is nothing to run here — no dev server and no test suite — so a change is reviewed by reading it, and the fastest way to influence what ships next is to say which component you needed and did not find.


Built by Marcel Stuliglowa, a lead product designer working on enterprise loyalty and gamification platforms. The opinions in this kit are not theoretical: they come from shipping these mechanics through compliance review and multi-brand theming, at volumes where a mispriced reward is a budget line rather than a bug.

About

React components for the member-facing side of loyalty and gamification programs. Server-authoritative, token-themed, accessible. MIT.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages