@matteoaliano/forest-ui 0.5.2 → 0.7.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.
@@ -1,202 +0,0 @@
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
- > **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 |
40
-
41
- ## Inputs
42
-
43
- | Component | Import | Variants / Key Props | Default Props |
44
- |-----------|--------|----------------------|---------------|
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 |
60
-
61
- ## Data Display
62
-
63
- | Component | Import | Variants / Key Props | Default Props |
64
- |-----------|--------|----------------------|---------------|
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, type GridRenderCellParams, type GridRowSelectionModel } from "@matteoaliano/forest-ui"` | `rows`, `columns`, `paginationModel`, `sortModel`, `filterModel`, `checkboxSelection`, `loading`, `density`. Types: `GridColDef`, `GridRowsProp`, `GridRowParams`, `GridCellParams`, `GridRenderCellParams`, `GridRowSelectionModel`, `GridSortModel`, `GridFilterModel`, `GridPaginationModel` | — |
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` |
85
-
86
- ## Surfaces
87
-
88
- | Component | Import | Variants / Key Props | Default Props |
89
- |-----------|--------|----------------------|---------------|
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"`, `hideBackdrop` | `anchor="right"`, `hideBackdrop={true}` |
97
- | `SwipeableDrawer` | `import { SwipeableDrawer } from "@matteoaliano/forest-ui"` | `onOpen` (required), `onClose` (required), `open`, `anchor`, `swipeAreaWidth` |
98
-
99
- ## Feedback
100
-
101
- | Component | Import | Variants / Key Props | Default Props |
102
- |-----------|--------|----------------------|---------------|
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` | — |
113
-
114
- ## Navigation
115
-
116
- | Component | Import | Variants / Key Props | Default Props |
117
- |-----------|--------|----------------------|---------------|
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"` |
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` |
138
-
139
- ## Charts
140
-
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
144
-
145
- | Component | Import | Variants / Key Props | Default Props |
146
- |-----------|--------|----------------------|---------------|
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 |
@@ -1,405 +0,0 @@
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, Box } from "@matteoaliano/forest-ui";
9
-
10
- function ContactForm() {
11
- return (
12
- <Box sx={{ display: "flex", flexDirection: "column", gap: 3 }}>
13
- <TextField label="Name" fullWidth />
14
- <TextField label="Email" type="email" fullWidth />
15
- <Select label="Subject" fullWidth>
16
- <MenuItem value="support">Support</MenuItem>
17
- <MenuItem value="sales">Sales</MenuItem>
18
- </Select>
19
- <Button variant="contained" type="submit">
20
- Send
21
- </Button>
22
- </Box>
23
- );
24
- }
25
- ```
26
-
27
- ### MultiSelect with Select All
28
-
29
- ```tsx
30
- import { useState } from "react";
31
- import { MultiSelect } from "@matteoaliano/forest-ui";
32
-
33
- const options = [
34
- { label: "Bug", value: "bug" },
35
- { label: "Enhancement", value: "enhancement" },
36
- { label: "New Feature", value: "feature" },
37
- ];
38
-
39
- function CategoryFilter() {
40
- const [selected, setSelected] = useState<string[]>([]);
41
- return (
42
- <MultiSelect
43
- label="Category"
44
- options={options}
45
- value={selected}
46
- onChange={setSelected}
47
- />
48
- );
49
- }
50
- ```
51
-
52
- ### Data Table
53
-
54
- ```tsx
55
- import {
56
- Table, TableContainer, TableHead, TableBody, TableRow, TableCell,
57
- } from "@matteoaliano/forest-ui";
58
-
59
- function UsersTable({ users }) {
60
- return (
61
- <TableContainer>
62
- <Table>
63
- <TableHead>
64
- <TableRow>
65
- <TableCell>Name</TableCell>
66
- <TableCell>Email</TableCell>
67
- </TableRow>
68
- </TableHead>
69
- <TableBody>
70
- {users.map((u) => (
71
- <TableRow key={u.id}>
72
- <TableCell>{u.name}</TableCell>
73
- <TableCell>{u.email}</TableCell>
74
- </TableRow>
75
- ))}
76
- </TableBody>
77
- </Table>
78
- </TableContainer>
79
- );
80
- }
81
- ```
82
-
83
- ### DataGrid
84
-
85
- ```tsx
86
- import { DataGrid, type GridColDef } from "@matteoaliano/forest-ui";
87
-
88
- const columns: GridColDef[] = [
89
- { field: "id", headerName: "ID", width: 70 },
90
- { field: "name", headerName: "Name", flex: 1 },
91
- { field: "email", headerName: "Email", flex: 1 },
92
- ];
93
-
94
- function UsersGrid({ rows }) {
95
- return <DataGrid rows={rows} columns={columns} />;
96
- }
97
- ```
98
-
99
- ### Feedback Pattern
100
-
101
- ```tsx
102
- import { Alert, AlertTitle, Snackbar } from "@matteoaliano/forest-ui";
103
-
104
- // Inline feedback
105
- <Alert severity="error">
106
- <AlertTitle>Error</AlertTitle>
107
- Something went wrong.
108
- </Alert>
109
-
110
- // Toast notification
111
- <Snackbar open={open} autoHideDuration={4000} onClose={handleClose}>
112
- <Alert severity="success" variant="filled">Saved!</Alert>
113
- </Snackbar>
114
- ```
115
-
116
- ### Confirmation Dialog
117
-
118
- ```tsx
119
- import { Dialog, DialogTitle, DialogContent, DialogActions, DialogContentText, Button } from "@matteoaliano/forest-ui";
120
-
121
- function ConfirmDialog({ open, onClose, onConfirm }) {
122
- return (
123
- <Dialog open={open} onClose={onClose}>
124
- <DialogTitle>Confirm</DialogTitle>
125
- <DialogContent>
126
- <DialogContentText>Are you sure?</DialogContentText>
127
- </DialogContent>
128
- <DialogActions>
129
- <Button variant="outlined" onClick={onClose}>Cancel</Button>
130
- <Button onClick={onConfirm}>Confirm</Button>
131
- </DialogActions>
132
- </Dialog>
133
- );
134
- }
135
- ```
136
-
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.
140
-
141
- ```tsx
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";
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);
155
-
156
- return (
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>
214
- );
215
- }
216
- ```
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
-
226
- ### Detail Drawer
227
-
228
- Use the `Drawer` component when a user clicks an item (table row, card, list entry) to view or edit its details in a side panel. The Drawer defaults to `anchor="right"` and `hideBackdrop={true}`, so it opens on the right without dimming the page — the user retains full visibility of the content behind it.
229
-
230
- ```tsx
231
- import { useState } from "react";
232
- import {
233
- Drawer, Box, Typography, IconButton, Divider, Chip, Stack,
234
- DataGrid, type GridColDef,
235
- } from "@matteoaliano/forest-ui";
236
- import CloseOutlined from "@mui/icons-material/CloseOutlined";
237
-
238
- function KeywordTable({ rows, columns }: { rows: any[]; columns: GridColDef[] }) {
239
- const [selected, setSelected] = useState<any | null>(null);
240
-
241
- return (
242
- <Box sx={{ display: "flex", height: "100%" }}>
243
- <Box sx={{ flex: 1, minWidth: 0 }}>
244
- <DataGrid
245
- rows={rows}
246
- columns={columns}
247
- onRowClick={(params) => setSelected(params.row)}
248
- />
249
- </Box>
250
-
251
- <Drawer open={!!selected} onClose={() => setSelected(null)}>
252
- {selected && (
253
- <Box sx={{ width: 400, p: 3 }}>
254
- {/* Header */}
255
- <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2 }}>
256
- <Typography variant="h6">{selected.name}</Typography>
257
- <IconButton size="small" onClick={() => setSelected(null)}>
258
- <CloseOutlined />
259
- </IconButton>
260
- </Box>
261
- <Divider sx={{ mb: 2 }} />
262
-
263
- {/* Detail content */}
264
- <Stack direction="row" spacing={1} sx={{ mb: 3 }}>
265
- <Chip label={`${selected.volume} vol`} size="small" />
266
- <Chip label={selected.category} size="small" variant="outlined" />
267
- </Stack>
268
- <Typography variant="body2" color="text.secondary">
269
- {selected.description}
270
- </Typography>
271
- </Box>
272
- )}
273
- </Drawer>
274
- </Box>
275
- );
276
- }
277
- ```
278
-
279
- **Key points:**
280
- - `anchor="right"` and `hideBackdrop={true}` are the Forest defaults — no need to set them
281
- - The Drawer takes full viewport height and overlays the right side of the page
282
- - Always include a close button in the Drawer header
283
- - Set a fixed `width` on the Drawer content (e.g. 400px)
284
- - The content behind the Drawer remains fully visible and interactive
285
-
286
- ### Charts
287
-
288
- Colors are automatically assigned from the theme's 12-series palette. Override with the `colors` prop if needed.
289
-
290
- ```tsx
291
- import { BarChart, LineChart, PieChart, useChartColors } from "@matteoaliano/forest-ui";
292
-
293
- // Bar chart with striped variant
294
- <BarChart
295
- series={[
296
- { data: [10, 20, 30], label: "Current", variant: "solid" },
297
- { data: [8, 15, 25], label: "Previous", variant: "striped" },
298
- ]}
299
- xAxis={[{ data: ["Jan", "Feb", "Mar"], scaleType: "band" }]}
300
- height={300}
301
- />
302
-
303
- // Line chart
304
- <LineChart
305
- series={[{ data: [10, 20, 30], label: "Revenue" }]}
306
- xAxis={[{ data: ["Jan", "Feb", "Mar"], scaleType: "band" }]}
307
- height={300}
308
- />
309
-
310
- // Pie chart
311
- <PieChart
312
- series={[{ data: [
313
- { id: 0, value: 40, label: "Desktop" },
314
- { id: 1, value: 30, label: "Mobile" },
315
- { id: 2, value: 30, label: "Tablet" },
316
- ]}]}
317
- height={300}
318
- />
319
-
320
- // Access chart colors programmatically
321
- const colors = useChartColors(3);
322
- ```
323
-
324
- ## Storybook Controls
325
-
326
- When adding argTypes to stories:
327
-
328
- ```tsx
329
- const meta: Meta<typeof Button> = {
330
- component: Button,
331
- argTypes: {
332
- variant: {
333
- control: "select",
334
- options: ["contained", "outlined", "text"],
335
- },
336
- color: {
337
- control: "select",
338
- options: ["primary", "secondary", "error", "warning", "success", "info"],
339
- },
340
- disabled: { control: "boolean" },
341
- },
342
- };
343
- ```
344
-
345
- **Control types:** `"select"` with `options`, `"boolean"`, `"number"`, `"text"`.
346
-
347
- ## Anti-Patterns
348
-
349
- ```tsx
350
- // WRONG: importing from @mui/material
351
- import Button from "@mui/material/Button";
352
-
353
- // WRONG: hardcoded colors
354
- <Box sx={{ backgroundColor: "#7f56d9" }} />
355
-
356
- // WRONG: hardcoded spacing
357
- <Box sx={{ padding: "16px" }} />
358
-
359
- // WRONG: forgetting ForestProvider
360
- ReactDOM.render(<App />, root); // theme won't apply
361
-
362
- // WRONG: using filled (default) icons
363
- import CloseIcon from "@mui/icons-material/Close";
364
-
365
- // CORRECT: always use Outlined variant
366
- import CloseIcon from "@mui/icons-material/CloseOutlined";
367
-
368
- // CORRECT: use theme tokens
369
- <Box sx={{ backgroundColor: "primary.main", p: 4 }} />
370
-
371
- // WRONG: manually building multi-select with Select + Checkbox
372
- // CORRECT: use the MultiSelect component
373
- <MultiSelect options={options} value={value} onChange={setValue} />
374
-
375
- // WRONG: inline detail panel — a flex Box that sits inside the content area
376
- // This is not a design system pattern and creates inconsistent layouts
377
- <Box sx={{ display: "flex" }}>
378
- <Box sx={{ flex: 1 }}><DataGrid ... /></Box>
379
- {selected && (
380
- <Box sx={{ width: 400, borderLeft: 1, borderColor: "divider", p: 2 }}>
381
- {/* detail content sitting next to the table */}
382
- </Box>
383
- )}
384
- </Box>
385
-
386
- // CORRECT: use the Drawer component for detail panels
387
- // It opens full viewport height on the right, without a backdrop
388
- <Drawer open={!!selected} onClose={() => setSelected(null)}>
389
- <Box sx={{ width: 400, p: 3 }}>
390
- {/* detail content */}
391
- </Box>
392
- </Drawer>
393
- ```
394
-
395
- ## TypeScript Props
396
-
397
- Every component exports its props type:
398
-
399
- ```tsx
400
- import { Button, type ButtonProps } from "@matteoaliano/forest-ui";
401
-
402
- interface MyButtonProps extends ButtonProps {
403
- analyticsId: string;
404
- }
405
- ```