@matteoaliano/forest-ui 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,256 @@
1
+ # Forest UI — Code Patterns & Anti-Patterns
2
+
3
+ ## Code Patterns
4
+
5
+ ### Form Layout
6
+
7
+ ```tsx
8
+ import { TextField, Button, Select, MenuItem, Checkbox } from "@matteoaliano/forest-ui";
9
+ import Box from "@mui/material/Box"; // Box, Stack, Grid are OK from MUI
10
+
11
+ function ContactForm() {
12
+ return (
13
+ <Box sx={{ display: "flex", flexDirection: "column", gap: 3 }}>
14
+ <TextField label="Name" fullWidth />
15
+ <TextField label="Email" type="email" fullWidth />
16
+ <Select label="Subject" fullWidth>
17
+ <MenuItem value="support">Support</MenuItem>
18
+ <MenuItem value="sales">Sales</MenuItem>
19
+ </Select>
20
+ <Button variant="contained" type="submit">
21
+ Send
22
+ </Button>
23
+ </Box>
24
+ );
25
+ }
26
+ ```
27
+
28
+ ### MultiSelect with Select All
29
+
30
+ ```tsx
31
+ import { useState } from "react";
32
+ import { MultiSelect } from "@matteoaliano/forest-ui";
33
+
34
+ const options = [
35
+ { label: "Bug", value: "bug" },
36
+ { label: "Enhancement", value: "enhancement" },
37
+ { label: "New Feature", value: "feature" },
38
+ ];
39
+
40
+ function CategoryFilter() {
41
+ const [selected, setSelected] = useState<string[]>([]);
42
+ return (
43
+ <MultiSelect
44
+ label="Category"
45
+ options={options}
46
+ value={selected}
47
+ onChange={setSelected}
48
+ />
49
+ );
50
+ }
51
+ ```
52
+
53
+ ### Data Table
54
+
55
+ ```tsx
56
+ import {
57
+ Table, TableContainer, TableHead, TableBody, TableRow, TableCell,
58
+ } from "@matteoaliano/forest-ui";
59
+
60
+ function UsersTable({ users }) {
61
+ return (
62
+ <TableContainer>
63
+ <Table>
64
+ <TableHead>
65
+ <TableRow>
66
+ <TableCell>Name</TableCell>
67
+ <TableCell>Email</TableCell>
68
+ </TableRow>
69
+ </TableHead>
70
+ <TableBody>
71
+ {users.map((u) => (
72
+ <TableRow key={u.id}>
73
+ <TableCell>{u.name}</TableCell>
74
+ <TableCell>{u.email}</TableCell>
75
+ </TableRow>
76
+ ))}
77
+ </TableBody>
78
+ </Table>
79
+ </TableContainer>
80
+ );
81
+ }
82
+ ```
83
+
84
+ ### DataGrid
85
+
86
+ ```tsx
87
+ import { DataGrid, type GridColDef } from "@matteoaliano/forest-ui";
88
+
89
+ const columns: GridColDef[] = [
90
+ { field: "id", headerName: "ID", width: 70 },
91
+ { field: "name", headerName: "Name", flex: 1 },
92
+ { field: "email", headerName: "Email", flex: 1 },
93
+ ];
94
+
95
+ function UsersGrid({ rows }) {
96
+ return <DataGrid rows={rows} columns={columns} />;
97
+ }
98
+ ```
99
+
100
+ ### Feedback Pattern
101
+
102
+ ```tsx
103
+ import { Alert, AlertTitle, Snackbar } from "@matteoaliano/forest-ui";
104
+
105
+ // Inline feedback
106
+ <Alert severity="error">
107
+ <AlertTitle>Error</AlertTitle>
108
+ Something went wrong.
109
+ </Alert>
110
+
111
+ // Toast notification
112
+ <Snackbar open={open} autoHideDuration={4000} onClose={handleClose}>
113
+ <Alert severity="success" variant="filled">Saved!</Alert>
114
+ </Snackbar>
115
+ ```
116
+
117
+ ### Confirmation Dialog
118
+
119
+ ```tsx
120
+ import { Dialog, DialogTitle, DialogContent, DialogActions, DialogContentText, Button } from "@matteoaliano/forest-ui";
121
+
122
+ function ConfirmDialog({ open, onClose, onConfirm }) {
123
+ return (
124
+ <Dialog open={open} onClose={onClose}>
125
+ <DialogTitle>Confirm</DialogTitle>
126
+ <DialogContent>
127
+ <DialogContentText>Are you sure?</DialogContentText>
128
+ </DialogContent>
129
+ <DialogActions>
130
+ <Button variant="outlined" onClick={onClose}>Cancel</Button>
131
+ <Button onClick={onConfirm}>Confirm</Button>
132
+ </DialogActions>
133
+ </Dialog>
134
+ );
135
+ }
136
+ ```
137
+
138
+ ### Sidebar Navigation
139
+
140
+ ```tsx
141
+ import { SidebarNav, SidebarItem } from "@matteoaliano/forest-ui";
142
+ import DashboardOutlined from "@mui/icons-material/DashboardOutlined";
143
+ import SettingsOutlined from "@mui/icons-material/SettingsOutlined";
144
+
145
+ function AppShell() {
146
+ const [open, setOpen] = useState(true);
147
+ return (
148
+ <SidebarNav open={open} onOpenChange={setOpen}>
149
+ <SidebarItem icon={<DashboardOutlined />} label="Dashboard" selected />
150
+ <SidebarItem icon={<SettingsOutlined />} label="Settings" />
151
+ </SidebarNav>
152
+ );
153
+ }
154
+ ```
155
+
156
+ ### Charts
157
+
158
+ Colors are automatically assigned from the theme's 12-series palette. Override with the `colors` prop if needed.
159
+
160
+ ```tsx
161
+ import { BarChart, LineChart, PieChart, useChartColors } from "@matteoaliano/forest-ui";
162
+
163
+ // Bar chart with striped variant
164
+ <BarChart
165
+ series={[
166
+ { data: [10, 20, 30], label: "Current", variant: "solid" },
167
+ { data: [8, 15, 25], label: "Previous", variant: "striped" },
168
+ ]}
169
+ xAxis={[{ data: ["Jan", "Feb", "Mar"], scaleType: "band" }]}
170
+ height={300}
171
+ />
172
+
173
+ // Line chart
174
+ <LineChart
175
+ series={[{ data: [10, 20, 30], label: "Revenue" }]}
176
+ xAxis={[{ data: ["Jan", "Feb", "Mar"], scaleType: "band" }]}
177
+ height={300}
178
+ />
179
+
180
+ // Pie chart
181
+ <PieChart
182
+ series={[{ data: [
183
+ { id: 0, value: 40, label: "Desktop" },
184
+ { id: 1, value: 30, label: "Mobile" },
185
+ { id: 2, value: 30, label: "Tablet" },
186
+ ]}]}
187
+ height={300}
188
+ />
189
+
190
+ // Access chart colors programmatically
191
+ const colors = useChartColors(3);
192
+ ```
193
+
194
+ ## Storybook Controls
195
+
196
+ When adding argTypes to stories:
197
+
198
+ ```tsx
199
+ const meta: Meta<typeof Button> = {
200
+ component: Button,
201
+ argTypes: {
202
+ variant: {
203
+ control: "select",
204
+ options: ["contained", "outlined", "text"],
205
+ },
206
+ color: {
207
+ control: "select",
208
+ options: ["primary", "secondary", "error", "warning", "success", "info"],
209
+ },
210
+ disabled: { control: "boolean" },
211
+ },
212
+ };
213
+ ```
214
+
215
+ **Control types:** `"select"` with `options`, `"boolean"`, `"number"`, `"text"`.
216
+
217
+ ## Anti-Patterns
218
+
219
+ ```tsx
220
+ // WRONG: importing from @mui/material
221
+ import Button from "@mui/material/Button";
222
+
223
+ // WRONG: hardcoded colors
224
+ <Box sx={{ backgroundColor: "#7f56d9" }} />
225
+
226
+ // WRONG: hardcoded spacing
227
+ <Box sx={{ padding: "16px" }} />
228
+
229
+ // WRONG: forgetting ForestProvider
230
+ ReactDOM.render(<App />, root); // theme won't apply
231
+
232
+ // WRONG: using filled (default) icons
233
+ import CloseIcon from "@mui/icons-material/Close";
234
+
235
+ // CORRECT: always use Outlined variant
236
+ import CloseIcon from "@mui/icons-material/CloseOutlined";
237
+
238
+ // CORRECT: use theme tokens
239
+ <Box sx={{ backgroundColor: "primary.main", p: 4 }} />
240
+
241
+ // WRONG: manually building multi-select with Select + Checkbox
242
+ // CORRECT: use the MultiSelect component
243
+ <MultiSelect options={options} value={value} onChange={setValue} />
244
+ ```
245
+
246
+ ## TypeScript Props
247
+
248
+ Every component exports its props type:
249
+
250
+ ```tsx
251
+ import { Button, type ButtonProps } from "@matteoaliano/forest-ui";
252
+
253
+ interface MyButtonProps extends ButtonProps {
254
+ analyticsId: string;
255
+ }
256
+ ```