Components
Restricted Icon Button
A permission-gated action that's always visible — disabled with a reason, never hidden.
DS convention for any action the current user might not be permitted to take: show the control, disabled, with a tooltip stating why — never remove it from the page. An absent control is indistinguishable from a permissions gap, a rendering bug, or a feature that hasn't shipped yet; a visibly disabled one with a stated reason is not, for the user or for test automation asserting on it.
Hover or focus the Edit/Delete buttons above to see the reason.
Props
Accessibility
- Uses
aria-disabled, not the nativedisabledattribute — a truly disabled button stops receiving pointer and focus events in every browser, which would silently prevent the tooltip from ever triggering. The trigger stays keyboard-reachable. - The tooltip text is the only place the reason lives — make it specific enough to stand alone (e.g. "Only Product Team can edit price seasons," not "Not permitted").
Do / Don't
- Do use this for every row/toolbar action whose availability depends on the user's role or permissions.
- Don't conditionally render the button itself (
{canEdit && <IconButton .../>}) for a permission check — that reintroduces the hidden state this component exists to replace. - Don't use this for actions that are unavailable for a data reason (e.g. "nothing selected") — that's a different, non-permission disabled state and doesn't need a tooltip explaining a role.