MiHCM
primitives/@mihcm/ui·v0.21.0·stable

AccessLevelGroup

4-state segmented button: None / View / Edit / Full Access. Each option has its own brand color when active.

Single row

import { useState } from 'react';
import { AccessLevelGroup, type AccessLevel } from '@mihcm/ui/AccessLevelGroup';
 
const [level, setLevel] = useState<AccessLevel>('view');
 
<AccessLevelGroup value={level} onValueChange={setLevel} />

Per-module rows (canonical use case)

Leave
Attendance
Payroll
Reports
import { AccessLevelGroup, type AccessLevel } from '@mihcm/ui/AccessLevelGroup';
 
const MODULES = ['Leave', 'Attendance', 'Payroll', 'Reports'];
const [levels, setLevels] = useState<Record<string, AccessLevel>>({});
 
{MODULES.map((m) => (
  <div key={m} className="flex items-center justify-between gap-3">
    <span className="text-sm font-medium">{m}</span>
    <AccessLevelGroup
      value={levels[m] ?? 'none'}
      onValueChange={(v) => setLevels((prev) => ({ ...prev, [m]: v }))}
    />
  </div>
))}

Disabled

<AccessLevelGroup value="full" onValueChange={() => {}} disabled />

Custom labels

import { AccessLevelGroup, type AccessLevelOption } from '@mihcm/ui/AccessLevelGroup';
 
const REVIEW_LEVELS: AccessLevelOption[] = [
  { value: 'none', label: 'Not reviewed', tone: 'neutral' },
  { value: 'view', label: 'In review',    tone: 'view' },
  { value: 'edit', label: 'Approved',     tone: 'accent' },
  { value: 'full', label: 'Published',    tone: 'primary' },
];
 
<AccessLevelGroup
  value={status}
  onValueChange={setStatus}
  options={REVIEW_LEVELS}
/>