@matteoaliano/forest-ui 0.4.3 → 0.5.0

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.
@@ -3,14 +3,14 @@ name: forest-external
3
3
  description: Forest UI Design System rules for the External (violet) preset. Enforces correct imports, component usage, and theming with @matteoaliano/forest-ui. Use when the project uses forest-ui, forest-external preset, or when user builds UI components in a forest-ui project. Triggers on "forest", "forest-ui", "forest external", "@matteoaliano/forest-ui".
4
4
  metadata:
5
5
  author: Forest Design System
6
- version: 0.4.3
6
+ version: 0.5.0
7
7
  ---
8
8
 
9
9
  # Forest UI — External Preset
10
10
 
11
11
  ## Golden Rules
12
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`.
13
+ 1. **NEVER import from `@mui/material` directly.** Always import from `@matteoaliano/forest-ui`. All MUI components, layout primitives, transitions, form helpers, and hooks are re-exported. The only exception is `@mui/icons-material` — import icons from there directly.
14
14
  2. **ALWAYS wrap your app root with `<ForestProvider>`** — it applies the theme and CSS baseline.
15
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
16
  4. **NEVER create custom component wrappers** for things Forest UI already provides.
@@ -23,6 +23,8 @@ metadata:
23
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
24
  ```
25
25
 
26
+ > **Note:** `@mui/material`, `@mui/x-data-grid`, `@mui/x-date-pickers`, and `@mui/x-charts` are **peer dependencies** — install them but **always import from `@matteoaliano/forest-ui`**, not from these packages directly. Forest UI re-exports everything.
27
+
26
28
  ```tsx
27
29
  import { ForestProvider } from "@matteoaliano/forest-ui";
28
30
 
@@ -39,30 +41,39 @@ function App() {
39
41
 
40
42
  - **Aeonik** — the default font for all UI text (headings, body, labels, buttons, etc.)
41
43
  - **Aeonik Mono** — use for numeric values: prices, stats, table figures, counters, dates, IDs, code snippets
42
- - **Alkemy Beta** — reserved exclusively for branding elements (e.g. Logo component). Never use for general UI text
44
+ - **Alkemy Beta** — use for page titles (h1/hero headings). Not for general UI text
43
45
 
44
46
  Import the font CSS files you need in your app entry point:
45
47
 
46
48
  ```tsx
47
49
  import "@matteoaliano/forest-ui/fonts/aeonik/aeonik.css";
48
50
  import "@matteoaliano/forest-ui/fonts/aeonik-mono/aeonik-mono.css";
49
- // Only if using branding/logo elements:
50
51
  import "@matteoaliano/forest-ui/fonts/alkemy-beta/alkemy-beta.css";
51
52
  ```
52
53
 
53
54
  ## Available Components
54
55
 
55
- **Inputs:** Button, ButtonGroup, TextField, Select + MenuItem, MultiSelect, Checkbox, RadioGroup + Radio, Switch, ToggleButton + ToggleButtonGroup, Fab, IconButton, Autocomplete, Search, DatePicker
56
+ **Inputs:** Button, ButtonGroup, TextField, Select + MenuItem, MultiSelect, Checkbox, RadioGroup + Radio, Switch, ToggleButton + ToggleButtonGroup, Fab, IconButton, Autocomplete, Search, DatePicker, Input
57
+
58
+ **Data Display:** Badge, Chip, Divider, Typography, Tooltip, Logo, Table family (Table, TableHead, TableBody, TableRow, TableCell, TableContainer, TableFooter, TablePagination, TableSortLabel), DataGrid + GridColDef, List family (List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListItemAvatar, ListItemSecondaryAction, ListSubheader), Avatar + AvatarGroup, ImageList + ImageListItem + ImageListItemBar, Rating
59
+
60
+ **Surfaces:** Accordion family, AppBar + Toolbar + AppBarNavItem, Card family + CardActionArea, Paper, Drawer + SwipeableDrawer
61
+
62
+ **Feedback:** Alert + AlertTitle, Dialog family, Backdrop, LinearProgress, CircularProgress, Skeleton, Modal, Popover, Snackbar + SnackbarContent, Slider
63
+
64
+ **Navigation:** Breadcrumbs, Link, Menu + MenuList, Pagination + PaginationItem, Stepper family (Stepper, Step, StepLabel, StepButton, StepConnector, StepContent, StepIcon), Tabs + Tab + TabScrollButton, SidebarNav + SidebarItem + useSidebar, BottomNavigation + BottomNavigationAction, SpeedDial + SpeedDialAction + SpeedDialIcon, MobileStepper
65
+
66
+ **Layout:** Box, Stack, Grid, Container
56
67
 
57
- **Data Display:** Badge, Chip, Divider, Typography, Tooltip, Table family (Table, TableHead, TableBody, TableRow, TableCell, TableContainer), DataGrid + GridColDef, List family
68
+ **Form Helpers:** FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel, InputAdornment, InputBase, InputLabel, OutlinedInput, FilledInput
58
69
 
59
- **Surfaces:** Accordion family, AppBar + Toolbar, Card family, Paper
70
+ **Transitions:** Collapse, Fade, Grow, Slide, Zoom
60
71
 
61
- **Feedback:** Alert + AlertTitle, Dialog family, Backdrop, LinearProgress, CircularProgress, Skeleton, Modal, Popover, Snackbar
72
+ **Utilities:** ClickAwayListener, NoSsr, Portal, Popper, TextareaAutosize, SvgIcon, ButtonBase, GlobalStyles
62
73
 
63
- **Navigation:** Breadcrumbs, Link, Menu + MenuList, Pagination, Stepper family, Tabs + Tab, SidebarNav + SidebarItem + useSidebar
74
+ **Hooks:** useMediaQuery, useScrollTrigger, useFormControl, useTheme
64
75
 
65
- **Charts:** BarChart, LineChart, PieChart, useChartColors
76
+ **Charts:** BarChart, LineChart, PieChart, ScatterChart, Gauge, SparkLineChart, useChartColors, plus composition primitives (see components.md)
66
77
 
67
78
  See `references/components.md` for full API details and `references/patterns.md` for code examples.
68
79
 
@@ -75,7 +86,7 @@ See `references/components.md` for full API details and `references/patterns.md`
75
86
 
76
87
  ## Common Anti-Patterns
77
88
 
78
- 1. **Importing from `@mui/material`** instead of `@matteoaliano/forest-ui`
89
+ 1. **Importing from `@mui/material`** instead of `@matteoaliano/forest-ui` — all components, hooks, and layout primitives are available from forest-ui
79
90
  2. **Hardcoded color values** (`backgroundColor: "#7f56d9"`) instead of theme tokens (`backgroundColor: "primary.main"`)
80
91
  3. **Hardcoded spacing** (`padding: "16px"`) instead of theme spacing (`p: 4`)
81
92
  4. **Missing `<ForestProvider>`** at the app root — theme won't apply
@@ -12,83 +12,191 @@ import { Button, TextField, Alert } from "@matteoaliano/forest-ui";
12
12
  import Button from "@mui/material/Button";
13
13
  ```
14
14
 
15
- > Layout primitives (`Box`, `Stack`, `Grid`, `Container`) are NOT re-exported. Import those directly from `@mui/material`.
15
+ > **All MUI components are re-exported.** Never import from `@mui/material` always use `@matteoaliano/forest-ui`. The only exception is `@mui/icons-material` for icons.
16
+
17
+ ## Layout
18
+
19
+ | Component | Import | Key Props |
20
+ |-----------|--------|-----------|
21
+ | `Box` | `import { Box } from "@matteoaliano/forest-ui"` | `sx`, `component`, all HTML attributes |
22
+ | `Stack` | `import { Stack } from "@matteoaliano/forest-ui"` | `direction`, `spacing`, `divider`, `alignItems`, `justifyContent` |
23
+ | `Grid` | `import { Grid } from "@matteoaliano/forest-ui"` | `container`, `size`, `spacing`, `offset`, `columns`, `direction` |
24
+ | `Container` | `import { Container } from "@matteoaliano/forest-ui"` | `maxWidth: "xs" \| "sm" \| "md" \| "lg" \| "xl" \| false`, `fixed`, `disableGutters` |
25
+
26
+ ## Form Helpers
27
+
28
+ | Component | Import | Key Props |
29
+ |-----------|--------|-----------|
30
+ | `FormControl` | `import { FormControl } from "@matteoaliano/forest-ui"` | `variant`, `fullWidth`, `error`, `disabled`, `required`, `size` |
31
+ | `FormControlLabel` | `import { FormControlLabel } from "@matteoaliano/forest-ui"` | `control` (required), `label`, `labelPlacement`, `disabled` |
32
+ | `FormGroup` | `import { FormGroup } from "@matteoaliano/forest-ui"` | `row`, `children` |
33
+ | `FormHelperText` | `import { FormHelperText } from "@matteoaliano/forest-ui"` | `error`, `disabled`, `margin` |
34
+ | `FormLabel` | `import { FormLabel } from "@matteoaliano/forest-ui"` | `error`, `focused`, `required`, `disabled`, `color` |
35
+ | `InputAdornment` | `import { InputAdornment } from "@matteoaliano/forest-ui"` | `position: "start" \| "end"`, `variant`, `disablePointerEvents` |
36
+ | `InputBase` | `import { InputBase } from "@matteoaliano/forest-ui"` | `value`, `onChange`, `placeholder`, `multiline`, `rows`, `startAdornment`, `endAdornment` |
37
+ | `InputLabel` | `import { InputLabel } from "@matteoaliano/forest-ui"` | `shrink`, `variant`, `error`, `required`, `disabled` |
38
+ | `OutlinedInput` | `import { OutlinedInput } from "@matteoaliano/forest-ui"` | `label`, `notched`, all InputBase props |
39
+ | `FilledInput` | `import { FilledInput } from "@matteoaliano/forest-ui"` | All InputBase props |
16
40
 
17
41
  ## Inputs
18
42
 
19
43
  | Component | Import | Variants / Key Props | Default Props |
20
44
  |-----------|--------|----------------------|---------------|
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 |
45
+ | `Button` | `import { Button } from "@matteoaliano/forest-ui"` | `variant: "contained" \| "outlined" \| "text"`, `color`, `size: "small" \| "medium" \| "large"`, `disabled`, `startIcon`, `endIcon`, `fullWidth`, `href` | `variant="contained"` |
46
+ | `ButtonGroup` | `import { ButtonGroup } from "@matteoaliano/forest-ui"` | `variant: "contained" \| "outlined" \| "text"`, `size: "small" \| "medium" \| "large"`, `orientation: "horizontal" \| "vertical"`, `color`, `disabled`, `fullWidth` | `variant="contained"` |
47
+ | `TextField` | `import { TextField } from "@matteoaliano/forest-ui"` | `variant: "outlined" \| "filled" \| "standard"`, `size: "small" \| "medium"`, `label`, `error`, `helperText`, `fullWidth`, `multiline`, `rows`, `type`, `placeholder`, `required`, `disabled` | — |
48
+ | `Select` + `MenuItem` | `import { Select, MenuItem } from "@matteoaliano/forest-ui"` | `variant: "outlined" \| "filled" \| "standard"`, `size: "small" \| "medium"`, `multiple`, `displayEmpty`, `label`, `labelId`, `renderValue`, `native`, `error`, `disabled` | — |
49
+ | `MultiSelect` | `import { MultiSelect } from "@matteoaliano/forest-ui"` | `options: { label, value }[]`, `value: string[]`, `onChange: (values) => void`, `selectAll: boolean`, `selectAllLabel: string`, `label` + all SelectProps | `selectAll={true}`, `selectAllLabel="Select All"` |
50
+ | `Checkbox` | `import { Checkbox } from "@matteoaliano/forest-ui"` | `color: "default" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning"`, `size: "small" \| "medium"`, `checked`, `indeterminate`, `disabled` | — |
51
+ | `RadioGroup` + `Radio` | `import { RadioGroup, Radio } from "@matteoaliano/forest-ui"` | `row`, `value`, `onChange`; Radio: `color`, `size: "small" \| "medium" \| "large"`, `disabled` | — |
52
+ | `Switch` | `import { Switch } from "@matteoaliano/forest-ui"` | `color: "default" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning"`, `size: "small" \| "medium"`, `checked`, `disabled` | — |
53
+ | `ToggleButton` + `ToggleButtonGroup` | `import { ToggleButton, ToggleButtonGroup } from "@matteoaliano/forest-ui"` | `value`, `exclusive`, `onChange`, `orientation: "horizontal" \| "vertical"`, `size: "small" \| "medium" \| "large"`, `color`, `fullWidth` | — |
54
+ | `Fab` | `import { Fab } from "@matteoaliano/forest-ui"` | `variant: "circular" \| "extended"`, `size: "small" \| "medium" \| "large"`, `color`, `disabled`, `href` | `color="primary"` |
55
+ | `IconButton` | `import { IconButton } from "@matteoaliano/forest-ui"` | `color: "inherit" \| "primary" \| "secondary" \| "error" \| "info" \| "success" \| "warning" \| "default"`, `size: "small" \| "medium" \| "large"`, `disabled`, `disableRipple` | — |
56
+ | `Autocomplete` | `import { Autocomplete } from "@matteoaliano/forest-ui"` | `options`, `renderInput` (required), `multiple`, `freeSolo`, `disableClearable`, `loading`, `groupBy`, `limitTags`, `filterOptions` | — |
57
+ | `Search` | `import { Search } from "@matteoaliano/forest-ui"` | `onClear`, `placeholder`, all TextField props (except `variant`) | `variant="outlined"`, `placeholder="Search..."`, built-in search icon and clear button |
58
+ | `Input` | `import { Input } from "@matteoaliano/forest-ui"` | `value`, `onChange`, `placeholder`, `multiline`, `rows`, `startAdornment`, `endAdornment`, `disabled`, `error` all InputBase props | |
59
+ | `DatePicker` | `import { DatePicker } from "@matteoaliano/forest-ui"` | All MUI X DatePicker props (`value`, `onChange`, `label`, `format`, `minDate`, `maxDate`, `disabled`, `readOnly`) | Wraps with `LocalizationProvider` + `AdapterDayjs` automatically |
35
60
 
36
61
  ## Data Display
37
62
 
38
63
  | Component | Import | Variants / Key Props | Default Props |
39
64
  |-----------|--------|----------------------|---------------|
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` | — |
65
+ | `Badge` | `import { Badge } from "@matteoaliano/forest-ui"` | `variant: "standard" \| "dot"`, `color`, `badgeContent`, `max`, `invisible`, `showZero`, `overlap: "rectangular" \| "circular"`, `anchorOrigin` | — |
66
+ | `Chip` | `import { Chip } from "@matteoaliano/forest-ui"` | `variant: "filled" \| "outlined"`, `color`, `size: "small" \| "medium"`, `label`, `onDelete`, `clickable`, `avatar`, `icon` | `deleteIcon={<CloseOutlined />}` |
67
+ | `Divider` | `import { Divider } from "@matteoaliano/forest-ui"` | `orientation: "horizontal" \| "vertical"`, `variant: "fullWidth" \| "inset" \| "middle"`, `textAlign`, `flexItem` | — |
68
+ | `Typography` | `import { Typography } from "@matteoaliano/forest-ui"` | `variant: "h1"-"h6" \| "subtitle1" \| "subtitle2" \| "body1" \| "body2" \| "caption" \| "overline" \| "button"`, `align`, `gutterBottom`, `noWrap` | — |
69
+ | `Tooltip` | `import { Tooltip } from "@matteoaliano/forest-ui"` | `title` (required), `placement` (12 positions), `arrow`, `followCursor`, `enterDelay`, `leaveDelay` | `arrow={true}` |
70
+ | `Avatar` | `import { Avatar } from "@matteoaliano/forest-ui"` | `src`, `alt`, `variant: "circular" \| "rounded" \| "square"`, `sizes`, `children` (fallback) |
71
+ | `AvatarGroup` | `import { AvatarGroup } from "@matteoaliano/forest-ui"` | `max`, `total`, `spacing`, `variant` |
72
+ | `ImageList` | `import { ImageList } from "@matteoaliano/forest-ui"` | `variant: "masonry" \| "quilted" \| "standard" \| "woven"`, `cols`, `gap`, `rowHeight` |
73
+ | `ImageListItem` | `import { ImageListItem } from "@matteoaliano/forest-ui"` | `cols`, `rows` |
74
+ | `ImageListItemBar` | `import { ImageListItemBar } from "@matteoaliano/forest-ui"` | `title`, `subtitle`, `position`, `actionIcon` |
75
+ | `Logo` | `import { Logo } from "@matteoaliano/forest-ui"` | `product: "wsuite" \| "studio" \| "feedati"`, `variant: "logo" \| "logomark"`, `sx` | `product="wsuite"`, `variant="logo"`, `height={32}` |
76
+ | `Rating` | `import { Rating } from "@matteoaliano/forest-ui"` | `value`, `onChange`, `precision`, `max`, `size`, `readOnly`, `disabled` |
77
+ | `Table` family | `import { Table, TableHead, TableBody, TableRow, TableCell, TableContainer } from "@matteoaliano/forest-ui"` | Table: `size: "small" \| "medium"`, `stickyHeader`; TableCell: `align`, `padding`, `sortDirection`, `variant`; TableRow: `hover`, `selected` | — |
78
+ | `DataGrid` | `import { DataGrid, type GridColDef } from "@matteoaliano/forest-ui"` | `rows`, `columns`, `paginationModel`, `sortModel`, `filterModel`, `checkboxSelection`, `loading`, `density` | — |
79
+ | `List` family | `import { List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListItemAvatar, ListSubheader } from "@matteoaliano/forest-ui"` | `dense`, `disablePadding`; ListItemButton: `selected`, `disabled`; ListItemText: `primary`, `secondary` | — |
80
+ | `TableFooter` | `import { TableFooter } from "@matteoaliano/forest-ui"` | `component`, `children` |
81
+ | `TablePagination` | `import { TablePagination } from "@matteoaliano/forest-ui"` | `count`, `page`, `rowsPerPage`, `onPageChange`, `onRowsPerPageChange` |
82
+ | `TableSortLabel` | `import { TableSortLabel } from "@matteoaliano/forest-ui"` | `active`, `direction: "asc" \| "desc"`, `onClick` |
83
+ | `ListItemSecondaryAction` | `import { ListItemSecondaryAction } from "@matteoaliano/forest-ui"` | `children` |
84
+ | `SnackbarContent` | `import { SnackbarContent } from "@matteoaliano/forest-ui"` | `message`, `action` |
48
85
 
49
86
  ## Surfaces
50
87
 
51
88
  | Component | Import | Variants / Key Props | Default Props |
52
89
  |-----------|--------|----------------------|---------------|
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` | — |
90
+ | `Accordion` family | `import { Accordion, AccordionSummary, AccordionDetails, AccordionActions } from "@matteoaliano/forest-ui"` | `expanded`, `defaultExpanded`, `onChange`, `disabled`, `disableGutters`, `square` | — |
91
+ | `AppBar` + `Toolbar` | `import { AppBar, Toolbar } from "@matteoaliano/forest-ui"` | `position`, `color`, `elevation`; Toolbar: `variant: "dense" \| "regular"` | — |
92
+ | `AppBarNavItem` | `import { AppBarNavItem } from "@matteoaliano/forest-ui"` | `label` (required), `icon`, `selected`, `href`, `sx` — navigation button for AppBar | — |
93
+ | `Card` family | `import { Card, CardContent, CardHeader, CardActions, CardMedia } from "@matteoaliano/forest-ui"` | `variant: "elevation" \| "outlined"`, `elevation`, `raised`; CardHeader: `title`, `subheader`, `avatar`, `action` | — |
94
+ | `Paper` | `import { Paper } from "@matteoaliano/forest-ui"` | `variant: "elevation" \| "outlined"`, `elevation` (0-24), `square` | — |
95
+ | `CardActionArea` | `import { CardActionArea } from "@matteoaliano/forest-ui"` | `onClick`, `href`, `disabled` |
96
+ | `Drawer` | `import { Drawer } from "@matteoaliano/forest-ui"` | `open`, `onClose`, `anchor: "left" \| "right" \| "top" \| "bottom"`, `variant: "permanent" \| "persistent" \| "temporary"` |
97
+ | `SwipeableDrawer` | `import { SwipeableDrawer } from "@matteoaliano/forest-ui"` | `onOpen` (required), `onClose` (required), `open`, `anchor`, `swipeAreaWidth` |
57
98
 
58
99
  ## Feedback
59
100
 
60
101
  | Component | Import | Variants / Key Props | Default Props |
61
102
  |-----------|--------|----------------------|---------------|
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` | — |
103
+ | `Alert` + `AlertTitle` | `import { Alert, AlertTitle } from "@matteoaliano/forest-ui"` | `severity: "success" \| "info" \| "warning" \| "error"`, `variant: "filled" \| "outlined" \| "standard"`, `color`, `icon`, `action`, `onClose` | — |
104
+ | `Dialog` family | `import { Dialog, DialogTitle, DialogContent, DialogActions, DialogContentText } from "@matteoaliano/forest-ui"` | `open` (required), `onClose`, `fullWidth`, `maxWidth`, `fullScreen`, `scroll: "paper" \| "body"` | — |
105
+ | `Backdrop` | `import { Backdrop } from "@matteoaliano/forest-ui"` | `open` (required), `invisible`, `onClick` | — |
106
+ | `LinearProgress` | `import { LinearProgress } from "@matteoaliano/forest-ui"` | `variant: "indeterminate" \| "determinate" \| "buffer" \| "query"`, `value` (0-100), `color` | — |
107
+ | `CircularProgress` | `import { CircularProgress } from "@matteoaliano/forest-ui"` | `variant: "indeterminate" \| "determinate"`, `value` (0-100), `color`, `size`, `thickness` | — |
108
+ | `Skeleton` | `import { Skeleton } from "@matteoaliano/forest-ui"` | `variant: "text" \| "circular" \| "rectangular" \| "rounded"`, `animation: "pulse" \| "wave" \| false`, `width`, `height` | — |
109
+ | `Modal` | `import { Modal } from "@matteoaliano/forest-ui"` | `open` (required), `onClose`, `children`, `keepMounted`, `disableAutoFocus`, `disableEscapeKeyDown` | — |
110
+ | `Popover` | `import { Popover } from "@matteoaliano/forest-ui"` | `open` (required), `anchorEl`, `onClose`, `anchorOrigin`, `transformOrigin`, `elevation` | — |
111
+ | `Snackbar` | `import { Snackbar } from "@matteoaliano/forest-ui"` | `open`, `message`, `autoHideDuration`, `onClose`, `action`, `anchorOrigin` | — |
112
+ | `Slider` | `import { Slider } from "@matteoaliano/forest-ui"` | `value`, `onChange`, `min`, `max`, `step`, `marks`, `valueLabelDisplay`, `orientation`, `size` | — |
71
113
 
72
114
  ## Navigation
73
115
 
74
116
  | Component | Import | Variants / Key Props | Default Props |
75
117
  |-----------|--------|----------------------|---------------|
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"` |
118
+ | `Breadcrumbs` | `import { Breadcrumbs } from "@matteoaliano/forest-ui"` | `separator`, `maxItems`, `itemsAfterCollapse`, `itemsBeforeCollapse` | — |
119
+ | `Link` | `import { Link } from "@matteoaliano/forest-ui"` | `href`, `underline: "none" \| "hover" \| "always"`, `color`, `variant` | — |
120
+ | `Menu` + `MenuList` | `import { Menu, MenuList } from "@matteoaliano/forest-ui"` | Menu: `open` (required), `anchorEl`, `onClose`; use with `MenuItem` | — |
121
+ | `Pagination` | `import { Pagination } from "@matteoaliano/forest-ui"` | `count`, `page`, `onChange`, `variant: "text" \| "outlined"`, `shape`, `size`, `color`, `showFirstButton`, `showLastButton` | — |
122
+ | `Stepper` family | `import { Stepper, Step, StepLabel } from "@matteoaliano/forest-ui"` | `activeStep`, `orientation`, `alternativeLabel`, `nonLinear`; Step: `completed`, `disabled`; StepLabel: `optional`, `error` | — |
123
+ | `Tabs` + `Tab` | `import { Tabs, Tab } from "@matteoaliano/forest-ui"` | Tabs: `value`, `onChange`, `variant: "standard" \| "scrollable" \| "fullWidth"`, `orientation`, `centered`; Tab: `label`, `icon`, `iconPosition`, `disabled`, `value` | — |
124
+ | `SidebarNav` | `import { SidebarNav, SidebarItem, useSidebar } from "@matteoaliano/forest-ui"` | `open`, `onOpenChange`, `behavior: "permanent" \| "hover"`, `expandedWidth`, `collapsedWidth`, `showToggle`, `header`, `footer` | `expandedWidth=240`, `collapsedWidth=48`, `behavior="permanent"` |
83
125
  | `SidebarItem` | (same import) | `icon` (required), `label` (required), `endAdornment`, `selected`, `onClick`, `disabled` | — |
126
+ | `BottomNavigation` | `import { BottomNavigation } from "@matteoaliano/forest-ui"` | `value`, `onChange`, `showLabels` |
127
+ | `BottomNavigationAction` | `import { BottomNavigationAction } from "@matteoaliano/forest-ui"` | `label`, `icon`, `value`, `showLabel` |
128
+ | `SpeedDial` | `import { SpeedDial } from "@matteoaliano/forest-ui"` | `ariaLabel` (required), `open`, `onOpen`, `onClose`, `icon`, `direction` |
129
+ | `SpeedDialAction` | `import { SpeedDialAction } from "@matteoaliano/forest-ui"` | `icon`, `tooltipTitle`, `onClick` |
130
+ | `SpeedDialIcon` | `import { SpeedDialIcon } from "@matteoaliano/forest-ui"` | `icon`, `openIcon` |
131
+ | `MobileStepper` | `import { MobileStepper } from "@matteoaliano/forest-ui"` | `steps`, `activeStep`, `variant: "dots" \| "progress" \| "text"`, `nextButton`, `backButton` |
132
+ | `PaginationItem` | `import { PaginationItem } from "@matteoaliano/forest-ui"` | `type`, `page`, `selected`, `disabled`, `shape`, `size` |
133
+ | `StepButton` | `import { StepButton } from "@matteoaliano/forest-ui"` | `optional`, `children`, `onClick` |
134
+ | `StepConnector` | `import { StepConnector } from "@matteoaliano/forest-ui"` | (styling via theme) |
135
+ | `StepContent` | `import { StepContent } from "@matteoaliano/forest-ui"` | `children`, `TransitionComponent`, `transitionDuration` |
136
+ | `StepIcon` | `import { StepIcon } from "@matteoaliano/forest-ui"` | `active`, `completed`, `error`, `icon` |
137
+ | `TabScrollButton` | `import { TabScrollButton } from "@matteoaliano/forest-ui"` | `direction: "left" \| "right"`, `orientation`, `disabled` |
84
138
 
85
139
  ## Charts
86
140
 
87
- Requires `@mui/x-charts` peer dependency. Chart colors are automatically applied from the theme's 12-color series palette.
141
+ Requires `@mui/x-charts` peer dependency. All chart components are re-exported from `@matteoaliano/forest-ui` — never import directly from `@mui/x-charts`. Chart colors are automatically applied from the theme's 12-color series palette.
142
+
143
+ ### Chart Components
88
144
 
89
145
  | Component | Import | Variants / Key Props | Default Props |
90
146
  |-----------|--------|----------------------|---------------|
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) | — |
147
+ | `BarChart` | `import { BarChart } from "@matteoaliano/forest-ui"` | `series` (supports `variant: "solid" \| "striped"` per series), `colors`, `xAxis`, `yAxis`, `width`, `height` | `grid horizontal`, `borderRadius=4`, highlight/fade on hover |
148
+ | `LineChart` | `import { LineChart } from "@matteoaliano/forest-ui"` | `series`, `colors`, `xAxis`, `yAxis`, `width`, `height` | `curve="linear"`, `strokeWidth=3`, `grid horizontal`, highlight/fade on hover |
149
+ | `PieChart` | `import { PieChart } from "@matteoaliano/forest-ui"` | `series` (data: `{ id, value, label, color? }[]`), `colors`, `width`, `height` | highlight/fade on hover |
150
+ | `ScatterChart` | `import { ScatterChart } from "@matteoaliano/forest-ui"` | `series`, `colors`, `xAxis`, `yAxis`, `width`, `height` | — |
151
+ | `Gauge` | `import { Gauge } from "@matteoaliano/forest-ui"` | `value`, `valueMin`, `valueMax`, `startAngle`, `endAngle`, `width`, `height` | — |
152
+ | `SparkLineChart` | `import { SparkLineChart } from "@matteoaliano/forest-ui"` | `data`, `plotType: "line" \| "bar"`, `width`, `height`, `colors` | — |
153
+ | `useChartColors` | `import { useChartColors } from "@matteoaliano/forest-ui"` | `useChartColors(count)` — returns `string[]` of theme chart series colors (max 12) | — |
154
+
155
+ ### Chart Composition Primitives
156
+
157
+ For building custom chart layouts, these low-level primitives are also available:
158
+
159
+ - **Containers:** `ChartContainer`, `ResponsiveChartContainer`, `ChartsSurface`, `ChartsClipPath`
160
+ - **Axis & Grid:** `ChartsAxis`, `ChartsXAxis`, `ChartsYAxis`, `ChartsGrid`, `ChartsReferenceLine`
161
+ - **Legend & Tooltip:** `ChartsLegend`, `DefaultChartsLegend`, `ChartsTooltip`, `ChartsAxisTooltipContent`, `ChartsItemTooltipContent`, `ContinuousColorLegend`, `PiecewiseColorLegend`
162
+ - **Gauge parts:** `GaugeContainer`, `GaugeReferenceArc`, `GaugeValueArc`, `GaugeValueText`
163
+ - **Plot layers — Bar:** `BarPlot`, `BarElement`, `BarElementPath`, `BarLabel`
164
+ - **Plot layers — Line & Area:** `LinePlot`, `LineElement`, `AreaPlot`, `AreaElement`, `LineHighlightPlot`, `MarkPlot`, `AnimatedArea`, `AnimatedLine`
165
+ - **Plot layers — Pie:** `PiePlot`, `PieArc`, `PieArcPlot`, `PieArcLabel`, `PieArcLabelPlot`
166
+ - **Plot layers — Scatter:** `ScatterPlot`, `Scatter`
167
+ - **Interaction:** `ChartsAxisHighlight`, `ChartsOnAxisClickHandler`, `ChartsVoronoiHandler`, `HighlightedProvider`
168
+ - **Text:** `ChartsText`
169
+ - **Hooks:** `useDrawingArea`, `useChartId`, `useSvgRef`, `useXAxis`, `useXScale`, `useYAxis`, `useYScale`, `useAxisTooltip`, `useItemTooltip`, `useMouseTracker`, `useHighlighted`, `useItemHighlighted`, `useGaugeState`
170
+ - **Color palettes:** `blueberryTwilightPalette`, `cheerfulFiestaPalette`, `mangoFusionPalette` (each with `Light` and `Dark` variants)
171
+
172
+ ## Transitions
173
+
174
+ | Component | Import | Key Props |
175
+ |-----------|--------|-----------|
176
+ | `Collapse` | `import { Collapse } from "@matteoaliano/forest-ui"` | `in`, `timeout`, `orientation: "vertical" \| "horizontal"`, `collapsedSize`, `unmountOnExit` |
177
+ | `Fade` | `import { Fade } from "@matteoaliano/forest-ui"` | `in`, `timeout`, `appear` |
178
+ | `Grow` | `import { Grow } from "@matteoaliano/forest-ui"` | `in`, `timeout`, `appear` |
179
+ | `Slide` | `import { Slide } from "@matteoaliano/forest-ui"` | `in`, `direction: "up" \| "down" \| "left" \| "right"`, `timeout`, `container` |
180
+ | `Zoom` | `import { Zoom } from "@matteoaliano/forest-ui"` | `in`, `timeout`, `appear` |
181
+
182
+ ## Utilities
183
+
184
+ | Component | Import | Key Props |
185
+ |-----------|--------|-----------|
186
+ | `ClickAwayListener` | `import { ClickAwayListener } from "@matteoaliano/forest-ui"` | `onClickAway` (required), `mouseEvent`, `touchEvent`, `children` |
187
+ | `NoSsr` | `import { NoSsr } from "@matteoaliano/forest-ui"` | `defer`, `fallback`, `children` |
188
+ | `Portal` | `import { Portal } from "@matteoaliano/forest-ui"` | `container`, `disablePortal`, `children` |
189
+ | `Popper` | `import { Popper } from "@matteoaliano/forest-ui"` | `open` (required), `anchorEl`, `placement`, `transition`, `modifiers` |
190
+ | `TextareaAutosize` | `import { TextareaAutosize } from "@matteoaliano/forest-ui"` | `minRows`, `maxRows`, all textarea HTML attributes |
191
+ | `SvgIcon` | `import { SvgIcon } from "@matteoaliano/forest-ui"` | `viewBox`, `fontSize`, `color`, `children` (SVG path elements) |
192
+ | `ButtonBase` | `import { ButtonBase } from "@matteoaliano/forest-ui"` | `onClick`, `disabled`, `href`, `component`, `disableRipple` |
193
+ | `GlobalStyles` | `import { GlobalStyles } from "@matteoaliano/forest-ui"` | `styles` (required) — CSS object or function |
194
+
195
+ ## Hooks
196
+
197
+ | Hook | Import | Signature |
198
+ |------|--------|-----------|
199
+ | `useMediaQuery` | `import { useMediaQuery } from "@matteoaliano/forest-ui"` | `useMediaQuery(query): boolean` — responsive breakpoint detection |
200
+ | `useScrollTrigger` | `import { useScrollTrigger } from "@matteoaliano/forest-ui"` | `useScrollTrigger(options?): boolean` — detect scroll for hide-on-scroll AppBars |
201
+ | `useFormControl` | `import { useFormControl } from "@matteoaliano/forest-ui"` | `useFormControl(): FormControlState` — access parent FormControl state |
202
+ | `useTheme` | `import { useTheme } from "@matteoaliano/forest-ui"` | `useTheme(): Theme` — access the current MUI theme object |
@@ -5,8 +5,7 @@
5
5
  ### Form Layout
6
6
 
7
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
8
+ import { TextField, Button, Select, MenuItem, Checkbox, Box } from "@matteoaliano/forest-ui";
10
9
 
11
10
  function ContactForm() {
12
11
  return (
@@ -135,24 +134,95 @@ function ConfirmDialog({ open, onClose, onConfirm }) {
135
134
  }
136
135
  ```
137
136
 
138
- ### Sidebar Navigation
137
+ ### App Shell (AppBar + Sidebar Navigation)
138
+
139
+ The standard application layout: a full-width AppBar at the top with a SidebarNav below it. The Toolbar uses three equal `flex: 1` columns so the Search stays visually centered. The sidebar drawer uses `position: relative` to flow inside the layout instead of overlaying as a fixed panel.
139
140
 
140
141
  ```tsx
141
- import { SidebarNav, SidebarItem } from "@matteoaliano/forest-ui";
142
- import DashboardOutlined from "@mui/icons-material/DashboardOutlined";
142
+ import { useState } from "react";
143
+ import {
144
+ AppBar, Toolbar, Logo, Search, IconButton, Badge,
145
+ SidebarNav, SidebarItem, List, Typography, Box, Avatar,
146
+ } from "@matteoaliano/forest-ui";
147
+ import NotificationsOutlined from "@mui/icons-material/NotificationsOutlined";
143
148
  import SettingsOutlined from "@mui/icons-material/SettingsOutlined";
149
+ import HomeOutlined from "@mui/icons-material/HomeOutlined";
150
+ import BarChartOutlined from "@mui/icons-material/BarChartOutlined";
151
+ import PeopleOutlined from "@mui/icons-material/PeopleOutlined";
152
+
153
+ function AppShell({ children }) {
154
+ const [sidebarOpen, setSidebarOpen] = useState(true);
144
155
 
145
- function AppShell() {
146
- const [open, setOpen] = useState(true);
147
156
  return (
148
- <SidebarNav open={open} onOpenChange={setOpen}>
149
- <SidebarItem icon={<DashboardOutlined />} label="Dashboard" selected />
150
- <SidebarItem icon={<SettingsOutlined />} label="Settings" />
151
- </SidebarNav>
157
+ <Box sx={{ display: "flex", flexDirection: "column", height: "100vh" }}>
158
+ {/* ── App Bar ── */}
159
+ <AppBar
160
+ position="sticky"
161
+ elevation={0}
162
+ sx={{ zIndex: (theme) => theme.zIndex.drawer + 1 }}
163
+ >
164
+ <Toolbar variant="dense" sx={{ px: { xs: "16px", sm: "16px" } }}>
165
+ {/* Left — Logo */}
166
+ <Box sx={{ flex: 1, display: "flex", alignItems: "center" }}>
167
+ <Logo product="wsuite" />
168
+ </Box>
169
+ {/* Center — Search (always visually centered) */}
170
+ <Box sx={{ flex: 1, display: "flex", justifyContent: "center" }}>
171
+ <Search size="small" sx={{ width: "100%", maxWidth: 480 }} />
172
+ </Box>
173
+ {/* Right — Actions */}
174
+ <Box sx={{ flex: 1, display: "flex", alignItems: "center", justifyContent: "flex-end", gap: 1 }}>
175
+ <IconButton size="small" color="inherit">
176
+ <Badge color="error" variant="dot">
177
+ <NotificationsOutlined fontSize="small" />
178
+ </Badge>
179
+ </IconButton>
180
+ <IconButton size="small" color="inherit">
181
+ <SettingsOutlined fontSize="small" />
182
+ </IconButton>
183
+ <Avatar sx={{ width: 28, height: 28, fontSize: 13 }}>MA</Avatar>
184
+ </Box>
185
+ </Toolbar>
186
+ </AppBar>
187
+
188
+ {/* ── Body: Sidebar + Content ── */}
189
+ <Box sx={{ display: "flex", flexGrow: 1, overflow: "hidden" }}>
190
+ <SidebarNav
191
+ open={sidebarOpen}
192
+ onOpenChange={setSidebarOpen}
193
+ sx={{
194
+ height: "100%",
195
+ "& .MuiDrawer-paper": { position: "relative", height: "100%" },
196
+ }}
197
+ >
198
+ <List>
199
+ <SidebarItem icon={<HomeOutlined />} label="Home" selected />
200
+ <SidebarItem icon={<BarChartOutlined />} label="Analytics" />
201
+ <SidebarItem icon={<PeopleOutlined />} label="Users" />
202
+ <SidebarItem icon={<SettingsOutlined />} label="Settings" />
203
+ </List>
204
+ </SidebarNav>
205
+
206
+ <Box
207
+ component="main"
208
+ sx={{ flexGrow: 1, p: 3, overflow: "auto", backgroundColor: "background.paper" }}
209
+ >
210
+ {children}
211
+ </Box>
212
+ </Box>
213
+ </Box>
152
214
  );
153
215
  }
154
216
  ```
155
217
 
218
+ **Key patterns:**
219
+ - `Toolbar variant="dense"` — 48px height instead of 64px
220
+ - Three `flex: 1` columns in Toolbar — keeps Search centered regardless of left/right content width
221
+ - `px: { xs: "16px", sm: "16px" }` on Toolbar — aligns logo with sidebar icons (overrides MUI's responsive 24px default)
222
+ - `position: "relative"` on drawer paper — makes sidebar flow in layout, not overlay
223
+ - `height: "100%"` on SidebarNav — sidebar border extends full height
224
+ - `backgroundColor: "background.paper"` on content — contrasts with sidebar/AppBar background
225
+
156
226
  ### Charts
157
227
 
158
228
  Colors are automatically assigned from the theme's 12-series palette. Override with the `colors` prop if needed.
@@ -3,14 +3,14 @@ name: forest-internal
3
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
4
  metadata:
5
5
  author: Forest Design System
6
- version: 0.4.3
6
+ version: 0.5.0
7
7
  ---
8
8
 
9
9
  # Forest UI — Internal Preset
10
10
 
11
11
  ## Golden Rules
12
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`.
13
+ 1. **NEVER import from `@mui/material` directly.** Always import from `@matteoaliano/forest-ui`. All MUI components, layout primitives, transitions, form helpers, and hooks are re-exported. The only exception is `@mui/icons-material` — import icons from there directly.
14
14
  2. **ALWAYS wrap your app root with `<ForestProvider>`** — it applies the theme and CSS baseline.
15
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
16
  4. **NEVER create custom component wrappers** for things Forest UI already provides.
@@ -23,6 +23,8 @@ metadata:
23
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
24
  ```
25
25
 
26
+ > **Note:** `@mui/material`, `@mui/x-data-grid`, `@mui/x-date-pickers`, and `@mui/x-charts` are **peer dependencies** — install them but **always import from `@matteoaliano/forest-ui`**, not from these packages directly. Forest UI re-exports everything.
27
+
26
28
  ```tsx
27
29
  import { ForestProvider } from "@matteoaliano/forest-ui";
28
30
 
@@ -39,30 +41,39 @@ function App() {
39
41
 
40
42
  - **Aeonik** — the default font for all UI text (headings, body, labels, buttons, etc.)
41
43
  - **Aeonik Mono** — use for numeric values: prices, stats, table figures, counters, dates, IDs, code snippets
42
- - **Alkemy Beta** — reserved exclusively for branding elements (e.g. Logo component). Never use for general UI text
44
+ - **Alkemy Beta** — use for page titles (h1/hero headings). Not for general UI text
43
45
 
44
46
  Import the font CSS files you need in your app entry point:
45
47
 
46
48
  ```tsx
47
49
  import "@matteoaliano/forest-ui/fonts/aeonik/aeonik.css";
48
50
  import "@matteoaliano/forest-ui/fonts/aeonik-mono/aeonik-mono.css";
49
- // Only if using branding/logo elements:
50
51
  import "@matteoaliano/forest-ui/fonts/alkemy-beta/alkemy-beta.css";
51
52
  ```
52
53
 
53
54
  ## Available Components
54
55
 
55
- **Inputs:** Button, ButtonGroup, TextField, Select + MenuItem, MultiSelect, Checkbox, RadioGroup + Radio, Switch, ToggleButton + ToggleButtonGroup, Fab, IconButton, Autocomplete, Search, DatePicker
56
+ **Inputs:** Button, ButtonGroup, TextField, Select + MenuItem, MultiSelect, Checkbox, RadioGroup + Radio, Switch, ToggleButton + ToggleButtonGroup, Fab, IconButton, Autocomplete, Search, DatePicker, Input
57
+
58
+ **Data Display:** Badge, Chip, Divider, Typography, Tooltip, Logo, Table family (Table, TableHead, TableBody, TableRow, TableCell, TableContainer, TableFooter, TablePagination, TableSortLabel), DataGrid + GridColDef, List family (List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListItemAvatar, ListItemSecondaryAction, ListSubheader), Avatar + AvatarGroup, ImageList + ImageListItem + ImageListItemBar, Rating
59
+
60
+ **Surfaces:** Accordion family, AppBar + Toolbar + AppBarNavItem, Card family + CardActionArea, Paper, Drawer + SwipeableDrawer
61
+
62
+ **Feedback:** Alert + AlertTitle, Dialog family, Backdrop, LinearProgress, CircularProgress, Skeleton, Modal, Popover, Snackbar + SnackbarContent, Slider
63
+
64
+ **Navigation:** Breadcrumbs, Link, Menu + MenuList, Pagination + PaginationItem, Stepper family (Stepper, Step, StepLabel, StepButton, StepConnector, StepContent, StepIcon), Tabs + Tab + TabScrollButton, SidebarNav + SidebarItem + useSidebar, BottomNavigation + BottomNavigationAction, SpeedDial + SpeedDialAction + SpeedDialIcon, MobileStepper
65
+
66
+ **Layout:** Box, Stack, Grid, Container
56
67
 
57
- **Data Display:** Badge, Chip, Divider, Typography, Tooltip, Table family (Table, TableHead, TableBody, TableRow, TableCell, TableContainer), DataGrid + GridColDef, List family
68
+ **Form Helpers:** FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel, InputAdornment, InputBase, InputLabel, OutlinedInput, FilledInput
58
69
 
59
- **Surfaces:** Accordion family, AppBar + Toolbar, Card family, Paper
70
+ **Transitions:** Collapse, Fade, Grow, Slide, Zoom
60
71
 
61
- **Feedback:** Alert + AlertTitle, Dialog family, Backdrop, LinearProgress, CircularProgress, Skeleton, Modal, Popover, Snackbar
72
+ **Utilities:** ClickAwayListener, NoSsr, Portal, Popper, TextareaAutosize, SvgIcon, ButtonBase, GlobalStyles
62
73
 
63
- **Navigation:** Breadcrumbs, Link, Menu + MenuList, Pagination, Stepper family, Tabs + Tab, SidebarNav + SidebarItem + useSidebar
74
+ **Hooks:** useMediaQuery, useScrollTrigger, useFormControl, useTheme
64
75
 
65
- **Charts:** BarChart, LineChart, PieChart, useChartColors
76
+ **Charts:** BarChart, LineChart, PieChart, ScatterChart, Gauge, SparkLineChart, useChartColors, plus composition primitives (see components.md)
66
77
 
67
78
  See `references/components.md` for full API details and `references/patterns.md` for code examples.
68
79
 
@@ -75,7 +86,7 @@ See `references/components.md` for full API details and `references/patterns.md`
75
86
 
76
87
  ## Common Anti-Patterns
77
88
 
78
- 1. **Importing from `@mui/material`** instead of `@matteoaliano/forest-ui`
89
+ 1. **Importing from `@mui/material`** instead of `@matteoaliano/forest-ui` — all components, hooks, and layout primitives are available from forest-ui
79
90
  2. **Hardcoded color values** (`backgroundColor: "#7f56d9"`) instead of theme tokens (`backgroundColor: "primary.main"`)
80
91
  3. **Hardcoded spacing** (`padding: "16px"`) instead of theme spacing (`p: 4`)
81
92
  4. **Missing `<ForestProvider>`** at the app root — theme won't apply