Add cookie-banner React example app
Interactive playground with themed banner, headless components, and debug tabs demonstrating programmatic consent access via getConsent() across separate bundles. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
47
examples/cookie-banner-react/src/hooks/useConfig.ts
Normal file
47
examples/cookie-banner-react/src/hooks/useConfig.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useCallback, useSyncExternalStore } from "react";
|
||||
|
||||
export interface Config {
|
||||
bannerId: string;
|
||||
baseUrl: string;
|
||||
}
|
||||
|
||||
const STORAGE_KEY = "probo-example-config";
|
||||
|
||||
const defaultConfig: Config = {
|
||||
bannerId: "",
|
||||
baseUrl: "",
|
||||
};
|
||||
|
||||
function getSnapshot(): Config {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
if (raw) return JSON.parse(raw) as Config;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
let cached = getSnapshot();
|
||||
const listeners = new Set<() => void>();
|
||||
|
||||
function subscribe(cb: () => void): () => void {
|
||||
listeners.add(cb);
|
||||
return () => listeners.delete(cb);
|
||||
}
|
||||
|
||||
function snapshot(): Config {
|
||||
return cached;
|
||||
}
|
||||
|
||||
function persist(next: Config): void {
|
||||
cached = next;
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
||||
for (const cb of listeners) cb();
|
||||
}
|
||||
|
||||
export function useConfig(): [Config, (next: Config) => void] {
|
||||
const config = useSyncExternalStore(subscribe, snapshot);
|
||||
const setConfig = useCallback((next: Config) => persist(next), []);
|
||||
return [config, setConfig];
|
||||
}
|
||||
Reference in New Issue
Block a user