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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@bharathwaj1421/cpm-sdk-components

v2.0.0

Published

UI components for CPM SDK

Readme

@cpm-sdk/components

The Components package of the CPM SDK provides reusable UI components for consent and preference management. This package includes pre-built components like consent banners, preference centers, and utility components that can be easily integrated into any React application.

🚀 Features

  • Consent Banner: Fully customizable consent collection interface
  • Preference Center: Comprehensive user preference management
  • Consent Modal: Modal-based consent collection
  • Utility Components: Toggle switches, status indicators, and more
  • Theme Support: Light, dark, and auto themes
  • Responsive Design: Mobile-first responsive components
  • Accessibility: WCAG compliant with proper ARIA labels
  • TypeScript: Full type safety and IntelliSense support
  • Customizable: Extensive styling and behavior customization options

📦 Installation

npm install @cpm-sdk/components @cpm-sdk/core
# or
yarn add @cpm-sdk/components @cpm-sdk/core
# or
pnpm add @cpm-sdk/components @cpm-sdk/core

🔧 Basic Usage

Comprehensive Example

See all components working together in the comprehensive example:

import { ComprehensiveExample } from '@cpm-sdk/components/examples';

function App() {
  return <ComprehensiveExample />;
}

Consent Banner

The main component for collecting user consent:

import React from 'react';
import { ConsentBanner } from '@cpm-sdk/components';
import { ConsentCategory } from '@cpm-sdk/core';

const categories: ConsentCategory[] = [
  {
    id: 'necessary',
    name: 'Necessary',
    description: 'Essential cookies for website functionality',
    required: true,
    purpose: 'Basic functionality',
    legalBasis: 'Legitimate interest',
    retentionPeriod: 365,
    withdrawable: false,
    version: '1.0',
    lastUpdated: new Date(),
  },
  {
    id: 'analytics',
    name: 'Analytics',
    description: 'Cookies for website analytics and performance',
    required: false,
    purpose: 'Performance measurement',
    legalBasis: 'Consent',
    retentionPeriod: 365,
    withdrawable: true,
    version: '1.0',
    lastUpdated: new Date(),
  },
];

function App() {
  const handleAcceptAll = async (categories: Record<string, boolean>) => {
    console.log('All categories accepted:', categories);
  };

  const handleAcceptSelected = async (categories: Record<string, boolean>) => {
    console.log('Selected categories accepted:', categories);
  };

  const handleRejectAll = async (categories: Record<string, boolean>) => {
    console.log('All categories rejected:', categories);
  };

  return (
    <div>
      <h1>My Website</h1>
      
      <ConsentBanner
        categories={categories}
        position="bottom"
        theme="light"
        showOverlay={true}
        onAcceptAll={handleAcceptAll}
        onAcceptSelected={handleAcceptSelected}
        onRejectAll={handleRejectAll}
        onPreferencesOpen={() => console.log('Open preferences')}
        onClose={() => console.log('Banner closed')}
      />
    </div>
  );
}

Custom Styling

Apply custom styles and themes:

<ConsentBanner
  categories={categories}
  theme="dark"
  position="top"
  className="my-custom-banner"
  style={{
    backgroundColor: '#1a1a1a',
    color: '#ffffff',
    border: '2px solid #007bff',
  }}
/>

Component Composition

Use individual components for custom layouts:

import {
  ConsentBannerHeader,
  ConsentBannerBody,
  ConsentBannerFooter,
  ConsentBannerOverlay,
} from '@cpm-sdk/components';

function CustomConsentBanner() {
  return (
    <>
      <ConsentBannerOverlay onClick={handleClose} />
      <div className="custom-banner">
        <ConsentBannerHeader
          title="Custom Cookie Notice"
          description="We value your privacy"
          onClose={handleClose}
        />
        <ConsentBannerBody
          categories={categories}
          selectedCategories={selectedCategories}
          onCategoryChange={handleCategoryChange}
          isExpanded={isExpanded}
          onToggleExpand={handleToggleExpand}
        />
        <ConsentBannerFooter
          onAcceptAll={handleAcceptAll}
          onAcceptSelected={handleAcceptSelected}
          onRejectAll={handleRejectAll}
        />
      </div>
    </>
  );
}

🎨 Available Components

Consent Banner Components

ConsentBanner

The main consent collection component:

<ConsentBanner
  categories={categories}
  position="bottom"           // 'top' | 'bottom' | 'left' | 'right'
  theme="light"               // 'light' | 'dark' | 'auto'
  showOverlay={true}          // Show backdrop overlay
  showCloseButton={true}      // Show close button
  showPreferencesButton={true} // Show preferences button
  showAcceptAllButton={true}  // Show accept all button
  showRejectAllButton={true}  // Show reject all button
  showAcceptSelectedButton={true} // Show accept selected button
  onAcceptAll={handleAcceptAll}
  onAcceptSelected={handleAcceptSelected}
  onRejectAll={handleRejectAll}
  onPreferencesOpen={handlePreferencesOpen}
  onClose={handleClose}
  onConsentChange={handleConsentChange}
/>

ConsentBannerHeader

Header section with title, description, and close button:

<ConsentBannerHeader
  title="Cookie Preferences"
  description="We use cookies to enhance your experience"
  showCloseButton={true}
  onClose={handleClose}
  theme="light"
/>

ConsentBannerBody

Main content area with consent categories:

<ConsentBannerBody
  categories={categories}
  selectedCategories={selectedCategories}
  onCategoryChange={handleCategoryChange}
  isExpanded={isExpanded}
  onToggleExpand={handleToggleExpand}
  theme="light"
/>

ConsentBannerFooter

Footer with action buttons:

<ConsentBannerFooter
  showPreferencesButton={true}
  showAcceptAllButton={true}
  showRejectAllButton={true}
  showAcceptSelectedButton={true}
  onPreferencesClick={handlePreferencesClick}
  onAcceptAll={handleAcceptAll}
  onRejectAll={handleRejectAll}
  onAcceptSelected={handleAcceptSelected}
  theme="light"
/>

ConsentBannerOverlay

Backdrop overlay:

<ConsentBannerOverlay
  onClick={handleClose}
  theme="light"
/>

ConsentCategoryItem

Individual consent category with expandable details:

<ConsentCategoryItem
  category={category}
  isSelected={true}
  isRequired={false}
  onSelectionChange={handleSelectionChange}
  theme="light"
/>

Preference Center Components

PreferenceCenter

Comprehensive preference management interface:

<PreferenceCenter
  preferences={userPreferences}
  onPreferencesChange={handlePreferencesChange}
  theme="light"
  layout="modal" // 'modal' | 'drawer' | 'inline'
  size="large" // 'small' | 'medium' | 'large' | 'full'
  autoSave={false} // Auto-save changes after 1 second
/>

PreferenceCenterModal

Modal-based preference center:

<PreferenceCenterModal
  isOpen={isOpen}
  onClose={handleClose}
  preferences={userPreferences}
  onPreferencesChange={handlePreferencesChange}
  size="large"
  theme="light"
  showConsentCategories={true}
  showPreferenceSections={true}
  showActionButtons={true}
/>

PreferenceCenterDrawer

Drawer-based preference center with slide animations:

<PreferenceCenterDrawer
  isOpen={isOpen}
  onClose={handleClose}
  position="right" // 'left' | 'right' | 'top' | 'bottom'
  size="large"
  preferences={userPreferences}
  onPreferencesChange={handlePreferencesChange}
  theme="light"
/>

Consent Modal Components

ConsentModal

Modal-based consent collection with full functionality:

<ConsentModal
  isOpen={isOpen}
  onClose={handleClose}
  categories={categories}
  currentConsent={currentConsent}
  onConsentChange={handleConsentChange}
  size="large" // 'small' | 'medium' | 'large' | 'full'
  theme="light"
  variant="modal" // 'banner' | 'modal' | 'drawer'
  showOverlay={true}
  showCloseButton={true}
  showPreferencesButton={true}
  showAcceptAllButton={true}
  showRejectAllButton={true}
  showAcceptSelectedButton={true}
  onAcceptAll={handleAcceptAll}
  onAcceptSelected={handleAcceptSelected}
  onRejectAll={handleRejectAll}
  onPreferencesOpen={handlePreferencesOpen}
/>

ConsentModalTrigger

Button, link, or icon to trigger consent modal:

<ConsentModalTrigger
  onOpen={handleOpen}
  theme="light"
  variant="button" // 'button' | 'link' | 'icon'
  size="medium" // 'small' | 'medium' | 'large'
  disabled={false}
>
  Update Cookie Preferences
</ConsentModalTrigger>

// Icon variant
<ConsentModalTrigger
  onOpen={handleOpen}
  variant="icon"
  size="medium"
  theme="light"
/>

// Link variant
<ConsentModalTrigger
  onOpen={handleOpen}
  variant="link"
  size="medium"
  theme="light"
>
  Cookie Settings
</ConsentModalTrigger>

Utility Components (Coming Soon)

ConsentToggle

Toggle switch for individual consent categories:

<ConsentToggle
  categoryId="analytics"
  isEnabled={hasConsent('analytics')}
  onToggle={handleToggle}
  theme="light"
  size="medium" // 'small' | 'medium' | 'large'
/>

ConsentStatus

Visual indicator of consent status:

<ConsentStatus
  status="compliant" // 'compliant' | 'non-compliant' | 'partial'
  theme="light"
  showDetails={true}
/>

PreferenceToggle

Toggle switch for user preferences:

<PreferenceToggle
  preferenceKey="notifications.email"
  isEnabled={preferences.notifications.email}
  onToggle={handleToggle}
  theme="light"
  label="Email Notifications"
/>

🎨 Theming and Styling

Theme Support

All components support multiple themes:

// Light theme (default)
<ConsentBanner theme="light" />

// Dark theme
<ConsentBanner theme="dark" />

// Auto theme (follows system preference)
<ConsentBanner theme="auto" />

Custom Styling

Apply custom styles and CSS classes:

<ConsentBanner
  className="my-custom-banner"
  style={{
    backgroundColor: '#f0f0f0',
    border: '2px solid #007bff',
    borderRadius: '12px',
    boxShadow: '0 4px 20px rgba(0, 0, 0, 0.15)',
  }}
/>

CSS Custom Properties

Override default colors and spacing:

:root {
  --cpm-primary-color: #007bff;
  --cpm-secondary-color: #6c757d;
  --cpm-success-color: #28a745;
  --cpm-danger-color: #dc3545;
  --cpm-warning-color: #ffc107;
  --cpm-info-color: #17a2b8;
  
  --cpm-border-radius: 8px;
  --cpm-spacing-unit: 16px;
  --cpm-font-size-base: 16px;
  --cpm-font-family: 'Inter', sans-serif;
}

📱 Responsive Design

All components are mobile-first and responsive:

<ConsentBanner
  position="bottom"        // Adapts to mobile screens
  showOverlay={true}       // Full-screen overlay on mobile
  className="responsive-banner"
/>

Breakpoint Support

Components automatically adapt to different screen sizes:

  • Mobile: < 768px - Stacked layout, full-width
  • Tablet: 768px - 1024px - Balanced layout
  • Desktop: > 1024px - Side-by-side layout

♿ Accessibility

WCAG Compliance

All components meet WCAG 2.1 AA standards:

  • Keyboard Navigation: Full keyboard support
  • Screen Readers: Proper ARIA labels and descriptions
  • Color Contrast: Sufficient contrast ratios
  • Focus Management: Clear focus indicators
  • Semantic HTML: Proper HTML structure

ARIA Support

<ConsentBanner
  role="dialog"
  aria-labelledby="consent-title"
  aria-describedby="consent-description"
>
  <h2 id="consent-title">Cookie Preferences</h2>
  <p id="consent-description">Manage your cookie preferences</p>
</ConsentBanner>

🔧 Configuration

Consent Categories

Define your consent categories:

const categories: ConsentCategory[] = [
  {
    id: 'necessary',
    name: 'Necessary',
    description: 'Essential cookies for website functionality',
    required: true,
    purpose: 'Basic functionality',
    legalBasis: 'Legitimate interest',
    retentionPeriod: 365,
    withdrawable: false,
    version: '1.0',
    lastUpdated: new Date(),
  },
  // ... more categories
];

Event Handlers

Handle all consent events:

const handlers = {
  onAcceptAll: (categories) => {
    // Handle accept all
    analytics.track('consent_all_accepted', { categories });
  },
  onAcceptSelected: (categories) => {
    // Handle accept selected
    analytics.track('consent_selected_accepted', { categories });
  },
  onRejectAll: (categories) => {
    // Handle reject all
    analytics.track('consent_all_rejected', { categories });
  },
  onPreferencesOpen: () => {
    // Open preference center
    setPreferenceCenterOpen(true);
  },
  onClose: () => {
    // Handle banner close
    analytics.track('consent_banner_closed');
  },
  onConsentChange: (categories) => {
    // Handle any consent change
    updateConsent(categories);
  },
};

📚 Examples

Available Examples

  • ConsentBannerExample: Standalone consent banner demonstration
  • PreferenceCenterExample: Preference center with all layout options
  • ConsentModalExample: Consent modal with all trigger variants
  • ComprehensiveExample: Complete demo with all components working together

Running Examples

# Start the development server
pnpm dev

# View examples in your browser
# Navigate to the examples directory

🧪 Testing

Test your components with React Testing Library:

import { render, screen, fireEvent } from '@testing-library/react';
import { ConsentBanner } from '@cpm-sdk/components';

test('renders consent banner with categories', () => {
  render(<ConsentBanner categories={mockCategories} />);
  
  expect(screen.getByText('Cookie Preferences')).toBeInTheDocument();
  expect(screen.getByText('Necessary')).toBeInTheDocument();
  expect(screen.getByText('Analytics')).toBeInTheDocument();
});

test('handles accept all button click', async () => {
  const handleAcceptAll = jest.fn();
  
  render(
    <ConsentBanner
      categories={mockCategories}
      onAcceptAll={handleAcceptAll}
    />
  );
  
  fireEvent.click(screen.getByText('Accept All'));
  expect(handleAcceptAll).toHaveBeenCalledWith({
    necessary: true,
    analytics: true,
  });
});

Visual Testing

Use Storybook for visual testing and development:

# Start Storybook
pnpm storybook

# Build Storybook
pnpm storybook:build

📚 API Reference

Component Props

All components accept standard HTML attributes and custom props:

interface BaseComponentProps {
  className?: string;
  style?: CSSProperties;
  theme?: 'light' | 'dark' | 'auto';
  children?: ReactNode;
  [key: string]: any;
}

Event Types

type ConsentChangeEvent = (categories: Record<string, boolean>) => void;
type PreferenceChangeEvent = (preferences: UserPreferences) => void;
type ModalEvent = () => void;

Style Hooks

Use the provided style hooks for custom styling:

import { useConsentBannerStyles } from '@cpm-sdk/components';

function CustomBanner() {
  const styles = useConsentBannerStyles({
    position: 'bottom',
    theme: 'dark',
    isExpanded: false,
  });
  
  return <div style={styles.banner}>Custom Banner</div>;
}

🚀 Performance

Optimization Features

  • Lazy Loading: Components load only when needed
  • Memoization: Prevents unnecessary re-renders
  • Bundle Splitting: Tree-shakeable components
  • CSS-in-JS: Efficient styling without external CSS

Bundle Size

  • Core components: ~15KB gzipped
  • Full package: ~25KB gzipped
  • Tree-shakeable: Only import what you need

🔒 Security

Data Protection

  • No External Requests: All data stays local
  • Input Validation: Sanitized user inputs
  • XSS Prevention: Safe HTML rendering
  • Privacy First: No tracking or analytics

🤝 Contributing

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

Development Setup

# Install dependencies
pnpm install

# Start development mode
pnpm dev

# Run tests
pnpm test

# Build package
pnpm build

# Start Storybook
pnpm storybook

📄 License

This package is licensed under the MIT License - see the LICENSE file for details.

🆘 Support


Built with ❤️ for privacy-first web applications

This components package provides beautiful, accessible, and customizable UI components for consent and preference management.