07 — Component Library (Staff Module)
- 1. Shared components in use (by screen)
- 2. Module-specific components
- 3. Composition rules
- 4. Golden tests
Module-specific components. Shared components are referenced by name from 00-shared/03_Component_Library.md; this file adds staff-specific widgets only. All tokens per 00-shared/02.
1. Shared components in use (by screen)
| Shared component | Screens |
|---|---|
AppSkeleton | S1, S6, S9 lists |
AppEmptyState | S1, S2 (404), S6, S7, S9, S10 |
AppErrorState | all (per error code) |
AppSearchBar | S1, S6, S9 (client-side filtering — server ignores q for staff, OQ-2) |
AppChips (FilterChip) | S1 status/type filters |
AppListTile | S1, S6, S7, S9, S10 rows |
AppAvatar | S1 rows, S2 header, S7 head |
AppBadge | status badges (S1, S2, S6, S9) |
AppTabs | S2 detail tabs |
AppFAB | S1, S6, S9 ("Add staff/department/designation") |
AppButton | forms, dialogs |
AppDialog | S5 deactivate confirm; delete confirms in catalogs |
AppMenu | row overflow menus |
AppSnackbar | create/update/deactivate feedback |
AppDropdown | department/designation/employment-type pickers |
AppDatePicker | joiningDate |
AppInfoRow | S2 detail fields |
AppSectionHeader | S7/S10 sections |
AppProgress | submit/pending states |
2. Module-specific components
StaffStatusBadge
- Props:
status: StaffStatus,size?. - Behavior: maps 1:1 to the enum (
staff.schema.ts:7-12):active→ success (secondary),inactive→ neutral (outline),on_leave→ tertiary/warning,terminated→ error. - A11y: icon + label + color — never color-only (00-shared/09 §9).
- Flutter:
AppBadgewithSemantics(label: 'Status: on leave').
EmploymentTypeLabel
- Props:
type: EmploymentType. - Behavior: renders humanized label for
full_time, part_time, contract, intern(staff.schema.ts:14-19), e.g. "Full-time". Localized; unknown value falls back to the raw string (server DTO allows any string — noIsEnumoncreate-staff.dto.ts:26-28, OQ-9). - Flutter: simple
Textwith a const map.
EmployeeNumberText
- Props:
employeeNumber: String. - Behavior:
monoface +FontFeature.tabularFigures()(00-shared/02 §2), copy affordance(proposed). - Flutter:
TextwithfontFamilyFallbackmono +SelectableText.
RefChip (department/designation ref)
- Props:
label,href. - Behavior: navigation chip for a resolved
departmentId/designationId; renders "—" when the ref is unset or unresolvable (soft-deleted catalog entry → 404 on lookup,base.repository.ts:20-30). - Flutter:
ActionChip+ null-state Text.
CatalogPickerSheet (used in S3, S4, S8, S11)
- Props:
endpoint(departments | designations),value,onPicked,allowClear. - Behavior:
AppBottomSheetlist backed byGET /departmentsorGET /designations(pagination + client search); onlystatus: activeentries offered(proposed); "Unassigned" clear option; empty state → "No departments yet — create one". - Flutter:
showModalBottomSheet+ListView.builder.
HeadPicker (S8)
- Props:
value,onPicked. - Behavior: staff picker limited to
status: active((proposed)filter over staff list; backend list returns all —staff.service.ts:64-76); shows employee number + name. - Flutter: sheet with
SearchBar+ListTiles.
MetadataEditor (S4 metadata field)
- Props:
value: Map<String, Object?>,onChanged. - Behavior: editable key/value rows (add/remove) bound to the free-form
metadataobject (staff.schema.ts:51-52,update-staff.dto.ts:40-42); values serialized as JSON strings client-side(proposed). - Flutter:
ListViewofRow(key TextField, value TextField, remove IconButton)- "Add field"
TextButton.
- "Add field"
3. Composition rules
- List screens:
AppScaffold+RefreshIndicator+ListView.builder+ footer (spinner / end-of-list) (00-shared/03 §F). - Detail: header
AppCard+AppTabs; tab content inTabBarViewwith keep-alive. - Forms: one screen, fields in
FormwithAppTextField/AppDropdown/AppDatePicker(08_Form_Specifications.md); submitAppButton(filled, loading:).
4. Golden tests
New components get goldens at 3 sizes + dark mode (00-shared/03 §G):
StaffStatusBadge (4 states), EmploymentTypeLabel (4 values), RefChip
(resolved/unset), CatalogPickerSheet (data/empty/error).