@matteoaliano/forest-ui 0.8.1 → 0.8.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matteoaliano/forest-ui",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "Forest Design System — themed MUI components",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -44,7 +44,8 @@
44
44
  "peerDependencies": {
45
45
  "@emotion/react": "^11.0.0",
46
46
  "@emotion/styled": "^11.0.0",
47
- "@mui/material": "^6.0.0 || ^7.0.0",
47
+ "@mui/icons-material": "^7.0.0",
48
+ "@mui/material": "^7.0.0",
48
49
  "@mui/x-charts": "^7.0.0",
49
50
  "@mui/x-data-grid": "^7.0.0",
50
51
  "@mui/x-date-pickers": "^7.0.0 || ^8.0.0",
@@ -3,7 +3,7 @@ name: forest-alkemy-plus
3
3
  description: Forest UI Design System rules for the Alkemy+ (charcoal/red) preset. Enforces correct imports, component usage, and theming with @matteoaliano/forest-ui. Use when the project uses forest-ui, forest-alkemy-plus preset, or when user builds UI components in a forest-ui project. Triggers on "forest", "forest-ui", "forest alkemy", "forest alkemy+", "@matteoaliano/forest-ui".
4
4
  metadata:
5
5
  author: Forest Design System
6
- version: 0.8.1
6
+ version: 0.8.3
7
7
  ---
8
8
 
9
9
  # Forest UI — Alkemy+ Preset
@@ -11,19 +11,67 @@ metadata:
11
11
  ## Golden Rules
12
12
 
13
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
- 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.
14
+ 2. **ALWAYS import the Forest font CSS at app entry** (see Setup Step 2). The package bundles Aeonik / Aeonik Mono / AlkemyBETA as `.woff2` + `@font-face` CSS, but it does **not** auto-inject them — the consuming app must import the CSS. Skip this and `font-family: "Aeonik"` silently falls back to system sans-serif (Helvetica / Arial / DejaVu), inconsistently across machines. This is the #1 reason Forest sites "don't look right".
15
+ 3. **ALWAYS wrap your app root with `<ForestProvider>`** it applies the theme and CSS baseline.
16
+ 4. **NEVER use inline colors or spacing values.** Use design tokens or MUI's `sx` prop with theme values (`p: 4`, `backgroundColor: "primary.main"`).
17
+ 5. **NEVER create custom component wrappers** for things Forest UI already provides.
18
+ 6. **TypeScript is required.** All components export their prop types (e.g. `type ButtonProps`).
19
+ 7. **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
 
20
21
  ## Setup
21
22
 
23
+ ### Step 1 — Install
24
+
22
25
  ```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
26
+ npm install @matteoaliano/forest-ui \
27
+ @mui/material@^7 @mui/icons-material@^7 \
28
+ @mui/x-charts@^7 @mui/x-data-grid@^7 @mui/x-date-pickers@^8 \
29
+ @emotion/react @emotion/styled dayjs
24
30
  ```
25
31
 
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.
32
+ > **Note:** Every `@mui/*` package above is a **peer dependency** of `@matteoaliano/forest-ui`. Install them at the pinned major versions shown newer majors are not yet supported and will fail `npm install` with `ERESOLVE`. Always import components, hooks, and layout primitives from `@matteoaliano/forest-ui` (Forest UI re-exports them with branded defaults). The single exception is `@mui/icons-material` — import icons from there directly, using the Outlined variant (e.g. `import { CloseOutlined } from "@mui/icons-material"`).
33
+
34
+ ### Step 2 — Load the fonts (CRITICAL — do this before anything else)
35
+
36
+ The Forest preset sets `fontFamily: '"Aeonik", sans-serif'`. Without the matching `@font-face` rules, the browser cannot resolve "Aeonik" and silently falls back to a system font. **Forest UI ships the font files in the npm tarball, but the consuming app must import the CSS.** Add these three imports at the top of your root entry file:
37
+
38
+ ```tsx
39
+ // Next.js App Router → app/layout.tsx (above any other CSS imports)
40
+ // Next.js Pages Router → pages/_app.tsx
41
+ // Vite / CRA → src/main.tsx or src/index.tsx
42
+ import "@matteoaliano/forest-ui/fonts/aeonik/aeonik.css";
43
+ import "@matteoaliano/forest-ui/fonts/aeonik-mono/aeonik-mono.css";
44
+ import "@matteoaliano/forest-ui/fonts/alkemy-beta/alkemy-beta.css";
45
+ ```
46
+
47
+ No `public/fonts/` copy, no `next/font/local`, no manual `@font-face` rules — the bundler resolves the relative `.woff2` URLs inside the CSS automatically.
48
+
49
+ **For Next.js**, also add `transpilePackages` so Turbopack resolves the CSS subpath exports cleanly:
50
+
51
+ ```ts
52
+ // next.config.ts
53
+ const nextConfig = {
54
+ transpilePackages: ["@matteoaliano/forest-ui"],
55
+ experimental: {
56
+ optimizePackageImports: [
57
+ "@matteoaliano/forest-ui",
58
+ "@mui/material",
59
+ "@mui/icons-material",
60
+ ],
61
+ },
62
+ };
63
+ export default nextConfig;
64
+ ```
65
+
66
+ **Verify it worked.** Open DevTools after running `next dev`:
67
+
68
+ 1. **Network tab → filter "font"** — you should see `aeonik-regular.woff2` and friends loading with `200 OK` from `/_next/static/media/...` (or your bundler's asset path).
69
+ 2. **Elements → Computed → font-family** on a `<Typography>` — should read `"Aeonik", sans-serif`.
70
+ 3. **Elements → Rendered Fonts** (Chrome only) — should say `Aeonik — Web font`, not `Arial — Local file` or `Helvetica — Local file`.
71
+
72
+ If Network shows 404s on the woff2 files, the `transpilePackages` step is missing or the bundler isn't picking up the package's subpath exports.
73
+
74
+ ### Step 3 — Wrap your app
27
75
 
28
76
  ```tsx
29
77
  import { ForestProvider } from "@matteoaliano/forest-ui";
@@ -39,17 +87,14 @@ function App() {
39
87
 
40
88
  ## Typography & Fonts
41
89
 
42
- - **Aeonik** — the default font for all UI text (headings, body, labels, buttons, etc.)
43
- - **Aeonik Mono** — use for numeric values: prices, stats, table figures, counters, dates, IDs, code snippets
44
- - **Alkemy Beta** — use for page titles (h1/hero headings). Not for general UI text
45
-
46
- Import the font CSS files you need in your app entry point:
90
+ - **Aeonik** — the default font for all UI text (headings, body, labels, buttons, etc.). Family name: `"Aeonik"`.
91
+ - **Aeonik Mono** — use for numeric values: prices, stats, table figures, counters, dates, IDs, code snippets. Family name: `"Aeonik Mono"`.
92
+ - **AlkemyBETA** — editorial display face for page titles / hero h1. Family name: **`"AlkemyBETA"`** (one word, no space — do not write `"Alkemy Beta"`, it will not resolve). Not auto-applied by the preset — opt in explicitly:
93
+ ```tsx
94
+ <Typography variant="h1" sx={{ fontFamily: '"AlkemyBETA", serif' }}>...</Typography>
95
+ ```
47
96
 
48
- ```tsx
49
- import "@matteoaliano/forest-ui/fonts/aeonik/aeonik.css";
50
- import "@matteoaliano/forest-ui/fonts/aeonik-mono/aeonik-mono.css";
51
- import "@matteoaliano/forest-ui/fonts/alkemy-beta/alkemy-beta.css";
52
- ```
97
+ The three CSS imports in Setup → Step 2 register all of these families. If a Forest site looks like Arial or Helvetica, you skipped Step 2.
53
98
 
54
99
  ## Available Components
55
100
 
@@ -86,9 +131,11 @@ See `references/components.md` for full API details, `references/patterns.md` fo
86
131
 
87
132
  ## Common Anti-Patterns
88
133
 
89
- 1. **Importing from `@mui/material`** instead of `@matteoaliano/forest-ui`all components, hooks, and layout primitives are available from forest-ui
90
- 2. **Hardcoded color values** (`backgroundColor: "#7f56d9"`) instead of theme tokens (`backgroundColor: "primary.main"`)
91
- 3. **Hardcoded spacing** (`padding: "16px"`) instead of theme spacing (`p: 4`)
92
- 4. **Missing `<ForestProvider>`** at the app root theme won't apply
93
- 5. **Using filled MUI icons** (`Close`) instead of Outlined (`CloseOutlined`)
94
- 6. **Building custom multi-select** instead of using the `<MultiSelect>` component
134
+ 1. **Missing the three font-CSS imports at app entry** the most common Forest setup mistake. Aeonik silently falls back to system sans-serif and the UI looks "off" without any console error. See Setup → Step 2 for the imports and a DevTools verification checklist.
135
+ 2. **Writing the AlkemyBETA family with a space** (`"Alkemy Beta"`) the `@font-face` declares `"AlkemyBETA"` (one word). The spaced form fails to resolve.
136
+ 3. **Importing from `@mui/material`** instead of `@matteoaliano/forest-ui` all components, hooks, and layout primitives are available from forest-ui
137
+ 4. **Hardcoded color values** (`backgroundColor: "#7f56d9"`) instead of theme tokens (`backgroundColor: "primary.main"`)
138
+ 5. **Hardcoded spacing** (`padding: "16px"`) instead of theme spacing (`p: 4`)
139
+ 6. **Missing `<ForestProvider>`** at the app root theme won't apply
140
+ 7. **Using filled MUI icons** (`Close`) instead of Outlined (`CloseOutlined`)
141
+ 8. **Building custom multi-select** instead of using the `<MultiSelect>` component