Files
skills/docs/ui/react/react-auth/src/components/permission-gate/permission-gate.md
2026-05-29 08:20:56 +01:00

3.0 KiB

<PermissionGate> — bitmask permission gate

(no submodules)

Purpose

<PermissionGate> is a declarative conditional renderer that consumes the Wave 1 usePermission() hook and decides whether to render its children based on the current user's bitwise permission set. It is the primary tool for hiding UI surfaces (admin links, destructive buttons, advanced settings panels) from users who lack the required permission bits.

The component is intentionally tiny — every interesting policy decision is delegated to usePermission(), which in turn reads useAuth().user.roles and performs the bitwise AND against the configured permission constants from Permissions. Two semantics are supported: any-of (the default, useful for "show this if any one of these roles applies") and all-of (requireAll, useful for compound predicates such as "must have both moderator and admin").

Features

  • Any-of semantics by default; all-of via requireAll.
  • Accepts named Permission keys ("USER_READ", "ADMIN_WRITE", ...) or raw numeric bitmasks.
  • Fallback subtree (default null) rendered when the check fails.
  • Unauthenticated users always fail the check — usePermission() returns false when user === null.
  • Zero runtime cost beyond a single context read + bitwise AND.

Usage: Basic

import { PermissionGate } from "@suaveplan/react-auth";

export function AdminLink() {
    return (
        <PermissionGate permissions={["ADMIN_READ"]}>
            <a href="/admin">Admin Console</a>
        </PermissionGate>
    );
}

Usage: Advanced

import { PermissionGate, Permissions } from "@suaveplan/react-auth";

export function ModeratorPanel() {
    return (
        <PermissionGate
            permissions={[
                Permissions.MODERATE_USERS,
                Permissions.MODERATE_CONTENT,
            ]}
            requireAll
            fallback={<p>You do not have moderator access.</p>}
        >
            <ModeratorTools />
        </PermissionGate>
    );
}

API Reference

PermissionGateProps

Field Type Default Description
children ReactNode — Subtree rendered when the permission check passes.
fallback ReactNode null Subtree rendered when the permission check fails.
permissions ReadonlyArray<Permission | number> [] Permission keys or raw numeric bitmasks.
requireAll boolean false When true, every entry must match (all-of).

Implementation Notes

  • Empty permissions array combined with default requireAll={false} denies (because [].some(...) === false). This matches the upstream contract; pass requireAll={true} to allow on empty input.
  • The gate does NOT throw when no <AuthProvider> is mounted — usePermission() does, surfacing the misuse at the call site rather than silently rendering the fallback.
  • For route-level guarding, prefer <AuthGuard> (which redirects); <PermissionGate> is for in-page subtree hiding.