componentType | Description | Example |
---|---|---|
Action Buttons | CRUD operations with built-in state management |
|
Form Wrappers | Specialized form components with validation |
|
Data Visualizers | Components for displaying model statistics |
|
Composite Utilities | Combined functionality components |
|
CRUD operations with built-in state management
DeleteButton, CreateButton, RefreshButton
Specialized form components with validation
QuickEditForm, StatusToggle
Components for displaying model statistics
StatsPanel, AnalyticsChart
Combined functionality components
FilterPanel, CategorySelector
// File: lib/project/Project.Util.tsx
"use client";
import { useState } from "react";
import { Button } from "@util/ui";
import { projectStore } from "./project.store";
import { projectSignal } from "./project.signal";
export const CreateButton = ({ className }: { className?: string }) => {
const { showCreateModal } = projectStore();
return (
<Button
className={className}
variant="primary"
onClick={showCreateModal}
>
Create New Project
</Button>
);
};
export const DeleteButton = ({ id, name }: { id: string; name: string }) => {
const [confirming, setConfirming] = useState(false);
const { deleteProject } = projectStore();
const handleDelete = async () => {
await projectSignal.deleteProject(id);
setConfirming(false);
deleteProject(id);
};
return (
<>
<Button variant="error" onClick={() => setConfirming(true)}>
Delete
</Button>
{confirming && (
<div className="modal modal-open">
<div className="modal-box">
<h3>Confirm Delete</h3>
<p>Delete project {name}?</p>
<div className="modal-action">
<Button variant="outline" onClick={() => setConfirming(false)}>
Cancel
</Button>
<Button variant="error" onClick={handleDelete}>
Confirm
</Button>
</div>
</div>
</div>
)}
</>
);
};
Option | Type | Default | Description | Example |
---|---|---|---|---|
useStore | Hook | - | Access store state and actions |
|
Selective State | Pattern | - | Extract only needed state properties |
|
Loading States | Handling | - | Track and display loading indicators |
|
Access store state and actions
st.use.model()
Extract only needed state properties
state => ({ item: state.items[id] })
Track and display loading indicators
isUpdating, isRefreshing
export const StatusToggle = ({ id }: { id: string }) => {
const { status, updateStatus } = projectStore(
(state) => ({
status: state.projects[id]?.status,
updateStatus: state.updateStatus
})
);
const toggle = () => {
const newStatus = status === 'active' ? 'inactive' : 'active';
updateStatus(id, newStatus);
};
return (
<Toggle
checked={status === 'active'}
onChange={toggle}
label={status === 'active' ? 'Active' : 'Inactive'}
/>
);
};
import { memo } from "react";
export const StatCard = memo(({ value, label }: { value: number; label: string }) => (
<div className="stats bg-base-200">
<div className="stat">
<div className="stat-title">{label}</div>
<div className="stat-value">{value}</div>
</div>
</div>
));
// Lazy load heavy components
const LazyChart = dynamic(() => import('./ChartComponent'), {
loading: () => <div className="loading loading-spinner"></div>
});
export const AnalyticsPanel = ({ id }: { id: string }) => (
<div className="h-96">
<LazyChart projectId={id} />
</div>
);
// In Views
import { ProjectUtil } from "../project.Util";
export const ProjectDetailView = ({ id }) => (
<div className="p-4">
<div className="flex justify-end gap-2 mb-4">
<ProjectUtil.EditButton id={id} />
<ProjectUtil.ShareButton id={id} />
<ProjectUtil.DeleteButton id={id} />
</div>
{/* ... */}
</div>
);
// In Units
export const ProjectCard = ({ project }) => (
<div className="card bg-base-100 shadow">
<div className="card-body">
<h3 className="card-title">{project.name}</h3>
<ProjectUtil.StatusBadge status={project.status} />
<div className="card-actions justify-end">
<ProjectUtil.ViewButton id={project.id} />
</div>
</div>
</div>
);
// In Templates
export const ProjectForm = () => (
<form>
{/* Form fields */}
<ProjectUtil.CategorySelector />
<ProjectUtil.TagsInput />
<div className="form-actions">
<ProjectUtil.CancelButton />
<ProjectUtil.SubmitButton />
</div>
</form>
);
/**
* Renders a status badge with color coding
*
* @param status - Current project status
* @param size - Badge size (sm/md/lg)
*/
export const StatusBadge = ({
status,
size = 'md'
}: {
status: ProjectStatus;
size?: 'sm' | 'md' | 'lg';
}) => {
const colorMap = {
active: 'success',
pending: 'warning',
archived: 'neutral'
};
return (
<span className={`badge badge-${colorMap[status]} badge-${size}`}>
{status}
</span>
);
};