Active Foundation · Example
Actions blocked with a reason
Actions blocked with a reasonClient
You need the approver role to approve statements.Statements that were sent cannot be changed.
Approved 0 times.
Full source examples/ui/guarded-action.tsx
// apps/docs/examples/ui/guarded-action.tsx'use client';
import {useState} from 'react';
import {GuardedAction} from '@workspace/active-ui/components/composed/guarded-action';import { Field, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import {Switch} from '@workspace/active-ui/components/primitives/switch';
/** * An action with the reason it is blocked. Without a reason it is an * ordinary button. Blocked, it stays focusable: hover or focus it to read * why, and pressing it does nothing. The permission is a switch here; in an * application it comes from your own rules. */export default function GuardedActionExample() { const [mayApprove, setMayApprove] = useState(false); const [approved, setApproved] = useState(0); return ( <div className="grid w-full max-w-sm justify-items-start gap-6"> <Field orientation="horizontal"> <Switch id="may-approve" checked={mayApprove} onCheckedChange={setMayApprove} /> <FieldLabel htmlFor="may-approve">I may approve statements</FieldLabel> </Field> <div className="flex gap-3"> <GuardedAction variant="outline" onClick={() => setApproved((count) => count + 1)} disabledReason={ mayApprove ? null : 'You need the approver role to approve statements.' } > Approve </GuardedAction> <GuardedAction variant="outline" disabledReason="Statements that were sent cannot be changed." reasonSide="bottom" > Edit </GuardedAction> </div> <p className="text-muted-foreground text-sm" aria-live="polite"> Approved {approved} {approved === 1 ? 'time' : 'times'}. </p> </div> );}