@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,94 @@
1
+ # Forest UI — Component Reference
2
+
3
+ > Full API reference for all components exported by `@matteoaliano/forest-ui`.
4
+
5
+ ## Import Pattern
6
+
7
+ ```tsx
8
+ // CORRECT — import from forest-ui
9
+ import { Button, TextField, Alert } from "@matteoaliano/forest-ui";
10
+
11
+ // WRONG — never import from @mui/material
12
+ import Button from "@mui/material/Button";
13
+ ```
14
+
15
+ > Layout primitives (`Box`, `Stack`, `Grid`, `Container`) are NOT re-exported. Import those directly from `@mui/material`.
16
+
17
+ ## Inputs
18
+
19
+ | Component | Import | Variants / Key Props | Default Props |
20
+ |-----------|--------|----------------------|---------------|
21
+ | `Button` | `import { Button } from "forest-ui"` | `variant: "contained" \| "outlined" \| "text"`, `color`, `disabled`, `startIcon`, `endIcon`, `loading`, `fullWidth`, `href` | `variant="contained"`, `size` prop removed |
22
+ | `ButtonGroup` | `import { ButtonGroup } from "forest-ui"` | `variant: "contained" \| "outlined" \| "text"`, `size: "small" \| "medium" \| "large"`, `orientation: "horizontal" \| "vertical"`, `color`, `disabled`, `fullWidth` | `variant="contained"` |
23
+ | `TextField` | `import { TextField } from "forest-ui"` | `variant: "outlined" \| "filled" \| "standard"`, `size: "small" \| "medium"`, `label`, `error`, `helperText`, `fullWidth`, `multiline`, `rows`, `type`, `placeholder`, `required`, `disabled` | — |
24
+ | `Select` + `MenuItem` | `import { Select, MenuItem } from "forest-ui"` | `variant: "outlined" \| "filled" \| "standard"`, `size: "small" \| "medium"`, `multiple`, `displayEmpty`, `label`, `labelId`, `renderValue`, `native`, `error`, `disabled` | — |
25
+ | `MultiSelect` | `import { MultiSelect } from "forest-ui"` | `options: { label, value }[]`, `value: string[]`, `onChange: (values) => void`, `selectAll: boolean`, `selectAllLabel: string`, `label` + all SelectProps | `selectAll={true}`, `selectAllLabel="Select All"` |
26
+ | `Checkbox` | `import { Checkbox } from "forest-ui"` | `color: "default" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning"`, `size: "small" \| "medium"`, `checked`, `indeterminate`, `disabled` | — |
27
+ | `RadioGroup` + `Radio` | `import { RadioGroup, Radio } from "forest-ui"` | `row`, `value`, `onChange`; Radio: `color`, `size: "small" \| "medium" \| "large"`, `disabled` | — |
28
+ | `Switch` | `import { Switch } from "forest-ui"` | `color: "default" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning"`, `size: "small" \| "medium"`, `checked`, `disabled` | — |
29
+ | `ToggleButton` + `ToggleButtonGroup` | `import { ToggleButton, ToggleButtonGroup } from "forest-ui"` | `value`, `exclusive`, `onChange`, `orientation: "horizontal" \| "vertical"`, `size: "small" \| "medium" \| "large"`, `color`, `fullWidth` | — |
30
+ | `Fab` | `import { Fab } from "forest-ui"` | `variant: "circular" \| "extended"`, `size: "small" \| "medium" \| "large"`, `color`, `disabled`, `href` | `color="primary"` |
31
+ | `IconButton` | `import { IconButton } from "forest-ui"` | `color: "inherit" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning" \| "default"`, `size: "small" \| "medium" \| "large"`, `disabled`, `disableRipple` | — |
32
+ | `Autocomplete` | `import { Autocomplete } from "forest-ui"` | `options`, `renderInput` (required), `multiple`, `freeSolo`, `disableClearable`, `loading`, `groupBy`, `limitTags`, `filterOptions` | — |
33
+ | `Search` | `import { Search } from "forest-ui"` | `onClear`, `placeholder`, all TextField props (except `variant`) | `variant="outlined"`, `placeholder="Search..."`, built-in search icon and clear button |
34
+ | `DatePicker` | `import { DatePicker } from "forest-ui"` | All MUI X DatePicker props (`value`, `onChange`, `label`, `format`, `minDate`, `maxDate`, `disabled`, `readOnly`) | Wraps with `LocalizationProvider` + `AdapterDayjs` automatically |
35
+
36
+ ## Data Display
37
+
38
+ | Component | Import | Variants / Key Props | Default Props |
39
+ |-----------|--------|----------------------|---------------|
40
+ | `Badge` | `import { Badge } from "forest-ui"` | `variant: "standard" \| "dot"`, `color`, `badgeContent`, `max`, `invisible`, `showZero`, `overlap: "rectangular" \| "circular"`, `anchorOrigin` | — |
41
+ | `Chip` | `import { Chip } from "forest-ui"` | `variant: "filled" \| "outlined"`, `color`, `size: "small" \| "medium"`, `label`, `onDelete`, `clickable`, `avatar`, `icon` | `deleteIcon={<CloseOutlined />}` |
42
+ | `Divider` | `import { Divider } from "forest-ui"` | `orientation: "horizontal" \| "vertical"`, `variant: "fullWidth" \| "inset" \| "middle"`, `textAlign`, `flexItem` | — |
43
+ | `Typography` | `import { Typography } from "forest-ui"` | `variant: "h1"-"h6" \| "subtitle1" \| "subtitle2" \| "body1" \| "body2" \| "caption" \| "overline" \| "button"`, `align`, `gutterBottom`, `noWrap` | — |
44
+ | `Tooltip` | `import { Tooltip } from "forest-ui"` | `title` (required), `placement` (12 positions), `arrow`, `followCursor`, `enterDelay`, `leaveDelay` | `arrow={true}` |
45
+ | `Table` family | `import { Table, TableHead, TableBody, TableRow, TableCell, TableContainer } from "forest-ui"` | Table: `size: "small" \| "medium"`, `stickyHeader`; TableCell: `align`, `padding`, `sortDirection`, `variant`; TableRow: `hover`, `selected` | — |
46
+ | `DataGrid` | `import { DataGrid, type GridColDef } from "forest-ui"` | `rows`, `columns`, `paginationModel`, `sortModel`, `filterModel`, `checkboxSelection`, `loading`, `density` | — |
47
+ | `List` family | `import { List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListItemAvatar, ListSubheader } from "forest-ui"` | `dense`, `disablePadding`; ListItemButton: `selected`, `disabled`; ListItemText: `primary`, `secondary` | — |
48
+
49
+ ## Surfaces
50
+
51
+ | Component | Import | Variants / Key Props | Default Props |
52
+ |-----------|--------|----------------------|---------------|
53
+ | `Accordion` family | `import { Accordion, AccordionSummary, AccordionDetails, AccordionActions } from "forest-ui"` | `expanded`, `defaultExpanded`, `onChange`, `disabled`, `disableGutters`, `square` | — |
54
+ | `AppBar` + `Toolbar` | `import { AppBar, Toolbar } from "forest-ui"` | `position`, `color`, `elevation`; Toolbar: `variant: "dense" \| "regular"` | — |
55
+ | `Card` family | `import { Card, CardContent, CardHeader, CardActions, CardMedia } from "forest-ui"` | `variant: "elevation" \| "outlined"`, `elevation`, `raised`; CardHeader: `title`, `subheader`, `avatar`, `action` | — |
56
+ | `Paper` | `import { Paper } from "forest-ui"` | `variant: "elevation" \| "outlined"`, `elevation` (0-24), `square` | — |
57
+
58
+ ## Feedback
59
+
60
+ | Component | Import | Variants / Key Props | Default Props |
61
+ |-----------|--------|----------------------|---------------|
62
+ | `Alert` + `AlertTitle` | `import { Alert, AlertTitle } from "forest-ui"` | `severity: "success" \| "info" \| "warning" \| "error"`, `variant: "filled" \| "outlined" \| "standard"`, `color`, `icon`, `action`, `onClose` | — |
63
+ | `Dialog` family | `import { Dialog, DialogTitle, DialogContent, DialogActions, DialogContentText } from "forest-ui"` | `open` (required), `onClose`, `fullWidth`, `maxWidth`, `fullScreen`, `scroll: "paper" \| "body"` | — |
64
+ | `Backdrop` | `import { Backdrop } from "forest-ui"` | `open` (required), `invisible`, `onClick` | — |
65
+ | `LinearProgress` | `import { LinearProgress } from "forest-ui"` | `variant: "indeterminate" \| "determinate" \| "buffer" \| "query"`, `value` (0-100), `color` | — |
66
+ | `CircularProgress` | `import { CircularProgress } from "forest-ui"` | `variant: "indeterminate" \| "determinate"`, `value` (0-100), `color`, `size`, `thickness` | — |
67
+ | `Skeleton` | `import { Skeleton } from "forest-ui"` | `variant: "text" \| "circular" \| "rectangular" \| "rounded"`, `animation: "pulse" \| "wave" \| false`, `width`, `height` | — |
68
+ | `Modal` | `import { Modal } from "forest-ui"` | `open` (required), `onClose`, `children`, `keepMounted`, `disableAutoFocus`, `disableEscapeKeyDown` | — |
69
+ | `Popover` | `import { Popover } from "forest-ui"` | `open` (required), `anchorEl`, `onClose`, `anchorOrigin`, `transformOrigin`, `elevation` | — |
70
+ | `Snackbar` | `import { Snackbar } from "forest-ui"` | `open`, `message`, `autoHideDuration`, `onClose`, `action`, `anchorOrigin` | — |
71
+
72
+ ## Navigation
73
+
74
+ | Component | Import | Variants / Key Props | Default Props |
75
+ |-----------|--------|----------------------|---------------|
76
+ | `Breadcrumbs` | `import { Breadcrumbs } from "forest-ui"` | `separator`, `maxItems`, `itemsAfterCollapse`, `itemsBeforeCollapse` | — |
77
+ | `Link` | `import { Link } from "forest-ui"` | `href`, `underline: "none" \| "hover" \| "always"`, `color`, `variant` | — |
78
+ | `Menu` + `MenuList` | `import { Menu, MenuList } from "forest-ui"` | Menu: `open` (required), `anchorEl`, `onClose`; use with `MenuItem` | — |
79
+ | `Pagination` | `import { Pagination } from "forest-ui"` | `count`, `page`, `onChange`, `variant: "text" \| "outlined"`, `shape`, `size`, `color`, `showFirstButton`, `showLastButton` | — |
80
+ | `Stepper` family | `import { Stepper, Step, StepLabel } from "forest-ui"` | `activeStep`, `orientation`, `alternativeLabel`, `nonLinear`; Step: `completed`, `disabled`; StepLabel: `optional`, `error` | — |
81
+ | `Tabs` + `Tab` | `import { Tabs, Tab } from "forest-ui"` | Tabs: `value`, `onChange`, `variant: "standard" \| "scrollable" \| "fullWidth"`, `orientation`, `centered`; Tab: `label`, `icon`, `iconPosition`, `disabled`, `value` | — |
82
+ | `SidebarNav` | `import { SidebarNav, SidebarItem, useSidebar } from "forest-ui"` | `open`, `onOpenChange`, `behavior: "permanent" \| "hover"`, `expandedWidth`, `collapsedWidth`, `showToggle`, `header`, `footer` | `expandedWidth=240`, `collapsedWidth=48`, `behavior="permanent"` |
83
+ | `SidebarItem` | (same import) | `icon` (required), `label` (required), `endAdornment`, `selected`, `onClick`, `disabled` | — |
84
+
85
+ ## Charts
86
+
87
+ Requires `@mui/x-charts` peer dependency. Chart colors are automatically applied from the theme's 12-color series palette.
88
+
89
+ | Component | Import | Variants / Key Props | Default Props |
90
+ |-----------|--------|----------------------|---------------|
91
+ | `BarChart` | `import { BarChart } from "forest-ui"` | `series` (supports `variant: "solid" \| "striped"` per series), `colors`, `xAxis`, `yAxis`, `width`, `height` | `grid horizontal`, `borderRadius=4`, highlight/fade on hover |
92
+ | `LineChart` | `import { LineChart } from "forest-ui"` | `series`, `colors`, `xAxis`, `yAxis`, `width`, `height` | `curve="linear"`, `strokeWidth=3`, `grid horizontal`, highlight/fade on hover |
93
+ | `PieChart` | `import { PieChart } from "forest-ui"` | `series` (data: `{ id, value, label, color? }[]`), `colors`, `width`, `height` | highlight/fade on hover |
94
+ | `useChartColors` | `import { useChartColors } from "forest-ui"` | `useChartColors(count)` — returns `string[]` of theme chart series colors (max 12) | — |
@@ -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
+ ```
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: forest-internal
3
+ description: Forest UI Design System rules for the Internal (magenta) preset. Enforces correct imports, component usage, and theming with @matteoaliano/forest-ui. Use when the project uses forest-ui, forest-internal preset, or when user builds UI components in a forest-ui project. Triggers on "forest", "forest-ui", "forest internal", "@matteoaliano/forest-ui".
4
+ metadata:
5
+ author: Forest Design System
6
+ version: 0.3.5
7
+ ---
8
+
9
+ # Forest UI — Internal Preset
10
+
11
+ ## Golden Rules
12
+
13
+ 1. **NEVER import from `@mui/material` directly.** Always import from `@matteoaliano/forest-ui`. Exception: layout primitives (`Box`, `Stack`, `Grid`, `Container`) come from `@mui/material`.
14
+ 2. **ALWAYS wrap your app root with `<ForestProvider>`** — it applies the theme and CSS baseline.
15
+ 3. **NEVER use inline colors or spacing values.** Use design tokens or MUI's `sx` prop with theme values (`p: 4`, `backgroundColor: "primary.main"`).
16
+ 4. **NEVER create custom component wrappers** for things Forest UI already provides.
17
+ 5. **TypeScript is required.** All components export their prop types (e.g. `type ButtonProps`).
18
+ 6. **ALWAYS use the Outlined variant of MUI icons.** Import from `@mui/icons-material/*Outlined` (e.g. `CloseOutlined`, `MailOutlined`). Never use filled, Rounded, Sharp, or TwoTone variants.
19
+
20
+ ## Setup
21
+
22
+ ```bash
23
+ npm install @matteoaliano/forest-ui @mui/material @mui/x-data-grid @mui/x-date-pickers @mui/x-charts dayjs @emotion/react @emotion/styled
24
+ ```
25
+
26
+ ```tsx
27
+ import { ForestProvider } from "@matteoaliano/forest-ui";
28
+
29
+ function App() {
30
+ return (
31
+ <ForestProvider preset="forest-internal">
32
+ {/* All app content here */}
33
+ </ForestProvider>
34
+ );
35
+ }
36
+ ```
37
+
38
+ ## Preset Identity
39
+
40
+ **Atmosphere:** Playful, energetic, and unapologetically expressive — vibrant yet functional.
41
+
42
+ | Role | Color | Hex |
43
+ |------|-------|-----|
44
+ | Primary (brand) | Hot Magenta | `#FF78F3` |
45
+ | Primary hover | Vivid Fuchsia | `#e650d4` |
46
+ | Brand depth | Deep Orchid | `#cc28b5` |
47
+ | Brand tint | Blush Mist | `#fff0fa` |
48
+ | Background | Warm Parchment | `#faf9f8` |
49
+ | Surface | Pure White | `#ffffff` |
50
+ | Text primary | Near-Black Ink | `#18181b` |
51
+ | Text secondary | Steel Gray | `#3f3f46` |
52
+ | Border primary | Silver Mist | `#d8d8dc` |
53
+ | Border brand | Pink Frost | `#ff90d8` |
54
+ | Success | Verdant | `#079455` |
55
+ | Warning | Amber | `#dc6803` |
56
+ | Error | Coral | `#d92d20` |
57
+ | Info | Sky | `#1570ef` |
58
+
59
+ **Corner radius:** Sharp and geometric (4px for buttons/inputs, up to 12px for cards/modals).
60
+ **Font:** Aeonik (geometric sans-serif). Consumers must load it.
61
+ **Button height:** Compact 32px.
62
+
63
+ ## Available Components
64
+
65
+ **Inputs:** Button, ButtonGroup, TextField, Select + MenuItem, MultiSelect, Checkbox, RadioGroup + Radio, Switch, ToggleButton + ToggleButtonGroup, Fab, IconButton, Autocomplete, Search, DatePicker
66
+
67
+ **Data Display:** Badge, Chip, Divider, Typography, Tooltip, Table family (Table, TableHead, TableBody, TableRow, TableCell, TableContainer), DataGrid + GridColDef, List family
68
+
69
+ **Surfaces:** Accordion family, AppBar + Toolbar, Card family, Paper
70
+
71
+ **Feedback:** Alert + AlertTitle, Dialog family, Backdrop, LinearProgress, CircularProgress, Skeleton, Modal, Popover, Snackbar
72
+
73
+ **Navigation:** Breadcrumbs, Link, Menu + MenuList, Pagination, Stepper family, Tabs + Tab, SidebarNav + SidebarItem + useSidebar
74
+
75
+ **Charts:** BarChart, LineChart, PieChart, useChartColors
76
+
77
+ See `references/components.md` for full API details and `references/patterns.md` for code examples.
78
+
79
+ ## Common Anti-Patterns
80
+
81
+ 1. **Importing from `@mui/material`** instead of `@matteoaliano/forest-ui`
82
+ 2. **Hardcoded color values** (`backgroundColor: "#7f56d9"`) instead of theme tokens (`backgroundColor: "primary.main"`)
83
+ 3. **Hardcoded spacing** (`padding: "16px"`) instead of theme spacing (`p: 4`)
84
+ 4. **Missing `<ForestProvider>`** at the app root — theme won't apply
85
+ 5. **Using filled MUI icons** (`Close`) instead of Outlined (`CloseOutlined`)
86
+ 6. **Building custom multi-select** instead of using the `<MultiSelect>` component
@@ -0,0 +1,94 @@
1
+ # Forest UI — Component Reference
2
+
3
+ > Full API reference for all components exported by `@matteoaliano/forest-ui`.
4
+
5
+ ## Import Pattern
6
+
7
+ ```tsx
8
+ // CORRECT — import from forest-ui
9
+ import { Button, TextField, Alert } from "@matteoaliano/forest-ui";
10
+
11
+ // WRONG — never import from @mui/material
12
+ import Button from "@mui/material/Button";
13
+ ```
14
+
15
+ > Layout primitives (`Box`, `Stack`, `Grid`, `Container`) are NOT re-exported. Import those directly from `@mui/material`.
16
+
17
+ ## Inputs
18
+
19
+ | Component | Import | Variants / Key Props | Default Props |
20
+ |-----------|--------|----------------------|---------------|
21
+ | `Button` | `import { Button } from "forest-ui"` | `variant: "contained" \| "outlined" \| "text"`, `color`, `disabled`, `startIcon`, `endIcon`, `loading`, `fullWidth`, `href` | `variant="contained"`, `size` prop removed |
22
+ | `ButtonGroup` | `import { ButtonGroup } from "forest-ui"` | `variant: "contained" \| "outlined" \| "text"`, `size: "small" \| "medium" \| "large"`, `orientation: "horizontal" \| "vertical"`, `color`, `disabled`, `fullWidth` | `variant="contained"` |
23
+ | `TextField` | `import { TextField } from "forest-ui"` | `variant: "outlined" \| "filled" \| "standard"`, `size: "small" \| "medium"`, `label`, `error`, `helperText`, `fullWidth`, `multiline`, `rows`, `type`, `placeholder`, `required`, `disabled` | — |
24
+ | `Select` + `MenuItem` | `import { Select, MenuItem } from "forest-ui"` | `variant: "outlined" \| "filled" \| "standard"`, `size: "small" \| "medium"`, `multiple`, `displayEmpty`, `label`, `labelId`, `renderValue`, `native`, `error`, `disabled` | — |
25
+ | `MultiSelect` | `import { MultiSelect } from "forest-ui"` | `options: { label, value }[]`, `value: string[]`, `onChange: (values) => void`, `selectAll: boolean`, `selectAllLabel: string`, `label` + all SelectProps | `selectAll={true}`, `selectAllLabel="Select All"` |
26
+ | `Checkbox` | `import { Checkbox } from "forest-ui"` | `color: "default" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning"`, `size: "small" \| "medium"`, `checked`, `indeterminate`, `disabled` | — |
27
+ | `RadioGroup` + `Radio` | `import { RadioGroup, Radio } from "forest-ui"` | `row`, `value`, `onChange`; Radio: `color`, `size: "small" \| "medium" \| "large"`, `disabled` | — |
28
+ | `Switch` | `import { Switch } from "forest-ui"` | `color: "default" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning"`, `size: "small" \| "medium"`, `checked`, `disabled` | — |
29
+ | `ToggleButton` + `ToggleButtonGroup` | `import { ToggleButton, ToggleButtonGroup } from "forest-ui"` | `value`, `exclusive`, `onChange`, `orientation: "horizontal" \| "vertical"`, `size: "small" \| "medium" \| "large"`, `color`, `fullWidth` | — |
30
+ | `Fab` | `import { Fab } from "forest-ui"` | `variant: "circular" \| "extended"`, `size: "small" \| "medium" \| "large"`, `color`, `disabled`, `href` | `color="primary"` |
31
+ | `IconButton` | `import { IconButton } from "forest-ui"` | `color: "inherit" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning" \| "default"`, `size: "small" \| "medium" \| "large"`, `disabled`, `disableRipple` | — |
32
+ | `Autocomplete` | `import { Autocomplete } from "forest-ui"` | `options`, `renderInput` (required), `multiple`, `freeSolo`, `disableClearable`, `loading`, `groupBy`, `limitTags`, `filterOptions` | — |
33
+ | `Search` | `import { Search } from "forest-ui"` | `onClear`, `placeholder`, all TextField props (except `variant`) | `variant="outlined"`, `placeholder="Search..."`, built-in search icon and clear button |
34
+ | `DatePicker` | `import { DatePicker } from "forest-ui"` | All MUI X DatePicker props (`value`, `onChange`, `label`, `format`, `minDate`, `maxDate`, `disabled`, `readOnly`) | Wraps with `LocalizationProvider` + `AdapterDayjs` automatically |
35
+
36
+ ## Data Display
37
+
38
+ | Component | Import | Variants / Key Props | Default Props |
39
+ |-----------|--------|----------------------|---------------|
40
+ | `Badge` | `import { Badge } from "forest-ui"` | `variant: "standard" \| "dot"`, `color`, `badgeContent`, `max`, `invisible`, `showZero`, `overlap: "rectangular" \| "circular"`, `anchorOrigin` | — |
41
+ | `Chip` | `import { Chip } from "forest-ui"` | `variant: "filled" \| "outlined"`, `color`, `size: "small" \| "medium"`, `label`, `onDelete`, `clickable`, `avatar`, `icon` | `deleteIcon={<CloseOutlined />}` |
42
+ | `Divider` | `import { Divider } from "forest-ui"` | `orientation: "horizontal" \| "vertical"`, `variant: "fullWidth" \| "inset" \| "middle"`, `textAlign`, `flexItem` | — |
43
+ | `Typography` | `import { Typography } from "forest-ui"` | `variant: "h1"-"h6" \| "subtitle1" \| "subtitle2" \| "body1" \| "body2" \| "caption" \| "overline" \| "button"`, `align`, `gutterBottom`, `noWrap` | — |
44
+ | `Tooltip` | `import { Tooltip } from "forest-ui"` | `title` (required), `placement` (12 positions), `arrow`, `followCursor`, `enterDelay`, `leaveDelay` | `arrow={true}` |
45
+ | `Table` family | `import { Table, TableHead, TableBody, TableRow, TableCell, TableContainer } from "forest-ui"` | Table: `size: "small" \| "medium"`, `stickyHeader`; TableCell: `align`, `padding`, `sortDirection`, `variant`; TableRow: `hover`, `selected` | — |
46
+ | `DataGrid` | `import { DataGrid, type GridColDef } from "forest-ui"` | `rows`, `columns`, `paginationModel`, `sortModel`, `filterModel`, `checkboxSelection`, `loading`, `density` | — |
47
+ | `List` family | `import { List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListItemAvatar, ListSubheader } from "forest-ui"` | `dense`, `disablePadding`; ListItemButton: `selected`, `disabled`; ListItemText: `primary`, `secondary` | — |
48
+
49
+ ## Surfaces
50
+
51
+ | Component | Import | Variants / Key Props | Default Props |
52
+ |-----------|--------|----------------------|---------------|
53
+ | `Accordion` family | `import { Accordion, AccordionSummary, AccordionDetails, AccordionActions } from "forest-ui"` | `expanded`, `defaultExpanded`, `onChange`, `disabled`, `disableGutters`, `square` | — |
54
+ | `AppBar` + `Toolbar` | `import { AppBar, Toolbar } from "forest-ui"` | `position`, `color`, `elevation`; Toolbar: `variant: "dense" \| "regular"` | — |
55
+ | `Card` family | `import { Card, CardContent, CardHeader, CardActions, CardMedia } from "forest-ui"` | `variant: "elevation" \| "outlined"`, `elevation`, `raised`; CardHeader: `title`, `subheader`, `avatar`, `action` | — |
56
+ | `Paper` | `import { Paper } from "forest-ui"` | `variant: "elevation" \| "outlined"`, `elevation` (0-24), `square` | — |
57
+
58
+ ## Feedback
59
+
60
+ | Component | Import | Variants / Key Props | Default Props |
61
+ |-----------|--------|----------------------|---------------|
62
+ | `Alert` + `AlertTitle` | `import { Alert, AlertTitle } from "forest-ui"` | `severity: "success" \| "info" \| "warning" \| "error"`, `variant: "filled" \| "outlined" \| "standard"`, `color`, `icon`, `action`, `onClose` | — |
63
+ | `Dialog` family | `import { Dialog, DialogTitle, DialogContent, DialogActions, DialogContentText } from "forest-ui"` | `open` (required), `onClose`, `fullWidth`, `maxWidth`, `fullScreen`, `scroll: "paper" \| "body"` | — |
64
+ | `Backdrop` | `import { Backdrop } from "forest-ui"` | `open` (required), `invisible`, `onClick` | — |
65
+ | `LinearProgress` | `import { LinearProgress } from "forest-ui"` | `variant: "indeterminate" \| "determinate" \| "buffer" \| "query"`, `value` (0-100), `color` | — |
66
+ | `CircularProgress` | `import { CircularProgress } from "forest-ui"` | `variant: "indeterminate" \| "determinate"`, `value` (0-100), `color`, `size`, `thickness` | — |
67
+ | `Skeleton` | `import { Skeleton } from "forest-ui"` | `variant: "text" \| "circular" \| "rectangular" \| "rounded"`, `animation: "pulse" \| "wave" \| false`, `width`, `height` | — |
68
+ | `Modal` | `import { Modal } from "forest-ui"` | `open` (required), `onClose`, `children`, `keepMounted`, `disableAutoFocus`, `disableEscapeKeyDown` | — |
69
+ | `Popover` | `import { Popover } from "forest-ui"` | `open` (required), `anchorEl`, `onClose`, `anchorOrigin`, `transformOrigin`, `elevation` | — |
70
+ | `Snackbar` | `import { Snackbar } from "forest-ui"` | `open`, `message`, `autoHideDuration`, `onClose`, `action`, `anchorOrigin` | — |
71
+
72
+ ## Navigation
73
+
74
+ | Component | Import | Variants / Key Props | Default Props |
75
+ |-----------|--------|----------------------|---------------|
76
+ | `Breadcrumbs` | `import { Breadcrumbs } from "forest-ui"` | `separator`, `maxItems`, `itemsAfterCollapse`, `itemsBeforeCollapse` | — |
77
+ | `Link` | `import { Link } from "forest-ui"` | `href`, `underline: "none" \| "hover" \| "always"`, `color`, `variant` | — |
78
+ | `Menu` + `MenuList` | `import { Menu, MenuList } from "forest-ui"` | Menu: `open` (required), `anchorEl`, `onClose`; use with `MenuItem` | — |
79
+ | `Pagination` | `import { Pagination } from "forest-ui"` | `count`, `page`, `onChange`, `variant: "text" \| "outlined"`, `shape`, `size`, `color`, `showFirstButton`, `showLastButton` | — |
80
+ | `Stepper` family | `import { Stepper, Step, StepLabel } from "forest-ui"` | `activeStep`, `orientation`, `alternativeLabel`, `nonLinear`; Step: `completed`, `disabled`; StepLabel: `optional`, `error` | — |
81
+ | `Tabs` + `Tab` | `import { Tabs, Tab } from "forest-ui"` | Tabs: `value`, `onChange`, `variant: "standard" \| "scrollable" \| "fullWidth"`, `orientation`, `centered`; Tab: `label`, `icon`, `iconPosition`, `disabled`, `value` | — |
82
+ | `SidebarNav` | `import { SidebarNav, SidebarItem, useSidebar } from "forest-ui"` | `open`, `onOpenChange`, `behavior: "permanent" \| "hover"`, `expandedWidth`, `collapsedWidth`, `showToggle`, `header`, `footer` | `expandedWidth=240`, `collapsedWidth=48`, `behavior="permanent"` |
83
+ | `SidebarItem` | (same import) | `icon` (required), `label` (required), `endAdornment`, `selected`, `onClick`, `disabled` | — |
84
+
85
+ ## Charts
86
+
87
+ Requires `@mui/x-charts` peer dependency. Chart colors are automatically applied from the theme's 12-color series palette.
88
+
89
+ | Component | Import | Variants / Key Props | Default Props |
90
+ |-----------|--------|----------------------|---------------|
91
+ | `BarChart` | `import { BarChart } from "forest-ui"` | `series` (supports `variant: "solid" \| "striped"` per series), `colors`, `xAxis`, `yAxis`, `width`, `height` | `grid horizontal`, `borderRadius=4`, highlight/fade on hover |
92
+ | `LineChart` | `import { LineChart } from "forest-ui"` | `series`, `colors`, `xAxis`, `yAxis`, `width`, `height` | `curve="linear"`, `strokeWidth=3`, `grid horizontal`, highlight/fade on hover |
93
+ | `PieChart` | `import { PieChart } from "forest-ui"` | `series` (data: `{ id, value, label, color? }[]`), `colors`, `width`, `height` | highlight/fade on hover |
94
+ | `useChartColors` | `import { useChartColors } from "forest-ui"` | `useChartColors(count)` — returns `string[]` of theme chart series colors (max 12) | — |