Differential Privacy Controls
A collapsible DP settings panel (enable toggle, epsilon slider, privacy-budget bar) plus a compact "DP Applied" provenance badge — driven by the app's DP-middleware state.
Differential Privacy Controls
The Differential Privacy Controls are a collapsible settings panel — an enable toggle, an epsilon slider with a derived privacy-level label (High/Balanced/Low), and a privacy-budget bar that turns warning then error as the budget is consumed — plus a compact DP Applied provenance badge (lock icon, epsilon used, embedding dimensionality) for rendering beneath protected output.
No turnkey hook. This primitive does no DP math. There is no
@localmode/reacthook behind it — the app owns the DP state, wiringdpEmbeddingMiddleware/dpClassificationMiddlewareand acreatePrivacyBudgettracker from@localmode/core, then passingenabled,epsilon, and the livebudgetin. The component only renders and reports user intent through the change callbacks.
When to use it: any local-first surface that perturbs embeddings or classification results with differential privacy and wants the user to control the privacy/accuracy tradeoff and see how much budget is left.
Preview
Installation
pnpm dlx shadcn@latest add @localmode/ui/security-privacy/differential-privacy-controlsnpx shadcn@latest add @localmode/ui/security-privacy/differential-privacy-controlsyarn dlx shadcn@latest add @localmode/ui/security-privacy/differential-privacy-controlsbunx --bun shadcn@latest add @localmode/ui/security-privacy/differential-privacy-controlsDependencies
- Data source: renders the
enabled/epsilon/budgetprops you pass and emits change callbacks — works with any backend; the component does no DP math. Recommended LocalMode producers:dpEmbeddingMiddleware/dpClassificationMiddleware+createPrivacyBudgetfrom@localmode/core, whose state you wire in (optional). lucide-react— theShieldCheck/ChevronDown/Lockiconsradix-ui— via theCollapsible,Slider, andSwitchprimitivesui/collapsible,ui/slider,ui/switch,ui/badge— the shadcn/ui base primitives (installed automatically as registry dependencies)clsx+tailwind-merge— via the sharedcn()util (installed automatically as a registry dependency)
Files installed
differential-privacy-controls.tsx— the panel and theDpAppliedBadgeui/collapsible.tsx,ui/slider.tsx,ui/switch.tsx,ui/badge.tsx— base primitives (registry dependencies)lib/utils.ts— thecn()helper (if not already present)
Props
DifferentialPrivacyControls
DifferentialPrivacyControls
Prop
Type
DpAppliedBadge
DpAppliedBadge
Prop
Type
Examples
Driven by app DP state
The app owns the DP middleware and the budget tracker. The panel renders that state and reports user changes:
import { createPrivacyBudget } from '@localmode/core';
import { DifferentialPrivacyControls } from '@/components/differential-privacy-controls';
const budget = await createPrivacyBudget({ maxEpsilon: 10, persistKey: 'my-app' });
export function Settings() {
const [enabled, setEnabled] = useState(true);
const [epsilon, setEpsilon] = useState(1.0);
const [consumed, setConsumed] = useState(budget.consumed());
return (
<DifferentialPrivacyControls
enabled={enabled}
onEnabledChange={setEnabled}
epsilon={epsilon}
onEpsilonChange={setEpsilon}
budget={{ consumed, maxEpsilon: 10 }}
/>
);
}Each protected query consumes epsilon from the real tracker; reflect that into the budget prop so the bar transitions ok → warning → error:
// after a DP-protected embedding/classification runs
budget.consume(epsilon);
setConsumed(budget.consumed());"DP Applied" provenance badge
Render the badge beneath protected output only when DP was actually applied, with the real epsilon and the embedding model's dimensionality:
import { DpAppliedBadge } from '@/components/differential-privacy-controls';
{dpEnabled && <DpAppliedBadge epsilon={epsilon} dimensions={model.dimensions} />}The badge fields must match the values emitted by the DP middleware run
(DPEmbeddingConfig.epsilon, the embedding model's dimensions) — never
placeholder values.
Disabled state
When the toggle is off, the slider and budget bar dim and you should not render
the DpAppliedBadge — no DP was applied, so showing provenance would be
misleading:
<DifferentialPrivacyControls enabled={false} /* … */ />
{/* no DpAppliedBadge while disabled */}Customization
The panel is styled with shadcn/ui CSS-variable utilities (bg-card,
border-border, text-muted-foreground) and composes the Collapsible,
Slider, Switch, and Badge base primitives, so it inherits your theme. The
budget/level state colors use Tailwind's red / amber / emerald palettes
directly — swap those classes in the copied file to match your design system.
Because you own the file, you can adjust the epsilon→level thresholds
(privacyLevelForEpsilon) and the budget warning/error thresholds to match your
privacy policy.
Accessibility
The ε control renders the Radix Slider primitive directly (Radix ignores
aria-label on the Root), so the accessible name and readout land on the
focusable Thumb — the role="slider" element. The Thumb carries a fixed
aria-label ("Epsilon (privacy budget per query)") and an aria-valuetext
that spells out both the value and the derived privacy level (e.g. "ε 1.0 — High privacy"), so screen readers announce the privacy trade-off, not just a
number. The spent-budget bar is a labelled role="progressbar" ("Privacy budget consumed"). getByRole('slider', { name: /epsilon/i }) resolves the
control uniquely.
Password Strength Bar
A presentational password/passphrase strength meter — a themed bar + label driven by a caller-computed 0–100 strength score.
Passphrase Gate
A controlled passphrase screen with create and unlock modes — composes the password strength bar and surfaces errors, performing no crypto itself.