cleanplate 0.2.0 → 0.2.1

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 +1 @@
1
- {"version":3,"file":"material-icon-names.d.ts","sourceRoot":"","sources":["../../../src/components/icon/material-icon-names.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,g/lEAolItB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;CAonIlB,CAAC;AAEX;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,gBAAgB,CAEzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,OAAO,eAAe,GAAG,SAAS,MAAM,EAAE,CAE5F"}
1
+ {"version":3,"file":"material-icon-names.d.ts","sourceRoot":"","sources":["../../../src/components/icon/material-icon-names.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,sjoEAqpItB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;CAqrIlB,CAAC;AAEX;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,gBAAgB,CAEzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,OAAO,eAAe,GAAG,SAAS,MAAM,EAAE,CAE5F"}
@@ -0,0 +1,125 @@
1
+ # Accordion Component
2
+
3
+ Purpose: Displays collapsible panels from an array of title and content items. Use for FAQ sections, feature lists, or expandable content. Supports grouped or spaced layout, icon styles (expand arrows or plus/minus), semantic headings (h2–h6) for SEO FAQ pages, allowMultiple, and margin/padding spacing.
4
+
5
+ ## Props / Inputs
6
+
7
+ | Prop | Type | Required | Default | Description |
8
+ | --- | --- | --- | --- | --- |
9
+ | items | AccordionItem[] | yes | — | Array of { title, content } items. |
10
+ | allowMultiple | boolean | no | false | Allow multiple panels open at once. |
11
+ | defaultExpandedIndex | number \| number[] | no | 0 | Index(es) of panel(s) open initially. |
12
+ | iconVariant | "expand" \| "plus" | no | "expand" | Icon style: expand (arrows) or plus (+/-). |
13
+ | variant | "grouped" \| "spaced" | no | "grouped" | Visual layout: grouped (one unit) or spaced (separate items, e.g. FAQ). |
14
+ | titleTag | "span" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" | no | "span" | Semantic HTML for title; h2–h6 for SEO FAQ pages. |
15
+ | margin | string \| SpacingOption[] | no | — | Spacing suffix(s) for outer margin; component adds m- prefix. |
16
+ | padding | string \| SpacingOption[] | no | — | Spacing suffix(s) for inner padding; component adds p- prefix. |
17
+ | className | string | no | "" | Additional class names for the root element. |
18
+
19
+ ## Types
20
+
21
+ ### AccordionItem
22
+ ```typescript
23
+ interface AccordionItem {
24
+ title: string;
25
+ content: React.ReactNode;
26
+ }
27
+ ```
28
+
29
+ ### AccordionIconVariant
30
+ ```typescript
31
+ type AccordionIconVariant = "expand" | "plus";
32
+ ```
33
+
34
+ ### AccordionVariant
35
+ ```typescript
36
+ type AccordionVariant = "grouped" | "spaced";
37
+ ```
38
+
39
+ ### AccordionTitleTag
40
+ ```typescript
41
+ type AccordionTitleTag = "span" | "h2" | "h3" | "h4" | "h5" | "h6";
42
+ ```
43
+
44
+ ### AccordionMargin / AccordionPadding
45
+ ```typescript
46
+ type AccordionMargin = string | SpacingOption[];
47
+ type AccordionPadding = string | SpacingOption[];
48
+ ```
49
+
50
+ ### AccordionProps
51
+ ```typescript
52
+ interface AccordionProps {
53
+ items: AccordionItem[];
54
+ allowMultiple?: boolean;
55
+ defaultExpandedIndex?: number | number[];
56
+ iconVariant?: AccordionIconVariant;
57
+ variant?: AccordionVariant;
58
+ titleTag?: AccordionTitleTag;
59
+ margin?: AccordionMargin;
60
+ padding?: AccordionPadding;
61
+ className?: string;
62
+ }
63
+ ```
64
+
65
+ ## Usage Examples
66
+
67
+ ### Basic
68
+
69
+ ```jsx
70
+ import { Accordion } from "cleanplate";
71
+
72
+ const items = [
73
+ { title: "Section 1", content: "Content for section 1." },
74
+ { title: "Section 2", content: "Content for section 2." },
75
+ ];
76
+
77
+ <Accordion items={items} />
78
+ ```
79
+
80
+ ### FAQ (SEO-friendly)
81
+
82
+ ```jsx
83
+ <Accordion
84
+ items={faqItems}
85
+ variant="spaced"
86
+ titleTag="h3"
87
+ iconVariant="plus"
88
+ />
89
+ ```
90
+
91
+ ### Variants and icons
92
+
93
+ ```jsx
94
+ <Accordion items={items} variant="grouped" />
95
+ <Accordion items={items} variant="spaced" />
96
+ <Accordion items={items} iconVariant="expand" />
97
+ <Accordion items={items} iconVariant="plus" />
98
+ ```
99
+
100
+ ### Initial panel(s)
101
+
102
+ ```jsx
103
+ <Accordion items={items} defaultExpandedIndex={1} />
104
+ <Accordion items={items} allowMultiple defaultExpandedIndex={[0, 2]} />
105
+ ```
106
+
107
+ ### With spacing
108
+
109
+ ```jsx
110
+ <Accordion items={items} margin="b-2" padding="4" />
111
+ ```
112
+
113
+ ## Behavior Notes
114
+
115
+ - **items:** Each item has `title` (string) and `content` (string or ReactNode). String content is wrapped in Typography.
116
+ - **titleTag:** When h2–h6, titles render as headings for SEO; header uses role="button" with keyboard support.
117
+ - **variant:** grouped = single bordered block; spaced = separate items with gap.
118
+ - **defaultExpandedIndex:** Single number or array; controls which panel(s) are open on initial render.
119
+ - **Margin/padding:** Uses suffix API (e.g. `"0"` → m-0, `"4"` → p-4).
120
+
121
+ ## Related Components / Links
122
+
123
+ - Container (layout around accordion)
124
+ - Typography (used internally for title and string content)
125
+ - Icon (used for expand/collapse indicator)
package/docs/Alert.md ADDED
@@ -0,0 +1,131 @@
1
+ # Alert Component
2
+
3
+ Purpose: Displays a short message with an optional variant icon and dismiss button. Use it for inline feedback (success, error, warning, info) or neutral notices. When dismissed, the alert unmounts (returns null). **Margin** uses the **framework-wide spacing suffix rule** (same for all components); see `llms.txt`.
4
+
5
+ ## Props / Inputs
6
+
7
+ | Prop | Type | Required | Default | Description |
8
+ | --- | --- | --- | --- | --- |
9
+ | message | string | no | — | Main message text shown in the alert. |
10
+ | size | "small" \| "medium" \| "large" | no | "medium" | Size of the alert and its icon/close button. |
11
+ | variant | "success" \| "error" \| "warning" \| "info" \| "default" | no | "info" | Visual variant; each has a matching icon (e.g. success → check_circle, error → error). |
12
+ | canDismiss | boolean | no | false | When true, shows a close button that calls onDismiss and unmounts the alert. |
13
+ | onDismiss | function | no | — | Called when the user dismisses the alert (clicks the close button). |
14
+ | 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"`, `["b-2"]`. |
15
+
16
+ ## Types
17
+
18
+ ### AlertSize
19
+ ```typescript
20
+ type AlertSize = "small" | "medium" | "large";
21
+ ```
22
+
23
+ ### AlertVariant
24
+ ```typescript
25
+ type AlertVariant = "success" | "error" | "warning" | "info" | "default";
26
+ ```
27
+
28
+ ### SpacingOption
29
+ ```typescript
30
+ type SpacingOption = (typeof SPACING_OPTIONS)[number];
31
+ ```
32
+
33
+ ### AlertMargin
34
+ ```typescript
35
+ type AlertMargin = string | SpacingOption[];
36
+ ```
37
+
38
+ ### AlertProps
39
+ ```typescript
40
+ interface AlertProps {
41
+ message?: string;
42
+ size?: AlertSize;
43
+ variant?: AlertVariant;
44
+ canDismiss?: boolean;
45
+ onDismiss?: () => void;
46
+ margin?: AlertMargin;
47
+ }
48
+ ```
49
+
50
+ ## Usage Examples
51
+
52
+ ### Basic
53
+
54
+ ```jsx
55
+ import { Alert } from "cleanplate";
56
+
57
+ export const Example = () => (
58
+ <Alert message="Your changes were saved." variant="success" />
59
+ );
60
+ ```
61
+
62
+ ### Variants
63
+
64
+ ```jsx
65
+ import { Alert } from "cleanplate";
66
+
67
+ export const Example = () => (
68
+ <>
69
+ <Alert message="Default message" variant="default" margin="b-2" />
70
+ <Alert message="Info message" variant="info" margin="b-2" />
71
+ <Alert message="Warning message" variant="warning" margin="b-2" />
72
+ <Alert message="Error message" variant="error" margin="b-2" />
73
+ <Alert message="Success message" variant="success" />
74
+ </>
75
+ );
76
+ ```
77
+
78
+ ### Sizes
79
+
80
+ ```jsx
81
+ import { Alert } from "cleanplate";
82
+
83
+ export const Example = () => (
84
+ <>
85
+ <Alert message="Small alert" variant="info" size="small" margin="b-2" />
86
+ <Alert message="Medium alert" variant="info" size="medium" margin="b-2" />
87
+ <Alert message="Large alert" variant="info" size="large" />
88
+ </>
89
+ );
90
+ ```
91
+
92
+ ### Dismissible
93
+
94
+ ```jsx
95
+ import { Alert } from "cleanplate";
96
+
97
+ export const Example = () => (
98
+ <Alert
99
+ message="This can be dismissed."
100
+ variant="info"
101
+ canDismiss
102
+ onDismiss={() => console.log("Dismissed")}
103
+ />
104
+ );
105
+ ```
106
+
107
+ ### With Container
108
+
109
+ ```jsx
110
+ import { Alert, Container } from "cleanplate";
111
+
112
+ export const Example = () => (
113
+ <Container padding="4">
114
+ <Alert message="Alert inside a container" variant="warning" margin="b-2" />
115
+ </Container>
116
+ );
117
+ ```
118
+
119
+ ## Behavior Notes
120
+
121
+ - **Icon:** Each variant maps to an icon via `getVariantIcon` (e.g. error → "error", success → "check_circle", info → "info", warning → "warning", default → "info").
122
+ - **Dismiss:** When `canDismiss` is true, a close button is shown. Clicking it sets internal visibility to false, calls `onDismiss`, and the component returns `null` (removed from the tree).
123
+ - **Spacing:** `margin` accepts the **spacing suffix**; the component adds the `m-` prefix via `getSpacingClass`. Use suffix form (e.g. `"0"`, `"b-2"`) when passing values.
124
+ - **Root element:** A `div`; Alert does not extend HTML attributes, so only the documented props are supported.
125
+
126
+ ## Related Components / Links
127
+
128
+ - Typography (used internally for the message text)
129
+ - Container (layout and spacing around alerts)
130
+ - Button (used internally for the dismiss button when canDismiss is true)
131
+ - Icon (used for the variant icon and the close icon)
@@ -0,0 +1,101 @@
1
+ # Animated Component
2
+
3
+ Purpose: Atom that adds scroll-triggered entrance (or exit) animations to any content. Uses IntersectionObserver to detect when the element enters the viewport, then applies a CSS animation class. Use it to animate headings, cards, avatars, or any wrapper content as the user scrolls. Supports polymorphic `as`, delay for staggering, and margin (suffix API).
4
+
5
+ ## Props / Inputs
6
+
7
+ | Prop | Type | Required | Default | Description |
8
+ | --- | --- | --- | --- | --- |
9
+ | animationType | AnimationType | no | "fade-in-bottom" | Animation when in view: fade-in-top, fade-in-right, fade-in-bottom, fade-in-left, fade-out-top, fade-out-right, fade-out-bottom, fade-out-left. |
10
+ | as | React.ElementType | no | "span" | Root element or component to render. |
11
+ | margin | string \| SpacingOption[] | no | ["0"] | Margin spacing. Suffix or array of spacing suffixes; component adds `m-` prefix. |
12
+ | delay | number | no | 0 | Delay in ms; maps to class `delay-{delay}` (e.g. 200 → delay-200) for staggered animations. |
13
+ | className | string | no | "" | Additional class names for the root element. |
14
+ | isBlock | boolean | no | false | If true, applies block display. |
15
+ | ...rest | React.HTMLAttributes<HTMLElement> | no | — | Any other HTML attributes forwarded to the root element. |
16
+
17
+ ## Types
18
+
19
+ ### SpacingOption
20
+ ```typescript
21
+ type SpacingOption = (typeof SPACING_OPTIONS)[number];
22
+ ```
23
+
24
+ ### AnimatedMargin
25
+ ```typescript
26
+ type AnimatedMargin = string | SpacingOption[];
27
+ ```
28
+
29
+ ### AnimationType
30
+ ```typescript
31
+ type AnimationType = (typeof ANIMATION_TYPE_OPTIONS)[number];
32
+ // "fade-in-top" | "fade-in-right" | "fade-in-bottom" | "fade-in-left" |
33
+ // "fade-out-top" | "fade-out-right" | "fade-out-bottom" | "fade-out-left"
34
+ ```
35
+
36
+ ### AnimationDelay
37
+ ```typescript
38
+ type AnimationDelay = (typeof ANIMATION_DELAY_OPTIONS)[number];
39
+ // number (e.g. 100, 200, ... 3000)
40
+ ```
41
+
42
+ ### AnimatedProps
43
+ ```typescript
44
+ interface AnimatedProps extends Omit<React.HTMLAttributes<HTMLElement>, "className"> {
45
+ animationType?: AnimationType;
46
+ as?: React.ElementType;
47
+ margin?: AnimatedMargin;
48
+ delay?: number;
49
+ className?: string;
50
+ isBlock?: boolean;
51
+ }
52
+ ```
53
+
54
+ ## Usage Examples
55
+
56
+ ### Basic
57
+
58
+ ```jsx
59
+ import { Animated } from "cleanplate";
60
+
61
+ <Animated animationType="fade-in-bottom">
62
+ <h2>Animates when in view</h2>
63
+ </Animated>
64
+ ```
65
+
66
+ ### Staggered delay
67
+
68
+ ```jsx
69
+ <Animated animationType="fade-in-bottom">First</Animated>
70
+ <Animated animationType="fade-in-bottom" delay={200}>Second</Animated>
71
+ <Animated animationType="fade-in-bottom" delay={400}>Third</Animated>
72
+ ```
73
+
74
+ ### With `as` and isBlock
75
+
76
+ ```jsx
77
+ <Animated as="div" isBlock animationType="fade-in-bottom">
78
+ <section>Block-level content</section>
79
+ </Animated>
80
+ ```
81
+
82
+ ### Animation types
83
+
84
+ ```jsx
85
+ <Animated animationType="fade-in-top">Content</Animated>
86
+ <Animated animationType="fade-in-bottom">Content</Animated>
87
+ <Animated animationType="fade-in-left">Content</Animated>
88
+ <Animated animationType="fade-in-right">Content</Animated>
89
+ ```
90
+
91
+ ## Behavior Notes
92
+
93
+ - **IntersectionObserver:** The root element is observed on mount. When it intersects the viewport, the animation class is applied and the observer unobserves it (one-shot per mount).
94
+ - **Delay:** The `delay` value is used to build a class name `delay-{delay}`. Styles must define the corresponding `animation-delay` for that class (e.g. `.delay-200 { animation-delay: 200ms; }`).
95
+ - **Spacing:** `margin` uses the suffix API; the component adds the `m-` prefix via `getSpacingClass`.
96
+
97
+ ## Related Components / Links
98
+
99
+ - Container (layout around animated content)
100
+ - Typography, Avatar, Badge, Button (common content wrapped by Animated)
101
+ - Header, BottomSheet, MenuList (use Animated internally)
@@ -0,0 +1,145 @@
1
+ # AppShell Component
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.
4
+
5
+ ## Props / Inputs
6
+
7
+ | Prop | Type | Required | Default | Description |
8
+ | --- | --- | --- | --- | --- |
9
+ | children | ReactNode | yes | — | Main content (page area). |
10
+ | header | ReactNode \| HeaderProps | no | — | Top bar: pass Header props object or custom ReactNode. Omit to hide header. |
11
+ | footer | ReactNode \| FooterProps | no | — | Bottom bar: pass Footer props object or custom ReactNode. Omit to hide footer. |
12
+ | sidebar | AppShellSidebarConfig | no | — | Sidebar config (MenuList as vertical nav on the left). Omit to hide sidebar. |
13
+ | sidebarWidth | string | no | "240px" | Width of the sidebar (e.g. "240px", "16rem"). |
14
+ | className | string | no | "" | Additional class name for the root element. |
15
+ | contentClassName | string | no | "" | Additional class name for the main content wrapper. |
16
+
17
+ ## Types
18
+
19
+ ### AppShellSidebarConfig
20
+ ```typescript
21
+ interface AppShellSidebarConfig {
22
+ items: MenuListItem[]; // Menu items for the sidebar
23
+ activeItem?: string; // Value of the currently active item
24
+ onMenuClick?: (item: MenuListItem) => void;
25
+ size?: MenuListSize; // small | medium | large
26
+ variant?: MenuListVariant; // light | dark
27
+ }
28
+ ```
29
+
30
+ ### AppShellProps
31
+ ```typescript
32
+ interface AppShellProps {
33
+ children: React.ReactNode;
34
+ header?: React.ReactNode | HeaderProps;
35
+ footer?: React.ReactNode | FooterProps;
36
+ sidebar?: AppShellSidebarConfig;
37
+ sidebarWidth?: string;
38
+ className?: string;
39
+ contentClassName?: string;
40
+ }
41
+ ```
42
+
43
+ ## Usage Examples
44
+
45
+ ### Full dashboard (sidebar + header + footer)
46
+
47
+ ```jsx
48
+ import { useState } from "react";
49
+ import { AppShell, Container, Typography, Avatar } from "cleanplate";
50
+
51
+ const MENU_ITEMS = [
52
+ { label: "Dashboard", value: "/", icon: "speed" },
53
+ { label: "Settings", value: "/settings", icon: "settings" },
54
+ ];
55
+
56
+ const Dashboard = () => {
57
+ const [active, setActive] = useState("/");
58
+ const onMenuClick = (item) => setActive(item.value);
59
+ return (
60
+ <AppShell
61
+ sidebar={{
62
+ items: MENU_ITEMS,
63
+ activeItem: active,
64
+ onMenuClick,
65
+ variant: "light",
66
+ }}
67
+ header={{
68
+ logoUrl="/logo.svg",
69
+ menuItems: MENU_ITEMS,
70
+ activeMenuItem: active,
71
+ onMenuItemClick: onMenuClick,
72
+ headerRight: <Avatar name="User" />,
73
+ }}
74
+ footer={{ brandName: "Acme Inc" }}
75
+ sidebarWidth="260px"
76
+ >
77
+ <Container padding="4">
78
+ <Typography variant="h4">Dashboard</Typography>
79
+ </Container>
80
+ </AppShell>
81
+ );
82
+ };
83
+ ```
84
+
85
+ ### Sidebar only
86
+
87
+ ```jsx
88
+ <AppShell
89
+ sidebar={{
90
+ items: menuItems,
91
+ activeItem: activeItem,
92
+ onMenuClick: (item) => setActiveItem(item.value),
93
+ }}
94
+ sidebarWidth="240px"
95
+ >
96
+ <Container padding="4">
97
+ <Typography variant="p">Main content</Typography>
98
+ </Container>
99
+ </AppShell>
100
+ ```
101
+
102
+ ### Header and footer only (no sidebar)
103
+
104
+ ```jsx
105
+ <AppShell
106
+ header={{
107
+ logoUrl="/logo.svg",
108
+ menuItems,
109
+ activeMenuItem: active,
110
+ onMenuItemClick: (item) => setActive(item.value),
111
+ headerRight: <Avatar name="User" />,
112
+ }}
113
+ footer={{ brandName: "My App" }}
114
+ >
115
+ <Container padding="4">
116
+ <Typography variant="p">Content</Typography>
117
+ </Container>
118
+ </AppShell>
119
+ ```
120
+
121
+ ### Content only (minimal shell)
122
+
123
+ ```jsx
124
+ <AppShell>
125
+ <Container padding="4">
126
+ <Typography variant="h4">Welcome</Typography>
127
+ </Container>
128
+ </AppShell>
129
+ ```
130
+
131
+ ## Behavior Notes
132
+
133
+ - **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.
134
+ - **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.
135
+ - **Sidebar:** Rendered in an `<aside aria-label="Main navigation">` with MenuList `direction="vertical"`. Width from `sidebarWidth` (inline style).
136
+ - **Responsive:** At viewport width ≤ 1024px the sidebar is hidden via CSS. Pass the same `menuItems` and `activeMenuItem` / `onMenuItemClick` to `header` so the header’s mobile menu provides navigation.
137
+ - **No root spacing props:** AppShell does not expose margin/padding; use `className` or `contentClassName` for layout.
138
+
139
+ ## Related Components / Links
140
+
141
+ - Header (rendered in header slot when header is Header props; use same menu items for mobile)
142
+ - Footer (rendered in footer slot when footer is Footer props)
143
+ - MenuList (used in sidebar with direction="vertical")
144
+ - Container (wrap page content inside children)
145
+ - Typography, Avatar (common in header and main)
package/docs/Avatar.md ADDED
@@ -0,0 +1,130 @@
1
+ # Avatar Component
2
+
3
+ Purpose: Displays user initials, an image, or a Material icon in a consistent circle. Use it for user identity in headers, lists, MediaObject, or anywhere you need a compact avatar. Supports sizes, spacing (margin), and optional click handling.
4
+
5
+ ## Props / Inputs
6
+
7
+ | Prop | Type | Required | Default | Description |
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. |
10
+ | image | string | no | "" | Image URL; when set, shows image instead of initials or icon. |
11
+ | icon | MaterialIconName | no | — | Material icon name; when set (and no image), shows icon instead of initials. |
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"]`. |
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. |
17
+
18
+ ## Types
19
+
20
+ ### SpacingOption
21
+ ```typescript
22
+ type SpacingOption = (typeof SPACING_OPTIONS)[number];
23
+ ```
24
+
25
+ ### AvatarSize
26
+ ```typescript
27
+ type AvatarSize = "small" | "medium";
28
+ ```
29
+
30
+ ### AvatarMargin
31
+ ```typescript
32
+ type AvatarMargin = string | SpacingOption[];
33
+ ```
34
+
35
+ ### AvatarProps
36
+ ```typescript
37
+ interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
38
+ name?: string;
39
+ image?: string;
40
+ icon?: MaterialIconName; // from "../icon/material-icon-names"
41
+ size?: AvatarSize;
42
+ margin?: AvatarMargin;
43
+ onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
44
+ className?: string;
45
+ }
46
+ ```
47
+
48
+ ## Usage Examples
49
+
50
+ ### Name (initials)
51
+
52
+ ```jsx
53
+ import { Avatar } from "cleanplate";
54
+
55
+ export const Example = () => (
56
+ <>
57
+ <Avatar name="John Doe" size="medium" />
58
+ <Avatar name="Jane Smith" size="small" margin="2" />
59
+ </>
60
+ );
61
+ ```
62
+
63
+ ### Icon
64
+
65
+ ```jsx
66
+ import { Avatar } from "cleanplate";
67
+
68
+ export const Example = () => (
69
+ <>
70
+ <Avatar icon="person" size="medium" />
71
+ <Avatar icon="account_circle" size="small" />
72
+ </>
73
+ );
74
+ ```
75
+
76
+ ### Image
77
+
78
+ ```jsx
79
+ import { Avatar } from "cleanplate";
80
+
81
+ export const Example = () => (
82
+ <Avatar
83
+ name="John Doe"
84
+ image="https://example.com/photo.jpg"
85
+ size="medium"
86
+ />
87
+ );
88
+ ```
89
+
90
+ ### Clickable avatar
91
+
92
+ ```jsx
93
+ import { Avatar } from "cleanplate";
94
+
95
+ export const Example = () => (
96
+ <Avatar
97
+ name="John Doe"
98
+ size="medium"
99
+ onClick={() => console.log("Avatar clicked")}
100
+ />
101
+ );
102
+ ```
103
+
104
+ ### With Container
105
+
106
+ ```jsx
107
+ import { Avatar, Container } from "cleanplate";
108
+
109
+ export const Example = () => (
110
+ <Container display="flex" gap="2" align="center">
111
+ <Avatar name="Alice" size="small" margin="0" />
112
+ <Avatar icon="person" size="medium" margin="0" />
113
+ <Avatar image="https://example.com/bob.jpg" name="Bob" size="medium" margin="0" />
114
+ </Container>
115
+ );
116
+ ```
117
+
118
+ ## Behavior Notes
119
+
120
+ - **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
+ - **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).
123
+ - **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`.
125
+
126
+ ## Related Components / Links
127
+
128
+ - MediaObject (often uses Avatar via `mediaAvatar` for the media slot)
129
+ - Container (layout and spacing around avatars)
130
+ - Icon (Avatar can show an icon via the `icon` prop; uses Material icon names)