cookiebanner-finally
Version:
Headless cookie banner library for Next.js with shadcn philosophy
427 lines (415 loc) • 11.3 kB
text/typescript
import React, { ReactNode } from 'react';
/**
* Cookie consent categories
*/
declare enum ConsentCategory {
Necessary = "necessary",
Preferences = "preferences",
Analytics = "analytics",
Marketing = "marketing"
}
/**
* Cookie consent preferences
*/
interface ConsentPreferences {
[ConsentCategory.Necessary]: boolean;
[ConsentCategory.Preferences]: boolean;
[ConsentCategory.Analytics]: boolean;
[ConsentCategory.Marketing]: boolean;
lastUpdated?: string;
}
/**
* Default consent preferences
*/
declare const DEFAULT_CONSENT_PREFERENCES: ConsentPreferences;
/**
* Script definition
*/
interface Script {
id: string;
category: ConsentCategory;
src?: string;
content?: string;
attributes?: Record<string, string>;
}
interface ConsentContextType {
preferences: ConsentPreferences;
isConsentGiven: boolean;
showBanner: boolean;
acceptAll: () => void;
denyAll: () => void;
updatePreferences: (preferences: Partial<ConsentPreferences>, closeOnUpdate?: boolean) => void;
closeBanner: () => void;
resetBanner: () => void;
hasConsentFor: (category: ConsentCategory) => boolean;
}
interface ConsentProviderProps {
children: ReactNode;
cookieName?: string;
cookieExpires?: number;
initialPreferences?: Partial<ConsentPreferences>;
autoShowBanner?: boolean;
}
/**
* Provider component for cookie consent management
*/
declare const ConsentProvider: React.FC<ConsentProviderProps>;
/**
* Hook for using consent context
*/
declare const useConsentContext: () => ConsentContextType;
/**
* Cookie manager for handling consent preferences
*/
declare class CookieManager {
private cookieName;
private cookieOptions;
constructor(cookieName?: string, cookieOptions?: Cookies.CookieAttributes);
/**
* Get current consent preferences
*/
getConsentPreferences(): ConsentPreferences;
/**
* Save consent preferences
*/
saveConsentPreferences(preferences: Partial<ConsentPreferences>): ConsentPreferences;
/**
* Check if consent is given for a specific category
*/
hasConsent(category: ConsentCategory): boolean;
/**
* Accept all cookie categories
*/
acceptAll(): ConsentPreferences;
/**
* Deny all non-necessary cookie categories
*/
denyAll(): ConsentPreferences;
/**
* Check if consent has been given (for any category besides necessary)
*/
hasConsentBeenGiven(): boolean;
/**
* Get cookie value
*/
private getCookieValue;
/**
* Set cookie value
*/
private setCookieValue;
}
declare const cookieManager: CookieManager;
/**
* Interface for the useCookieBanner hook
*/
interface UseCookieBannerResult {
isVisible: boolean;
isConsentGiven: boolean;
acceptAll: () => void;
denyAll: () => void;
close: () => void;
show: () => void;
}
/**
* Hook for managing the cookie consent banner
*
* @returns Banner state and methods
*
* @example
* ```tsx
* const CookieBanner = () => {
* const { isVisible, acceptAll, denyAll, close } = useCookieBanner();
*
* if (!isVisible) return null;
*
* return (
* <div className="cookie-banner">
* <p>We use cookies to improve your experience.</p>
* <div className="cookie-banner-buttons">
* <button onClick={acceptAll}>Accept All</button>
* <button onClick={denyAll}>Reject All</button>
* <button onClick={close}>Close</button>
* </div>
* </div>
* );
* }
* ```
*/
declare function useCookieBanner(): UseCookieBannerResult;
/**
* Interface for the useCookiePreferences hook
*/
interface UseCookiePreferencesResult {
preferences: ConsentPreferences;
isLoading: boolean;
isEnabled: (category: ConsentCategory) => boolean;
updatePreferences: (preferences: Partial<ConsentPreferences>) => void;
updateCategory: (category: ConsentCategory, enabled: boolean) => void;
}
/**
* Hook for reading and updating cookie preferences
*
* @returns Cookie preferences state and update methods
*
* @example
* ```tsx
* const CookieSettings = () => {
* const { preferences, isLoading, updateCategory } = useCookiePreferences();
*
* if (isLoading) return <div>Loading preferences...</div>;
*
* return (
* <div className="cookie-settings">
* <h2>Cookie Settings</h2>
*
* <div className="cookie-setting">
* <input
* type="checkbox"
* id="necessary"
* checked={preferences.necessary}
* disabled={true}
* />
* <label htmlFor="necessary">Necessary (Required)</label>
* </div>
*
* <div className="cookie-setting">
* <input
* type="checkbox"
* id="preferences"
* checked={preferences.preferences}
* onChange={(e) => updateCategory('preferences', e.target.checked)}
* />
* <label htmlFor="preferences">Preferences</label>
* </div>
*
* <div className="cookie-setting">
* <input
* type="checkbox"
* id="analytics"
* checked={preferences.analytics}
* onChange={(e) => updateCategory('analytics', e.target.checked)}
* />
* <label htmlFor="analytics">Analytics</label>
* </div>
*
* <div className="cookie-setting">
* <input
* type="checkbox"
* id="marketing"
* checked={preferences.marketing}
* onChange={(e) => updateCategory('marketing', e.target.checked)}
* />
* <label htmlFor="marketing">Marketing</label>
* </div>
* </div>
* );
* }
* ```
*/
declare function useCookiePreferences(): UseCookiePreferencesResult;
/**
* Interface for the useConsentGate hook
*/
interface UseConsentGateResult {
hasConsent: boolean;
isLoading: boolean;
showConsentPrompt: () => void;
}
/**
* Hook for conditionally rendering content based on consent
*
* @param category - The consent category to check
* @returns State indicating if content can be displayed
*
* @example
* ```tsx
* const YouTubeEmbed = ({ videoId }: { videoId: string }) => {
* const { hasConsent, isLoading, showConsentPrompt } = useConsentGate(
* ConsentCategory.Marketing
* );
*
* if (isLoading) {
* return <div>Loading...</div>;
* }
*
* if (!hasConsent) {
* return (
* <div className="consent-placeholder">
* <p>This content requires marketing cookies consent.</p>
* <button onClick={showConsentPrompt}>Manage Cookie Preferences</button>
* </div>
* );
* }
*
* return (
* <iframe
* src={`https://www.youtube.com/embed/${videoId}`}
* frameBorder="0"
* allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
* allowFullScreen
* />
* );
* }
* ```
*/
declare function useConsentGate(category: ConsentCategory): UseConsentGateResult;
/**
* Interface for the useScriptLoader hook
*/
interface UseScriptLoaderResult {
register: (script: Script) => void;
registerBatch: (scripts: Script[]) => void;
load: (id: string) => Promise<boolean>;
loadCategory: (category: ConsentCategory) => Promise<boolean[]>;
isLoaded: (id: string) => boolean;
}
/**
* Hook for loading scripts based on consent
*
* @returns Methods for registering and loading scripts
*
* @example
* ```tsx
* // In your layout or setup component
* const MyAnalyticsSetup = () => {
* const { register, load } = useScriptLoader();
*
* useEffect(() => {
* // Register analytics scripts
* register({
* id: 'google-analytics',
* category: ConsentCategory.Analytics,
* src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX',
* });
*
* register({
* id: 'ga-config',
* category: ConsentCategory.Analytics,
* content: `
* window.dataLayer = window.dataLayer || [];
* function gtag(){dataLayer.push(arguments);}
* gtag('js', new Date());
* gtag('config', 'G-XXXXXXXXXX');
* `,
* });
*
* // Attempt to load (will only load if user has given consent)
* load('google-analytics').then(() => {
* load('ga-config');
* });
* }, [register, load]);
*
* return null; // This is a utility component with no UI
* };
* ```
*/
declare function useScriptLoader(): UseScriptLoaderResult;
interface ConsentGateProps {
/**
* The content to render when consent is given
*/
children: ReactNode;
/**
* The consent category required
*/
category: ConsentCategory;
/**
* Custom component to render when consent is not given
*/
fallback?: ReactNode;
/**
* Custom loading component
*/
loading?: ReactNode;
/**
* Whether to show the consent banner when clicked
*/
showPromptOnClick?: boolean;
}
/**
* Component that conditionally renders content based on consent
*/
declare const ConsentGate: React.FC<ConsentGateProps>;
interface ScriptLoaderProps {
/**
* Script to load
*/
script: Script;
/**
* Callback when script is loaded
*/
onLoad?: () => void;
/**
* Whether to auto-load the script
* @default true
*/
autoLoad?: boolean;
}
/**
* Component that loads a script based on consent
*/
declare const ScriptLoader: React.FC<ScriptLoaderProps>;
interface ScriptBatchLoaderProps {
/**
* Scripts to load
*/
scripts: Script[];
/**
* Callback when all scripts are loaded
*/
onLoad?: () => void;
/**
* Whether to auto-load the scripts
* @default true
*/
autoLoad?: boolean;
}
/**
* Component that loads multiple scripts based on consent
*/
declare const ScriptBatchLoader: React.FC<ScriptBatchLoaderProps>;
/**
* Script manager for loading scripts based on consent
*/
declare class ScriptManager {
private scripts;
private loadedScripts;
/**
* Register a script
*/
register(script: Script): void;
/**
* Register multiple scripts
*/
registerBatch(scripts: Script[]): void;
/**
* Load a script by ID if consent is given
*/
loadScript(id: string, hasConsent: boolean): Promise<boolean>;
/**
* Load scripts by category if consent is given
*/
loadScriptsByCategory(category: ConsentCategory, hasConsent: boolean): Promise<boolean[]>;
/**
* Check if a script is loaded
*/
isLoaded(id: string): boolean;
/**
* Get all registered scripts
*/
getAllScripts(): Script[];
/**
* Get scripts by category
*/
getScriptsByCategory(category: ConsentCategory): Script[];
/**
* Load an external script
*/
private loadExternalScript;
/**
* Load an inline script
*/
private loadInlineScript;
}
declare const scriptManager: ScriptManager;
export { ConsentCategory, ConsentGate, type ConsentPreferences, ConsentProvider, CookieManager, DEFAULT_CONSENT_PREFERENCES, type Script, ScriptBatchLoader, ScriptLoader, ScriptManager, cookieManager, scriptManager, useConsentContext, useConsentGate, useCookieBanner, useCookiePreferences, useScriptLoader };