checkbox/00-permissions-panel
An invite panel — labeled permission checkboxes with helper text against a skeleton avatar stack, gating a primary action.
Loading interactive preview
"use client";
import { useState } from 'react';
import { Button } from 'ui-lab-components/button'
import { Checkbox } from 'ui-lab-components/checkbox'
import { Flex } from 'ui-lab-components/flex';
const invitees = ['Ava', 'Marcus', 'Priya'];
const permissions = [
{ id: 'edit', label: 'Edit files', helper: 'Create, rename, and update project files.' },
{ id: 'invite', label: 'Invite members', helper: 'Add or remove people from this workspace.' },
{ id: 'billing', label: 'Manage billing', helper: 'View invoices and change the payment method.' },
];
export default function Example() {
const [granted, setGranted] = useState<Set<string>>(new Set(['edit']));
const toggle = (id: string) => {
setGranted((current) => {
const next = new Set(current);
next.has(id) ? next.delete(id) : next.add(id);
return next;
});
};
return (
<section className="flex flex-col gap-6 rounded-sm p-5">
<Flex align-center gap="md" aria-hidden="true">
<div className="flex -space-x-2">
{invitees.map((_, i) => (
<div
key={i}
className="h-8 w-8 rounded-full border-2 border-background-950 bg-background-700/50"
style={{ opacity: 1 - i * 0.2 }}
/>
))}
</div>
<Flex direction="column" gap="xs">
<div className="h-3 w-32 rounded bg-background-700/55" />
<div className="h-2.5 w-20 rounded bg-background-700/30" />
</Flex>
</Flex>
<div className="h-px bg-background-700/40" aria-hidden="true" />
<Flex direction="column" gap="sm">
{permissions.map((permission) => (
<Checkbox
key={permission.id}
id={`permission-${permission.id}`}
label={permission.label}
helper={permission.helper}
selected={granted.has(permission.id)}
onChange={() => toggle(permission.id)}
/>
))}
</Flex>
<Button variant="primary" disabled={granted.size === 0} styles={{ root: 'w-full' }}>
Send invite
</Button>
</section>
);
}