cleanplate 0.1.11 → 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.
- package/README.md +193 -60
- package/dist/components/accordion/Accordion.d.ts +23 -12
- package/dist/components/accordion/Accordion.d.ts.map +1 -1
- package/dist/components/accordion/index.d.ts +2 -1
- package/dist/components/accordion/index.d.ts.map +1 -1
- package/dist/components/app-shell/AppShell.d.ts +35 -3
- package/dist/components/app-shell/AppShell.d.ts.map +1 -1
- package/dist/components/app-shell/index.d.ts +2 -1
- package/dist/components/app-shell/index.d.ts.map +1 -1
- package/dist/components/bottom-sheet/BottomSheet.d.ts +17 -16
- package/dist/components/bottom-sheet/BottomSheet.d.ts.map +1 -1
- package/dist/components/bottom-sheet/index.d.ts +2 -1
- package/dist/components/bottom-sheet/index.d.ts.map +1 -1
- package/dist/components/breadcrumb/BreadCrumb.d.ts +26 -0
- package/dist/components/breadcrumb/BreadCrumb.d.ts.map +1 -0
- package/dist/components/breadcrumb/index.d.ts +3 -2
- package/dist/components/breadcrumb/index.d.ts.map +1 -1
- package/dist/components/footer/Footer.d.ts +21 -16
- package/dist/components/footer/Footer.d.ts.map +1 -1
- package/dist/components/footer/index.d.ts +2 -1
- package/dist/components/footer/index.d.ts.map +1 -1
- package/dist/components/header/Header.d.ts +32 -28
- package/dist/components/header/Header.d.ts.map +1 -1
- package/dist/components/header/index.d.ts +2 -1
- package/dist/components/header/index.d.ts.map +1 -1
- package/dist/components/icon/material-icon-names.d.ts +5 -5
- package/dist/components/icon/material-icon-names.d.ts.map +1 -1
- package/dist/components/menu-list/MenuList.d.ts +32 -22
- package/dist/components/menu-list/MenuList.d.ts.map +1 -1
- package/dist/components/menu-list/index.d.ts +2 -1
- package/dist/components/menu-list/index.d.ts.map +1 -1
- package/dist/components/page-header/PageHeader.d.ts +22 -3
- package/dist/components/page-header/PageHeader.d.ts.map +1 -1
- package/dist/components/page-header/index.d.ts +2 -1
- package/dist/components/page-header/index.d.ts.map +1 -1
- package/dist/components/toast/Toast.d.ts +20 -12
- package/dist/components/toast/Toast.d.ts.map +1 -1
- package/dist/components/toast/index.d.ts +2 -1
- package/dist/components/toast/index.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.es.css +1 -1
- package/dist/index.es.js +3 -3
- package/dist/index.js +3 -3
- package/docs/Accordion.md +125 -0
- package/docs/Alert.md +131 -0
- package/docs/Animated.md +101 -0
- package/docs/AppShell.md +145 -0
- package/docs/Avatar.md +130 -0
- package/docs/Badge.md +83 -0
- package/docs/BottomSheet.md +78 -0
- package/docs/BreadCrumb.md +133 -0
- package/docs/Button.md +189 -0
- package/docs/ConfirmDialog.md +139 -0
- package/docs/Container.md +230 -0
- package/docs/Dropdown.md +175 -0
- package/docs/Footer.md +93 -0
- package/docs/FormControls.md +115 -0
- package/docs/Header.md +115 -0
- package/docs/Icon.md +225 -0
- package/docs/MediaObject.md +303 -0
- package/docs/MenuList.md +113 -0
- package/docs/Modal.md +152 -0
- package/docs/PageHeader.md +134 -0
- package/docs/Pagination.md +142 -0
- package/docs/Pills.md +104 -0
- package/docs/Spinner.md +115 -0
- package/docs/Stepper.md +131 -0
- package/docs/Table.md +194 -0
- package/docs/Toast.md +96 -0
- package/docs/Typography.md +231 -0
- package/llms.txt +293 -0
- package/package.json +6 -1
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)
|
package/docs/Animated.md
ADDED
|
@@ -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)
|
package/docs/AppShell.md
ADDED
|
@@ -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)
|
package/docs/Badge.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Badge Component
|
|
2
|
+
|
|
3
|
+
Purpose: Displays a short label with a colored background. Use it for status (e.g. success, error, warning), tags, or counts. Renders as an inline-block element with five variants (default, info, success, warning, error). Optional `className` for custom styling.
|
|
4
|
+
|
|
5
|
+
## Props / Inputs
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Required | Default | Description |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| label | string | no | — | Text shown inside the badge. |
|
|
10
|
+
| variant | "default" \| "info" \| "warning" \| "error" \| "success" | no | "default" | Visual variant (gray, blue, orange, red, green). |
|
|
11
|
+
| className | string | no | "" | Additional class names for the root element. |
|
|
12
|
+
|
|
13
|
+
## Types
|
|
14
|
+
|
|
15
|
+
### BadgeVariant
|
|
16
|
+
```typescript
|
|
17
|
+
type BadgeVariant = "default" | "info" | "warning" | "error" | "success";
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### BadgeProps
|
|
21
|
+
```typescript
|
|
22
|
+
interface BadgeProps {
|
|
23
|
+
label?: string;
|
|
24
|
+
variant?: BadgeVariant;
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage Examples
|
|
30
|
+
|
|
31
|
+
### Basic
|
|
32
|
+
|
|
33
|
+
```jsx
|
|
34
|
+
import { Badge } from "cleanplate";
|
|
35
|
+
|
|
36
|
+
<Badge label="New" />
|
|
37
|
+
<Badge label="Active" variant="success" />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Variants
|
|
41
|
+
|
|
42
|
+
```jsx
|
|
43
|
+
<Badge label="Default" variant="default" />
|
|
44
|
+
<Badge label="Info" variant="info" />
|
|
45
|
+
<Badge label="Success" variant="success" />
|
|
46
|
+
<Badge label="Warning" variant="warning" />
|
|
47
|
+
<Badge label="Error" variant="error" />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### With Table (customRender)
|
|
51
|
+
|
|
52
|
+
```jsx
|
|
53
|
+
import { Table, Badge } from "cleanplate";
|
|
54
|
+
|
|
55
|
+
const columns = [
|
|
56
|
+
{ id: "name", title: "Name" },
|
|
57
|
+
{
|
|
58
|
+
id: "status",
|
|
59
|
+
title: "Status",
|
|
60
|
+
customRender: (rowData, column) => (
|
|
61
|
+
<Badge label={String(rowData.status)} variant="success" />
|
|
62
|
+
),
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
<Table columns={columns} data={data} />;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Custom className
|
|
69
|
+
|
|
70
|
+
```jsx
|
|
71
|
+
<Badge label="Custom" variant="info" className="my-badge" />
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Behavior Notes
|
|
75
|
+
|
|
76
|
+
- **Element:** Renders as a `<p>` with `display: inline-block` in styles.
|
|
77
|
+
- **Label:** Optional; can be omitted or empty.
|
|
78
|
+
- **Variants:** Each variant maps to a CSS class that sets background color via design tokens (e.g. `var(--blue)` for info, `var(--green)` for success).
|
|
79
|
+
|
|
80
|
+
## Related Components / Links
|
|
81
|
+
|
|
82
|
+
- Table (often use Badge in column `customRender` for status or tag columns)
|
|
83
|
+
- Container (for layout when showing multiple badges)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# BottomSheet Component
|
|
2
|
+
|
|
3
|
+
Purpose: Slides up from the bottom of the screen. Use for additional content, forms, or actions without leaving the current context. Controlled by `isOpen` and `onClose`. Supports drag-to-close, snap points (30%, 60%, 90% of viewport), touch and mouse gestures, body scroll lock when open, and margin spacing.
|
|
4
|
+
|
|
5
|
+
## Props / Inputs
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Required | Default | Description |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| isOpen | boolean | yes | — | Whether the bottom sheet is open. |
|
|
10
|
+
| onClose | () => void | no | — | Called when the user drags to close (past threshold). |
|
|
11
|
+
| margin | string \| SpacingOption[] | no | — | Spacing suffix(s) for outer margin; component adds m- prefix. |
|
|
12
|
+
| className | string | no | "" | Additional class names for the sheet panel. |
|
|
13
|
+
| children | ReactNode | no | — | Content rendered inside the sheet. |
|
|
14
|
+
|
|
15
|
+
## Types
|
|
16
|
+
|
|
17
|
+
### BottomSheetMargin
|
|
18
|
+
```typescript
|
|
19
|
+
type BottomSheetMargin = string | SpacingOption[];
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### BottomSheetProps
|
|
23
|
+
```typescript
|
|
24
|
+
interface BottomSheetProps {
|
|
25
|
+
isOpen: boolean;
|
|
26
|
+
onClose?: () => void;
|
|
27
|
+
margin?: BottomSheetMargin;
|
|
28
|
+
className?: string;
|
|
29
|
+
children?: React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage Examples
|
|
34
|
+
|
|
35
|
+
### Basic
|
|
36
|
+
|
|
37
|
+
```jsx
|
|
38
|
+
import { useState } from "react";
|
|
39
|
+
import { BottomSheet, Button } from "cleanplate";
|
|
40
|
+
|
|
41
|
+
const App = () => {
|
|
42
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
43
|
+
return (
|
|
44
|
+
<>
|
|
45
|
+
<Button onClick={() => setIsOpen(true)}>Open</Button>
|
|
46
|
+
<BottomSheet isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
47
|
+
<p>Content here</p>
|
|
48
|
+
</BottomSheet>
|
|
49
|
+
</>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### With Container and Typography
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
<BottomSheet isOpen={isOpen} onClose={handleClose}>
|
|
58
|
+
<Container padding="4">
|
|
59
|
+
<Typography variant="h5" margin="m-0 m-b-2">Title</Typography>
|
|
60
|
+
<Typography variant="p">Body text</Typography>
|
|
61
|
+
</Container>
|
|
62
|
+
</BottomSheet>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Behavior Notes
|
|
66
|
+
|
|
67
|
+
- **isOpen / onClose:** Controlled visibility. `onClose` is called when the user drags past the close threshold.
|
|
68
|
+
- **Snap points:** Sheet snaps to 30%, 60%, or 90% of viewport height.
|
|
69
|
+
- **DOM:** Overlay div wrapping the sheet panel; handle area for drag; content area for children.
|
|
70
|
+
- **Body overflow:** Set to `hidden` when open, restored on close or unmount.
|
|
71
|
+
- **Margin:** Uses the suffix API (e.g. `"0"` → m-0).
|
|
72
|
+
|
|
73
|
+
## Related Components / Links
|
|
74
|
+
|
|
75
|
+
- Modal (full overlay dialog)
|
|
76
|
+
- ConfirmDialog (simple confirmation overlay)
|
|
77
|
+
- Button (commonly used to trigger opening)
|
|
78
|
+
- Container, Typography (layout and content inside the sheet)
|