Skip to content

gfargo/feature-lock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

49 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ”’ Feature Lock

Contextual feature locking for React that doesn't interrupt flow

Demo โ€ข Documentation โ€ข Blog Post

React 19 Next.js 14+ TypeScript MIT License


โœจ What is Feature Lock?

Feature Lock is a collection of React components for building contextual upgrade experiences. Instead of redirecting users to pricing pages, show upgrade prompts directly on the features they want to unlock.

The Problem

Traditional paywalls interrupt the user experience:

  • Click "Export Report" โ†’ Redirected to pricing page
  • Context is lost
  • User forgets why they clicked
  • Lower conversion rates

The Solution

Feature Lock keeps users in context:

  • Click "Export Report" โ†’ Overlay appears on the locked feature
  • Clear upgrade prompt right where they need it
  • User understands the value immediately
  • Higher conversion rates

๐Ÿ“ฆ Components

BlurWrapper

The flagship component that blurs locked features and guides users to upgradeโ€”without breaking their flow.

Stable Version 1.0.0

Quick Start

npx shadcn@latest add https://feature-lock.griffen.codes/r/blur-wrapper

Basic Usage

import { useState } from "react"
import BlurWrapper from "@/components/blurWrapper/blur-wrapper"

export function LockedFeature() {
  const [locked, setLocked] = useState(true)

  async function handleUpgrade() {
    await fetch("/api/upgrade", { method: "POST" })
    setLocked(false)
  }

  return (
    <BlurWrapper
      isBlurred={locked}
      onConfirm={handleUpgrade}
      onUnblur={() => setLocked(false)}
    >
      <YourPremiumContent />
    </BlurWrapper>
  )
}

View Full BlurWrapper Documentation โ†’

PaywallBanner

Dismissible announcement banner that spotlights new or locked functionality, provides upgrade CTAs, and respects user choice with optional local persistence.

  • Async primary & secondary actions with loading/error states
  • Variants for upgrade, info, success, and warning messages
  • Optional storageKey to remember dismissals across visits

Install directly into your project:

npx shadcn@latest add https://feature-lock.griffen.codes/r/paywall-banner

FeatureTooltip

Inline tooltip for gently nudging upgrades without interrupting users. Ideal for inline icons, disabled buttons, or table cells.

  • Accessible Radix tooltip trigger on hover/focus
  • Optional CTA (link or async action) with pending/error states
  • Highlight list for feature value props

Install it with one command:

npx shadcn@latest add https://feature-lock.griffen.codes/r/feature-tooltip

UpgradeModal

Standalone upgrade dialog that compares plans, highlights value props, and routes users to checkout flows.

  • Supports async CTAs and links per plan with pending/error states
  • Automatically adapts layout for one, two, or three plan offerings
  • Includes fine print, support contact callout, and recommended badge styling

Install directly:

npx shadcn@latest add https://feature-lock.griffen.codes/r/upgrade-modal

UsageProgress

Quota dashboards that show consumption trends, warn before limits, and route users to upgrade flows.

  • Per-track badges, trend arrows, and progress bars
  • Summary banner with plan unlock messaging and CTA row
  • Async upgrade handler with error feedback and secondary actions

Add it to your project:

npx shadcn@latest add https://feature-lock.griffen.codes/r/usage-progress

Coming Soon

  • More components - Additional monetization patterns coming soon

๐Ÿš€ Quick Start

Prerequisites

Make sure you have a Next.js project with shadcn/ui set up:

npx shadcn@latest init

Installation

Install the BlurWrapper component:

npx shadcn@latest add https://feature-lock.griffen.codes/r/blur-wrapper

This installs:

  • BlurWrapper component
  • Required shadcn/ui components (Button, Dialog)
  • All necessary dependencies

Your First Feature Lock

import { useState } from "react"
import BlurWrapper from "@/components/blurWrapper/blur-wrapper"

export function Dashboard() {
  const [analyticsLocked, setAnalyticsLocked] = useState(true)

  return (
    <BlurWrapper
      isBlurred={analyticsLocked}
      overlayMode="inline"
      inlinePosition="centerCenter"
      onConfirm={async () => {
        await upgradeUserPlan()
      }}
      onUnblur={() => setAnalyticsLocked(false)}
    >
      <AdvancedAnalytics />
    </BlurWrapper>
  )
}

๐ŸŽฏ BlurWrapper Features

๐ŸŽจ Two Overlay Modes

Dialog Mode - Full-screen modal for critical upgrade decisions Inline Mode - Contextual overlay positioned directly on locked content

โšก Key Features

  • Async-Ready: Built with React 19's useTransition for seamless async operations
  • Secondary Actions: Optional secondary button for "Learn More" or "Contact Sales" actions
  • Custom Icons: Replace the default Lock icon with any Lucide icon
  • Accessible by Default: Focus blocking with inert, screen reader announcements, error focus management
  • Flexible Positioning: 9 position options for inline overlays
  • Custom Overlays: Full control with render props
  • Error Handling: Built-in error states with automatic focus management

See the component README for detailed examples and API documentation.


๐Ÿ“š BlurWrapper Documentation

For complete API documentation, advanced examples, and implementation patterns, see:

For more examples including custom error handling, controlled state, and advanced patterns, see the component README.


๐Ÿ—๏ธ Built With


๐ŸŽฏ When to Use Feature Lock

โœ… Great For

  • Gating premium features (analytics, exports, advanced tools)
  • Contextual upgrade prompts in dashboards
  • Freemium SaaS products
  • Trial limitations
  • Feature-based pricing tiers

โš ๏ธ Not Recommended For

  • Full page paywalls (use traditional pricing pages)
  • Content behind authentication (use proper auth)
  • Critical security features (don't rely on client-side blur)

๐ŸŽจ Component Registry

Feature Lock components are distributed via a ShadcnUI-compatible registry. This means:

โœ… Easy Installation - One command installs everything โœ… Automatic Dependencies - No manual package.json editing โœ… Version Management - Registry tracks component versions โœ… Full Source Code - Components installed in your project (not node_modules)

Available Components

Component Status Command
BlurWrapper โœ… Stable npx shadcn@latest add https://feature-lock.griffen.codes/r/blur-wrapper
PaywallBanner โœ… New npx shadcn@latest add https://feature-lock.griffen.codes/r/paywall-banner
FeatureTooltip โœ… New npx shadcn@latest add https://feature-lock.griffen.codes/r/feature-tooltip
UpgradeModal โœ… New npx shadcn@latest add https://feature-lock.griffen.codes/r/upgrade-modal
UsageProgress โœ… New npx shadcn@latest add https://feature-lock.griffen.codes/r/usage-progress
AgeGate โœ… New npx shadcn@latest add https://feature-lock.griffen.codes/r/age-gate

Registry API

The registry exposes these endpoints:

  • GET /api/registry - List all components
  • GET /api/registry/r/:name - Get specific component

Learn more about the registry โ†’


๐Ÿ“Š Analytics

This project includes Vercel Analytics integration to track:

  • Component installations
  • Documentation engagement
  • Demo interactions
  • Conversion funnels

View Analytics Guide โ†’


๐Ÿค Contributing

We love contributions! Whether you want to:

  • ๐Ÿ› Report bugs
  • โœจ Suggest features
  • ๐Ÿ“ Improve documentation
  • ๐Ÿ’ป Submit code
  • ๐ŸŽจ Design new components

Check out our Contributing Guide โ†’

Development Setup

# Clone the repo
git clone https://github.com/gfargo/feature-lock.git
cd feature-lock

# Install dependencies
npm install

# Start dev server
npm run dev

# Generate registry
npm run gen:registry

๐Ÿ› Troubleshooting

Import Errors

Verify your tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"]
    }
  }
}

Blur Not Visible

Ensure content has non-transparent background:

<BlurWrapper isBlurred={locked}>
  <div className="bg-white dark:bg-slate-900">
    {/* Content */}
  </div>
</BlurWrapper>

Overlay Not Showing

Check that showOverlayOnBlur is not false:

<BlurWrapper
  isBlurred={locked}
  showOverlayOnBlur={true} // Default
>
  <Content />
</BlurWrapper>

View Full Troubleshooting Guide โ†’


๐Ÿ“„ License

MIT ยฉ Griffen Labs

See LICENSE for details.


๐Ÿ™ Acknowledgments

  • shadcn - For the amazing component library and CLI architecture
  • Radix UI - For accessible, unstyled primitives
  • Vercel - For hosting and analytics
  • React Team - For useTransition and concurrent features

๐Ÿ”— Links


๐Ÿ“ˆ Project Roadmap

Current (v1.0)

  • โœ… BlurWrapper component
  • โœ… PaywallBanner component
  • โœ… FeatureTooltip component
  • โœ… UpgradeModal component
  • โœ… UsageProgress component
  • โœ… Dialog and inline modes
  • โœ… Async handling with useTransition
  • โœ… Full accessibility support
  • โœ… Component registry
  • โœ… Documentation site
  • โœ… Analytics integration

Coming Soon (v1.1)

  • ๐Ÿšง Additional positioning options
  • ๐Ÿšง Animation customization

Future (v2.0)

  • ๐Ÿ”ฎ Internationalization (i18n)
  • ๐Ÿ”ฎ Vue and Svelte versions
  • ๐Ÿ”ฎ Storybook documentation

โญ Show Your Support

If Feature Lock helps your project, please give it a star on GitHub! It helps others discover the project.

Star on GitHub

Built with โค๏ธ by Griffen Labs

Website โ€ข GitHub โ€ข Twitter

About

A collection of React components for building contextual upgrade experiences

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published