Permissions
Client-side permission checks for @sumx/ui components and host screens. Server APIs remain authoritative — this layer is UX only.
Provider
import { PermissionProvider, type PermissionCheckFn } from '@sumx/ui';
const checkPermission: PermissionCheckFn = (keys) => {
if (keys.includes('allow')) return true;
return keys.some((k) => permissionStore.has(k));
};
<PermissionProvider checkPermission={checkPermission}>
{children}
</PermissionProvider>PermissionProviderProps
| Prop | Type | Description |
|---|---|---|
checkPermission | (keys: string[]) => boolean | Returns whether the current user may use the resource keys |
children | ReactNode | App tree |
usePermission
const { checkPermission } = usePermission();
const canEdit = checkPermission(['invoice.update']);Throws if used outside PermissionProvider.
hasPermission (non-React)
import { hasPermission } from '@sumx/ui';
hasPermission(['a', 'b'], (keys) => store.hasAny(keys));Use in services or tests when you already have a checker function.
usePermissionGate
Low-level hook used by Button and DialogTrigger:
const gate = usePermissionGate(['report.export'], 'disable');
// gate.show, gate.disabled, gate.allowedpermissionMode | Denied behavior |
|---|---|
hide (default) | show: false — component not rendered |
disable | show: true, disabled: true |
Types
type PermissionMode = 'hide' | 'disable';
type PermissionCheckFn = (keys: string[]) => boolean;
type SumxPermission = string; // resource key from your APIPortal wiring
// src/shared/providers/sumx-ui-permission-provider.tsx
import { PermissionProvider } from '@sumx/ui';
import usePermissionStore from '@/store/permissionStore';
export function SumxUiPermissionProvider({ children }) {
const has = usePermissionStore((s) => s.hasPermission);
return (
<PermissionProvider
checkPermission={(keys) =>
keys.includes('allow') || keys.some((k) => has(k))
}
>
{children}
</PermissionProvider>
);
}Place inside CheckToken (user known) and above feature routes in _app.tsx.