cleanplate 0.3.4 → 0.3.6

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,5 +1,4 @@
1
1
  export function getInitials(name?: string): string;
2
- export function getAvatarBgColor(name?: string): string;
3
2
  export function getSpacingClass(marginConfig: any, styleObject: any, prefix: any): any;
4
3
  export function getUniqueId(): string;
5
4
  export function getVariantIcon(variant: any): string;
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.js"],"names":[],"mappings":"AAEO,mDAIN;AAEM,wDASN;AAEM,uFAcN;AAEM,sCAON;AAEM,qDAgBN;AAEM,oDAEN;AAEM,mGAcN"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.js"],"names":[],"mappings":"AAEO,mDAIN;AAEM,uFAcN;AAEM,sCAON;AAEM,qDAgBN;AAEM,oDAEN;AAEM,mGAcN"}
package/docs/AppShell.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AppShell Component
2
2
 
3
- Purpose: Full-page layout that combines an optional Header (top), optional Footer (bottom), and an optional MenuList as a left sidebar, with main content in the center. Use for dashboard-style apps where the sidebar holds primary navigation and the header holds logo and utilities (e.g. user menu). Sidebar is hidden below 1024px; pass the same menu items to the header for the header’s mobile menu. To avoid duplicating nav in the header center on desktop, set **`showCenterMenu: false`** on Header props (see `docs/Header.md`).
3
+ Purpose: Full-page layout that combines an optional Header (top), optional Footer (bottom), and an optional MenuList as a left sidebar, with main content in the center. Use for dashboard-style apps where the sidebar holds primary navigation and the header holds logo and utilities (e.g. user account **Dropdown** with **Avatar** trigger). Sidebar is hidden below 1024px; pass the same menu items to the header for the header’s mobile menu. To avoid duplicating nav in the header center on desktop, set **`showCenterMenu: false`** on Header props (see `docs/Header.md`). For **`headerRight`** user menus, follow the same **user meta + vertical MenuList** content structure as **`docs/Dropdown.md`** (*Recommended: account / user menu content*)—whether you render **`<Header />`** yourself or pass **`header={{ ... }}`** here.
4
4
 
5
5
  ## Props / Inputs
6
6
 
@@ -50,13 +50,54 @@ interface AppShellProps {
50
50
 
51
51
  ```jsx
52
52
  import { useState } from "react";
53
- import { AppShell, Container, Typography, Avatar } from "cleanplate";
53
+ import { AppShell, Container, Typography, Avatar, Dropdown, MenuList } from "cleanplate";
54
54
 
55
55
  const MENU_ITEMS = [
56
56
  { label: "Dashboard", value: "/", icon: "speed" },
57
57
  { label: "Settings", value: "/settings", icon: "settings" },
58
58
  ];
59
59
 
60
+ const ACCOUNT_MENU_ITEMS = [
61
+ { label: "Profile", value: "/profile", icon: "account_circle" },
62
+ { label: "Sign out", value: "/logout", icon: "logout" },
63
+ ];
64
+
65
+ /** Same structure as `docs/Dropdown.md` — Recommended: account / user menu content */
66
+ function AccountMenuContent({ onClose }) {
67
+ const handleMenuClick = () => {
68
+ onClose?.();
69
+ };
70
+ return (
71
+ <>
72
+ <div
73
+ style={{
74
+ padding: "var(--space-2) var(--space-4) var(--space-3) var(--space-4)",
75
+ marginBottom: "var(--space-2)",
76
+ borderBottom: "1px solid var(--gray-100)",
77
+ }}
78
+ >
79
+ <Typography variant="small" margin="0" style={{ color: "var(--text-muted)" }}>
80
+ Signed in as
81
+ </Typography>
82
+ <Typography variant="p" margin="t-2" isBold style={{ color: "var(--text-default)" }}>
83
+ Jordan Lee
84
+ </Typography>
85
+ <Typography variant="small" margin="t-2" wordBreak="wrap" style={{ color: "var(--text-subtle)" }}>
86
+ jordan@example.com
87
+ </Typography>
88
+ </div>
89
+ <MenuList
90
+ items={ACCOUNT_MENU_ITEMS}
91
+ direction="vertical"
92
+ variant="light"
93
+ size="small"
94
+ margin="0"
95
+ onMenuClick={handleMenuClick}
96
+ />
97
+ </>
98
+ );
99
+ }
100
+
60
101
  const Dashboard = () => {
61
102
  const [active, setActive] = useState("/");
62
103
  const onMenuClick = (item) => setActive(item.value);
@@ -74,7 +115,16 @@ const Dashboard = () => {
74
115
  showCenterMenu: false,
75
116
  activeMenuItem: active,
76
117
  onMenuItemClick: onMenuClick,
77
- headerRight: <Avatar name="User" />,
118
+ headerRight: (
119
+ <Dropdown
120
+ placement="bottom-end"
121
+ offset={8}
122
+ trigger={
123
+ <Avatar name="Jordan Lee" size="medium" margin="0" tabIndex={0} />
124
+ }
125
+ content={<AccountMenuContent />}
126
+ />
127
+ ),
78
128
  }}
79
129
  footer={{ brandName: "Acme Inc" }}
80
130
  sidebarWidth="260px"
@@ -106,6 +156,8 @@ const Dashboard = () => {
106
156
 
107
157
  ### Header and footer only (no sidebar)
108
158
 
159
+ Use the same **`headerRight`** account menu pattern as in the full dashboard example (`Dropdown` + **`Avatar`** + **`AccountMenuContent`** from **`docs/Dropdown.md`**).
160
+
109
161
  ```jsx
110
162
  <AppShell
111
163
  header={{
@@ -113,7 +165,14 @@ const Dashboard = () => {
113
165
  menuItems,
114
166
  activeMenuItem: active,
115
167
  onMenuItemClick: (item) => setActive(item.value),
116
- headerRight: <Avatar name="User" />,
168
+ headerRight: (
169
+ <Dropdown
170
+ placement="bottom-end"
171
+ offset={8}
172
+ trigger={<Avatar name="Jordan Lee" size="medium" margin="0" tabIndex={0} />}
173
+ content={<AccountMenuContent />}
174
+ />
175
+ ),
117
176
  }}
118
177
  footer={{ brandName: "My App" }}
119
178
  >
@@ -136,7 +195,7 @@ const Dashboard = () => {
136
195
  ## Behavior Notes
137
196
 
138
197
  - **Layout:** Root is a flex column with `min-height: 100vh`. Header and footer slots are full width; body is a flex row (sidebar + main). Main area is scrollable.
139
- - **Header / footer:** When `header` or `footer` is a plain object with Header/Footer props (e.g. `menuItems` for header), the component renders `<Header {...header} />` or `<Footer {...footer} />`. Otherwise it renders the ReactNode as-is.
198
+ - **Header / footer:** When `header` or `footer` is a plain object with Header/Footer props (e.g. `menuItems` for header), the component renders `<Header {...header} />` or `<Footer {...footer} />`. Otherwise it renders the ReactNode as-is. **`header.headerRight`** should follow the same patterns as a standalone **`Header`** (see **`docs/Header.md`** and **`docs/Dropdown.md`** for the recommended account **`Dropdown`** content layout).
140
199
  - **Sidebar:** Rendered in an `<aside aria-label="Main navigation">` with MenuList `direction="vertical"`. Width from `sidebarWidth` (inline style).
141
200
  - **Responsive:** At viewport width ≤ 1024px the sidebar column is hidden via CSS. When `header` is `HeaderProps`, the default is to rely on the header’s mobile menu for the same items. When there is no header (or `mobileSidebarDrawer` is `true`), AppShell renders a **Floating UI** mobile drawer: fixed menu trigger, `FloatingPortal` + `FloatingOverlay` (scroll lock) + `FloatingFocusManager` (modal focus), dismiss on overlay press and Escape, and the same `MenuList` as the sidebar. On desktop, use Header’s **`showCenterMenu: false`** when the sidebar already shows the same items so the header center stays empty (or use **`headerCenter`** for a title or other content).
142
201
  - **No root spacing props:** AppShell does not expose margin/padding; use `className` or `contentClassName` for layout.
@@ -144,6 +203,7 @@ const Dashboard = () => {
144
203
  ## Related Components / Links
145
204
 
146
205
  - Header (Header props or custom node; with sidebar + `HeaderProps`, pass **`showCenterMenu: false`** to hide duplicate center nav on desktop while keeping `menuItems` for the mobile menu)
206
+ - Dropdown (see **`docs/Dropdown.md`** — recommended account menu **`content`** for **`headerRight`** with **`HeaderProps`**)
147
207
  - Footer (rendered in footer slot when footer is Footer props)
148
208
  - MenuList (used in sidebar with direction="vertical")
149
209
  - Container (wrap page content inside children)
package/docs/Avatar.md CHANGED
@@ -6,14 +6,14 @@ Purpose: Displays user initials, an image, or a Material icon in a consistent ci
6
6
 
7
7
  | Prop | Type | Required | Default | Description |
8
8
  | --- | --- | --- | --- | --- |
9
- | name | string | no | "" | Display name; used for initials and `title` when no image/icon. Also used for image `alt` and for generating background color when showing initials. |
9
+ | name | string | no | "" | Display name; used for initials and `title` when no image/icon. Also used for image `alt`. |
10
10
  | image | string | no | "" | Image URL; when set, shows image instead of initials or icon. |
11
11
  | icon | MaterialIconName | no | — | Material icon name; when set (and no image), shows icon instead of initials. |
12
12
  | size | "small" \| "medium" | no | "medium" | Size of the avatar. |
13
- | margin | string \| string[] | no | "m-0" | Spacing **suffix** for outer margin. The component adds the `m-` prefix (e.g. `"0"` → m-0, `"b-2"` → m-b-2). Use a single string or array: `"0"`, `["2", "b-3"]`. |
13
+ | margin | string \| string[] | no | "0" | Spacing **suffix** for outer margin. The component adds the `m-` prefix (e.g. `"0"` → m-0, `"b-2"` → m-b-2). Use a single string or array: `"0"`, `["2", "b-3"]`. |
14
14
  | onClick | function | no | — | Click handler for the root div. |
15
- | className | string | no | "" | Additional class names for the root element. |
16
- | ...rest | React.HTMLAttributes<HTMLDivElement> | no | — | Any other div attributes (e.g. `id`, `data-*`, `aria-*`, `style`) are forwarded. |
15
+ | className | string | no | "" | Additional class names for the root element; use to override backgrounds or other visuals (no inline `style` on Avatar). |
16
+ | ...rest | `Omit<HTMLAttributes<HTMLDivElement>, "style">` | no | — | Other div attributes (`id`, `data-*`, `aria-*`, etc.). The **`style`** prop is not supported; use **`className`** and CSS instead. Use the **`ref`** from `React.forwardRef` for imperative access or parent-managed refs (e.g. **Dropdown** `trigger`). |
17
17
 
18
18
  ## Types
19
19
 
@@ -34,7 +34,7 @@ type AvatarMargin = string | SpacingOption[];
34
34
 
35
35
  ### AvatarProps
36
36
  ```typescript
37
- interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
37
+ interface AvatarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "style"> {
38
38
  name?: string;
39
39
  image?: string;
40
40
  icon?: MaterialIconName; // from "../icon/material-icon-names"
@@ -87,6 +87,14 @@ export const Example = () => (
87
87
  );
88
88
  ```
89
89
 
90
+ ### Custom appearance (`className`)
91
+
92
+ Backgrounds come from CSS modules (`--primary-brand` for initials/icon, `--white` behind images). Override with your own class:
93
+
94
+ ```jsx
95
+ <Avatar name="VIP" className="my-avatar--gold" />
96
+ ```
97
+
90
98
  ### Clickable avatar
91
99
 
92
100
  ```jsx
@@ -101,6 +109,24 @@ export const Example = () => (
101
109
  );
102
110
  ```
103
111
 
112
+ ### As Dropdown trigger (e.g. header user menu)
113
+
114
+ [`Dropdown`](./Dropdown.md) clones the `trigger` element and injects **`ref`**, **`onClick`** (toggle), **`role="button"`**, **`aria-expanded`**, **`aria-haspopup`**, and a merged **`className`**. **`Avatar`** uses **`forwardRef`**, so pass it as the trigger and set identity props as usual. For account menus in **`Header`** or **`AppShell`** (`HeaderProps.headerRight`), use the **user meta + vertical `MenuList`** pattern in **`docs/Dropdown.md`** (*Recommended: account / user menu content*), not a bare `MenuList` only.
115
+
116
+ ```jsx
117
+ import { Dropdown, Avatar, MenuList } from "cleanplate";
118
+
119
+ <Dropdown
120
+ placement="bottom-end"
121
+ trigger={
122
+ <Avatar name="Jane Doe" image="/avatar.jpg" size="medium" margin="0" tabIndex={0} />
123
+ }
124
+ content={<AccountMenuContent />}
125
+ />
126
+ ```
127
+
128
+ You do **not** pass `onClick` yourself when using `trigger`—Dropdown supplies it. Optional: add **`tabIndex={0}`** on Avatar (via spread / rest) if you need the trigger in tab order like a native button.
129
+
104
130
  ### With Container
105
131
 
106
132
  ```jsx
@@ -119,9 +145,9 @@ export const Example = () => (
119
145
 
120
146
  - **Display priority:** If `image` is set, the image is shown. Else if `icon` is set, the Material icon is shown. Otherwise initials from `name` are shown.
121
147
  - **Initials:** Derived from the first letter of each word in `name` (up to 2 characters), e.g. "John Doe" → "JD".
122
- - **Background color:** When showing initials, background color is generated deterministically from `name` (hash-based).
148
+ - **Backgrounds (CSS only):** **Initials** use `var(--primary-brand)` on the root. **Icon** mode uses `var(--primary-brand)` for the circle. **Image** mode uses `var(--white)` behind the photo so transparent PNGs do not show a hole. To change colors, add a **`className`** and target the root in your stylesheet.
123
149
  - **Spacing:** `margin` accepts the **spacing suffix**; the component adds the `m-` prefix via `getSpacingClass`. Use suffix form (e.g. `"0"`, `"2"`, `"b-3"`) when passing values explicitly.
124
- - **Root element:** A `div`; all standard HTML div attributes and ref are supported via `...rest`.
150
+ - **Root element:** A `div`; supports `ref` and other attributes except **`style`** (omitted from the public type so layout stays class-based).
125
151
 
126
152
  ## Related Components / Links
127
153
 
package/docs/Dropdown.md CHANGED
@@ -160,6 +160,82 @@ export const Example = () => (
160
160
  />
161
161
  ```
162
162
 
163
+ ### Recommended: account / user menu content (Header & AppShell)
164
+
165
+ When **`headerRight`** is a user menu, use **`Dropdown`** with an **`Avatar`** trigger (`placement="bottom-end"` and `offset={8}` are typical) and **`content`** built in **two parts**:
166
+
167
+ 1. **User meta** — Optional caption (“Signed in as”), **display name**, **email**. Use **`Typography`** with clear hierarchy: `variant="small"` + `var(--text-muted)` for the caption; `variant="p"` + `isBold` + `var(--text-default)` for the name; `variant="small"` + `wordBreak="wrap"` + `var(--text-subtle)` for the email. Space lines with the **`margin`** suffix API (e.g. `"0"`, `"t-2"`).
168
+ 2. **Actions** — A vertical **`MenuList`** (`direction="vertical"`, `size="small"`). In `onMenuClick`, run your handler then call **`onClose?.()`** so the panel closes (Dropdown injects **`onClose`** into `content` when cloning).
169
+
170
+ **Whitespace:** Vertical **`MenuList`** items use **`padding: 8px 16px`** on each link (`--space-2` × `--space-4`). Wrap the meta block in a container using the same horizontal inset and similar vertical rhythm so copy lines up with menu rows:
171
+
172
+ ```jsx
173
+ const accountMetaStyle = {
174
+ padding: "var(--space-2) var(--space-4) var(--space-3) var(--space-4)",
175
+ marginBottom: "var(--space-2)",
176
+ borderBottom: "1px solid var(--gray-100)",
177
+ };
178
+ ```
179
+
180
+ Use the same structure whether **`Header`** is used standalone or passed as **`header`** on **`AppShell`** (`HeaderProps`); only data and handlers change.
181
+
182
+ ```jsx
183
+ import { Dropdown, Avatar, MenuList, Typography } from "cleanplate";
184
+
185
+ const ACCOUNT_MENU_ITEMS = [
186
+ { label: "Profile", value: "/profile", icon: "account_circle" },
187
+ { label: "Settings", value: "/settings", icon: "settings" },
188
+ { label: "Sign out", value: "/logout", icon: "logout" },
189
+ ];
190
+
191
+ function AccountMenuContent({ onClose, onItemSelect }) {
192
+ const handleMenuClick = (item) => {
193
+ onItemSelect?.(item);
194
+ onClose?.();
195
+ };
196
+ return (
197
+ <>
198
+ <div
199
+ style={{
200
+ padding: "var(--space-2) var(--space-4) var(--space-3) var(--space-4)",
201
+ marginBottom: "var(--space-2)",
202
+ borderBottom: "1px solid var(--gray-100)",
203
+ }}
204
+ >
205
+ <Typography variant="small" margin="0" style={{ color: "var(--text-muted)" }}>
206
+ Signed in as
207
+ </Typography>
208
+ <Typography variant="p" margin="t-2" isBold style={{ color: "var(--text-default)" }}>
209
+ Jordan Lee
210
+ </Typography>
211
+ <Typography variant="small" margin="t-2" wordBreak="wrap" style={{ color: "var(--text-subtle)" }}>
212
+ jordan@example.com
213
+ </Typography>
214
+ </div>
215
+ <MenuList
216
+ items={ACCOUNT_MENU_ITEMS}
217
+ direction="vertical"
218
+ variant="light"
219
+ size="small"
220
+ margin="0"
221
+ onMenuClick={handleMenuClick}
222
+ />
223
+ </>
224
+ );
225
+ }
226
+
227
+ <Dropdown
228
+ placement="bottom-end"
229
+ offset={8}
230
+ trigger={
231
+ <Avatar name="Jordan Lee" image="/avatar.jpg" size="medium" margin="0" tabIndex={0} />
232
+ }
233
+ content={<AccountMenuContent />}
234
+ />
235
+ ```
236
+
237
+ Live reference: **molecules/Header/Playground** in Storybook uses this pattern for **`headerRight`**.
238
+
163
239
  ## Behavior Notes
164
240
 
165
241
  - **Trigger modes:** Exactly one of `trigger`, `renderTrigger`, or `triggerLabel` must be used; the component throws if none are provided.
@@ -171,5 +247,7 @@ export const Example = () => (
171
247
  ## Related Components / Links
172
248
 
173
249
  - Button (commonly used as trigger or inside renderTrigger)
250
+ - Avatar (common trigger for account menus; see **Recommended: account / user menu content** above)
174
251
  - MenuList (often used inside dropdown content for menu items)
252
+ - Header, AppShell (pass the same `headerRight` / account menu structure for standalone header or shell layout)
175
253
  - Icon (used in the default trigger when `triggerLabel` is set for arrow icons)
package/docs/Header.md CHANGED
@@ -83,19 +83,33 @@ const AppHeader = () => {
83
83
 
84
84
  ### With AppShell (desktop nav in sidebar only)
85
85
 
86
- Use `showCenterMenu: false` so `menuItems` is only used for the header’s mobile menu while the sidebar shows the same links on desktop.
86
+ Use `showCenterMenu: false` so `menuItems` is only used for the header’s mobile menu while the sidebar shows the same links on desktop. For **`headerRight`**, use the same **Dropdown + Avatar + user meta + vertical MenuList** pattern as in **`docs/Dropdown.md`** (*Recommended: account / user menu content*)—whether **`Header`** is rendered by you or by **`AppShell`** via **`header={{ ... }}`**.
87
87
 
88
88
  ```jsx
89
+ import { Dropdown, Avatar } from "cleanplate";
90
+ // AccountMenuContent: full structure in docs/Dropdown.md
91
+
89
92
  <Header
90
93
  logoUrl="/logo.svg"
91
94
  menuItems={MENU_ITEMS}
92
95
  showCenterMenu={false}
93
96
  activeMenuItem={active}
94
97
  onMenuItemClick={onMenuClick}
95
- headerRight={<Avatar name="User" />}
98
+ headerRight={
99
+ <Dropdown
100
+ placement="bottom-end"
101
+ offset={8}
102
+ trigger={<Avatar name="Jordan Lee" size="medium" margin="0" tabIndex={0} />}
103
+ content={<AccountMenuContent />}
104
+ />
105
+ }
96
106
  />
97
107
  ```
98
108
 
109
+ ### User account menu (`headerRight`)
110
+
111
+ Prefer **`Dropdown`** with **`Avatar`** as **`trigger`** and **`content`** that separates **identity** (caption, name, email with **`Typography`** + meta padding aligned to vertical **`MenuList`** rows) from **actions** (vertical **`MenuList`** calling **`onClose`** after each action). See **`docs/Dropdown.md`** — *Recommended: account / user menu content* — and Storybook **molecules/Header/Playground**.
112
+
99
113
  ### With custom slots
100
114
 
101
115
  ```jsx
@@ -120,6 +134,7 @@ Use `showCenterMenu: false` so `menuItems` is only used for the header’s mobil
120
134
 
121
135
  - **menuItems:** Required; each item has label, value, optional icon (Material icon name).
122
136
  - **headerLeft / headerCenter / headerRight:** When provided, replace the default logo, MenuList, or right slot.
137
+ - **AppShell:** If you pass **`header`** as **`HeaderProps`** to **`AppShell`**, configure **`headerRight`** the same way as a standalone **`Header`** (recommended account dropdown structure does not change).
123
138
  - **showCenterMenu:** When `false`, the center column is empty on desktop (unless `headerCenter` is set). `menuItems` is still used for the mobile overlay.
124
139
  - **Mobile:** Below 1024px, center nav hides; hamburger shows. Click opens slide-in menu (Animated fade-in-left).
125
140
  - **onMenuItemClick:** Called with the clicked item; mobile menu closes on click.
@@ -128,6 +143,7 @@ Use `showCenterMenu: false` so `menuItems` is only used for the header’s mobil
128
143
  ## Related Components / Links
129
144
 
130
145
  - MenuList (used in center and mobile menu)
131
- - Avatar (commonly in headerRight)
146
+ - Dropdown, Avatar (account menu in **headerRight**; see `docs/Dropdown.md`)
147
+ - AppShell (passes **`header`** as Header props; same **headerRight** recommendations apply)
132
148
  - Button, Icon (mobile menu trigger and close)
133
149
  - Animated (mobile menu slide-in)
@@ -9,7 +9,7 @@ Purpose: Combines fixed media (`Avatar`: icon, image, or initials) with a dense
9
9
  | title | string | yes | — | Primary line (e.g. name, sender). Rendered emphasized. |
10
10
  | mediaIcon | `MaterialIconName` \| string | no | "" | Material Symbol name passed to `Avatar`. |
11
11
  | mediaImage | string | no | "" | Image URL for `Avatar`. |
12
- | mediaAvatar | string | no | "" | Display name used for initials and avatar color generation (when image/icon not shown). |
12
+ | mediaAvatar | string | no | "" | Display name used for initials when image/icon are not shown. |
13
13
  | subtitle | `React.ReactNode` | no | — | Optional middle line (e.g. subject). Omit for two-line layouts. |
14
14
  | description | `React.ReactNode` | no | — | Optional preview/snippet line(s); muted, multi-line ellipsis via `--cp-media-object-desc-lines`. |
15
15
  | descriptionLineClamp | number | no | 2 | Max lines for `description` before truncation. |
package/llms.txt CHANGED
@@ -74,7 +74,7 @@ All component documentation is located in the `docs/` folder. The following docu
74
74
  ### Avatar Component
75
75
  - File: `docs/Avatar.md`
76
76
  - Purpose: Displays user initials, an image, or a Material icon in a consistent circle. Use for user identity in headers, lists, MediaObject, or anywhere you need a compact avatar.
77
- - Key Features: Display modes (initials, image, icon), sizes (small, medium), margin spacing (suffix API: e.g. "0" → m-0), optional onClick
77
+ - Key Features: Display modes (initials, image, icon), sizes (small, medium), margin spacing (suffix API: e.g. "0" → m-0), optional onClick; backgrounds from CSS (className overrides), no inline style prop
78
78
  - Types: AvatarProps, AvatarSize, AvatarMargin, SpacingOption; icon prop uses MaterialIconName from Icon
79
79
  - Related Components: Used by MediaObject; often used with Container, Icon
80
80
 
@@ -87,9 +87,9 @@ All component documentation is located in the `docs/` folder. The following docu
87
87
  ### Dropdown Component
88
88
  - File: `docs/Dropdown.md`
89
89
  - Purpose: Floating panel that shows content relative to a trigger. Use for menus, option lists, or any content that opens on click.
90
- - Key Features: 12 placements, flip/shift to stay in viewport, three trigger modes (trigger element, renderTrigger, triggerLabel), close on outside click or Escape
90
+ - Key Features: 12 placements, flip/shift to stay in viewport, three trigger modes (trigger element, renderTrigger, triggerLabel), close on outside click or Escape; **recommended account menu content** (user meta Typography + padding aligned to vertical MenuList + divider + MenuList; same for Header and AppShell `headerRight`)
91
91
  - Types: DropdownProps, DropdownPlacement, DropdownTriggerProps, DropdownRenderTriggerParams
92
- - Related Components: Button (trigger), MenuList (content)
92
+ - Related Components: Button (trigger), Avatar (account trigger), MenuList (content), Header, AppShell
93
93
 
94
94
  ### Alert Component
95
95
  - File: `docs/Alert.md`
@@ -201,9 +201,9 @@ All component documentation is located in the `docs/` folder. The following docu
201
201
  ### Header Component
202
202
  - File: `docs/Header.md`
203
203
  - Purpose: Responsive navigation header with logo, menu items, and customizable left/center/right slots.
204
- - Key Features: logoUrl, menuItems, activeMenuItem, onMenuItemClick, headerLeft, headerCenter, headerRight, showCenterMenu, sizes (small, medium, large), variants (light, dark), margin (suffix API), responsive mobile menu
204
+ - Key Features: logoUrl, menuItems, activeMenuItem, onMenuItemClick, headerLeft, headerCenter, headerRight, showCenterMenu, sizes (small, medium, large), variants (light, dark), margin (suffix API), responsive mobile menu; **headerRight** account menus: Dropdown + Avatar + user meta + vertical MenuList (see `docs/Dropdown.md`)
205
205
  - Types: HeaderProps, HeaderSize, HeaderVariant, HeaderMargin
206
- - Related Components: MenuList (center and mobile menu), Avatar (headerRight), Button, Icon, Animated (used internally)
206
+ - Related Components: MenuList (center and mobile menu), Dropdown, Avatar (headerRight), AppShell, Button, Icon, Animated (used internally)
207
207
 
208
208
  ### PageHeader Component
209
209
  - File: `docs/PageHeader.md`
@@ -229,9 +229,9 @@ All component documentation is located in the `docs/` folder. The following docu
229
229
  ### AppShell Component
230
230
  - File: `docs/AppShell.md`
231
231
  - Purpose: Full-page layout combining optional Header (top), Footer (bottom), and MenuList as left sidebar with main content. For dashboard-style apps.
232
- - Key Features: header (Header props or ReactNode), footer (Footer props or ReactNode), sidebar (AppShellSidebarConfig: items, activeItem, onMenuClick, size, variant), sidebarWidth, mobileSidebarDrawer / mobileSidebarDrawerLabel, responsive (sidebar column hidden ≤1024px; default Floating UI drawer when no HeaderProps header, else header mobile menu); with Header + sidebar use Header `showCenterMenu: false` to avoid duplicate desktop nav
232
+ - Key Features: header (Header props or ReactNode), footer (Footer props or ReactNode), sidebar (AppShellSidebarConfig: items, activeItem, onMenuClick, size, variant), sidebarWidth, mobileSidebarDrawer / mobileSidebarDrawerLabel, responsive (sidebar column hidden ≤1024px; default Floating UI drawer when no HeaderProps header, else header mobile menu); with Header + sidebar use Header `showCenterMenu: false` to avoid duplicate desktop nav; **headerRight** uses same account Dropdown pattern as standalone Header (`docs/Dropdown.md`)
233
233
  - Types: AppShellProps, AppShellSidebarConfig
234
- - Related Components: Header, Footer, MenuList (sidebar), Container, Typography, Avatar
234
+ - Related Components: Header, Footer, MenuList (sidebar), Dropdown, Container, Typography, Avatar
235
235
 
236
236
  ## Documentation Format
237
237
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cleanplate",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "CleanPlate - A Headless React UI Framework",
5
5
  "files": [
6
6
  "dist",