Cross-Platform¶
Craft Easy Admin runs on web, iOS, and Android from a single codebase using React Native + Expo. The UI adapts automatically to each platform.
Platform Support¶
| Platform | Runtime | Notes |
|---|---|---|
| Web | react-native-web | Standard browser deployment |
| iOS | Expo (native) | Full native performance |
| Android | Expo (native) | Full native performance |
Responsive Layout¶
Desktop (width >= 768px)¶
- Sidebar is permanently visible on the left (250px wide)
- Header spans the remaining width, no menu button
- Content fills the remaining space
┌──────────┬─────────────────────────────────┐
│ │ Header │
│ Sidebar ├─────────────────────────────────┤
│ (250px) │ │
│ │ Content Area │
│ │ │
│ │ │
└──────────┴─────────────────────────────────┘
Mobile (width < 768px)¶
- Sidebar hidden, rendered as a drawer/modal overlay
- Header shows a menu button to open the drawer
- Content takes full width
┌─────────────────────────────────┐
│ [☰] Header │
├─────────────────────────────────┤
│ │
│ Content Area │
│ (full width) │
│ │
└─────────────────────────────────┘
Mobile-Optimized Components¶
Several components use modal-based pickers optimized for touch:
| Component | Desktop | Mobile |
|---|---|---|
| Select | Modal dropdown | Slide-up modal with FlatList |
| MultiSelect | Modal with checkboxes | Same — touch-friendly checkboxes |
| RelationPicker | Search modal | Same — with ActivityIndicator |
| Navigation | Sidebar | Drawer overlay |
All interactive elements use appropriate touch targets:
- Minimum
hitSlop={8}on small buttons Pressablecomponents with adequate spacing- Modal animations via
animationType="slide"for native feel
ETag Collision Modal¶
When two users edit the same document simultaneously, the API returns 412 Precondition Failed. The admin app handles this with a dedicated collision modal:
interface ETagCollisionModalProps {
visible: boolean;
onReload: () => void;
onOverwrite: () => void;
onCancel: () => void;
}
When it appears: A PATCH or PUT request fails with HTTP 412, meaning the document was modified since it was loaded.
Options:
| Action | Behavior |
|---|---|
| Reload | Fetches the latest version, re-initializes the form with updated data |
| Overwrite | Fetches the latest ETag, re-submits the user's changes with the new ETag |
| Cancel | Closes the modal, abandons the save attempt |
This prevents silent data loss from concurrent edits.
Soft Delete Filter¶
List views include a SoftDeleteFilter toggle that controls whether soft-deleted items are visible:
When enabled, the list query includes is_deleted=true items in the results.
Views¶
The admin app includes four view types that adapt to the current resource schema:
ListView¶
- Breadcrumb navigation
- Title with item count
- Search bar (when
search_fieldsconfigured) - Sort chips (when
sort_fieldsconfigured) - Paginated list with
FlatList - Bulk selection via long-press
- Create button (when
features.createis true)
DetailView¶
- Read-only display of all fields
- Edit button (when
features.editis true) - Delete button with confirmation dialog (when
features.deleteis true) - Audit trail section (created_at, updated_at, created_by, updated_by)
- Formatted values: booleans as checkmarks, dates localized, numbers formatted
CreateView¶
- Form groups from
resource.form.groups - Field validation: required, min_length, regex pattern
- Cancel and Save buttons
EditView¶
- Same form layout as CreateView
- Pre-populated with current data via
useResource() - ETag collision detection on save
- Cancel, Save buttons