Get Started
Introduction
Components
Accordion
Badge
Button
Card
Checkbox
Command
Dialog
Dropdown Menu
Input
Select
Switch
Table
Tabs
Toast
Tooltip
Forms
Introduction
Validation
Field Arrays

Permission Matrix

A Role x Permission grid with inheritance cascade, diamond memo dependency graphs, cascading derived state, and 2D grid rendering with bulk operations.

#Preview

Permission Matrix

Direct: 12Inherited: 16
Viewer: 2/12Editor: 5/12Admin: 9/12Owner: 12/12
Permission
Viewer
Editor
Admin
Owner
CreateContent
ReadContent
UpdateContent
DeleteContent
InviteUsers
ManageUsers
RemoveUsers
BillingSettings
IntegrationsSettings
SecuritySettings
ViewReports
ExportReports
Direct grant Inherited (disabled)
1"use client"23import { createSignal, createMemo } from '@barefootjs/client'4import { Checkbox } from '@/components/ui/checkbox'56const ROLES = [7  { id: 'viewer', rank: 4 },8  { id: 'editor', rank: 3 },9  { id: 'admin', rank: 2 },10  { id: 'owner', rank: 1 },11]1213function PermissionMatrix() {14  const [directGrants, setDirectGrants] = createSignal({})1516  // Diamond memo: directGrants → effectivePerms → cellStates + roleStats17  const effectivePerms = createMemo(() => {18    const grants = directGrants()19    const result = {}20    for (const role of ROLES) {21      const effective = new Set()22      for (const r of ROLES) {23        if (r.rank >= role.rank) {24          for (const p of (grants[r.id] || [])) effective.add(p)25        }26      }27      result[role.id] = [...effective]28    }29    return result30  })3132  const cellStates = createMemo(() => {33    const grants = directGrants()34    const effective = effectivePerms()35    const states = {}36    for (const role of ROLES) {37      for (const permId of ALL_PERM_IDS) {38        const key = role.id + ':' + permId39        const isEffective = (effective[role.id] || []).includes(permId)40        const isDirect = (grants[role.id] || []).includes(permId)41        // Inherited if a lower-authority role has it directly42        const fromBelow = ROLES.some(r =>43          r.rank > role.rank && (grants[r.id] || []).includes(permId)44        )45        const inherited = isEffective && fromBelow46        states[key] = { checked: isEffective, inherited, disabled: inherited }47      }48    }49    return states50  })5152  return (53    <table>54      <tbody>55        {ALL_PERMISSIONS.map(perm => (56          <tr key={perm.id}>57            <td>{perm.label}</td>58            {ROLES.map(role => (59              <td key={role.id}>60                <Checkbox61                  checked={cellStates()[role.id + ':' + perm.id].checked}62                  disabled={cellStates()[role.id + ':' + perm.id].disabled}63                  onCheckedChange={() => toggle(role.id, perm.id)}64                />65              </td>66            ))}67          </tr>68        ))}69      </tbody>70    </table>71  )72}

#Features

Diamond Memo Dependency Graph

directGrants signal feeds into effectivePerms memo, which feeds into both cellStates and roleStats memos. cellStates also reads directGrants directly, forming a diamond DAG where multiple paths converge on the same data sources. Tests that the compiler correctly tracks and batches updates across shared dependencies.

Inheritance Cascade

Roles are ranked (Owner > Admin > Editor > Viewer). When a permission is directly granted to a lower-ranked role, all higher-ranked roles automatically inherit it. Inherited checkboxes appear checked but disabled with reduced opacity, ensuring the cascade is both visually distinct and functionally correct.

2D Nested Loop with Per-Cell State

The grid renders as ALL_PERMISSIONS.map(perm => ROLES.map(role => cell)). Each cell reads from the cellStates memo to determine checked, inherited, and disabled status. Tests nested static array mapArray with per-item reactive attribute binding on Checkbox components.

Bulk Toggle Operations

"All" and "None" buttons per role (column) and "+" and "-" buttons per permission (row) trigger batch mutations that cascade through the entire memo chain. Tests that bulk signal updates propagate correctly through the diamond dependency graph.

Reactive Text in Loop

Per-role permission count badges (e.g., "Admin: 8/12") update reactively as permissions are toggled. Tests reactive text interpolation inside loop iterations.