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
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# BreadCrumb Component
|
|
2
|
+
|
|
3
|
+
Purpose: Renders a semantic navigation trail (e.g. Home → Products → Current page). Use it at the top of a page to show hierarchy and let users navigate back. The last item is treated as the current page when it has no `href`. Uses `<nav aria-label="Breadcrumb">` with an ordered list; includes Schema.org BreadcrumbList microdata for SEO.
|
|
4
|
+
|
|
5
|
+
## Props / Inputs
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Required | Default | Description |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| items | BreadCrumbItem[] | yes | — | List of breadcrumb items. Each has `label`; `href` is optional (omit for current page). |
|
|
10
|
+
| separator | "slash" \| "chevron" | no | "chevron" | Visual separator between items (chevron icon or "/"). |
|
|
11
|
+
| ariaLabel | string | no | "Breadcrumb" | Accessible label for the navigation landmark. |
|
|
12
|
+
| margin | string \| string[] | no | — | 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. |
|
|
13
|
+
| className | string | no | "" | Additional class name for the root nav element. |
|
|
14
|
+
|
|
15
|
+
## Types
|
|
16
|
+
|
|
17
|
+
### BreadCrumbItem
|
|
18
|
+
```typescript
|
|
19
|
+
interface BreadCrumbItem {
|
|
20
|
+
label: string; // Display label for the crumb
|
|
21
|
+
href?: string; // URL for the crumb; omit for the current page (typically last item)
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### BreadCrumbSeparator
|
|
26
|
+
```typescript
|
|
27
|
+
type BreadCrumbSeparator = "slash" | "chevron";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### SpacingOption
|
|
31
|
+
```typescript
|
|
32
|
+
type SpacingOption = (typeof SPACING_OPTIONS)[number];
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### BreadCrumbMargin
|
|
36
|
+
```typescript
|
|
37
|
+
type BreadCrumbMargin = string | SpacingOption[];
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### BreadCrumbProps
|
|
41
|
+
```typescript
|
|
42
|
+
interface BreadCrumbProps {
|
|
43
|
+
items: BreadCrumbItem[];
|
|
44
|
+
separator?: BreadCrumbSeparator;
|
|
45
|
+
ariaLabel?: string;
|
|
46
|
+
margin?: BreadCrumbMargin;
|
|
47
|
+
className?: string;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage Examples
|
|
52
|
+
|
|
53
|
+
### Basic
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
import { BreadCrumb } from "cleanplate";
|
|
57
|
+
|
|
58
|
+
const items = [
|
|
59
|
+
{ label: "Home", href: "/" },
|
|
60
|
+
{ label: "Products", href: "/products" },
|
|
61
|
+
{ label: "Current Product" },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
export const Example = () => <BreadCrumb items={items} />;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Slash separator
|
|
68
|
+
|
|
69
|
+
```jsx
|
|
70
|
+
import { BreadCrumb } from "cleanplate";
|
|
71
|
+
|
|
72
|
+
<BreadCrumb
|
|
73
|
+
items={[
|
|
74
|
+
{ label: "Home", href: "/" },
|
|
75
|
+
{ label: "Docs", href: "/docs" },
|
|
76
|
+
{ label: "Getting started" },
|
|
77
|
+
]}
|
|
78
|
+
separator="slash"
|
|
79
|
+
/>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Short trail
|
|
83
|
+
|
|
84
|
+
```jsx
|
|
85
|
+
<BreadCrumb
|
|
86
|
+
items={[
|
|
87
|
+
{ label: "Home", href: "/" },
|
|
88
|
+
{ label: "Current page" },
|
|
89
|
+
]}
|
|
90
|
+
/>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### With Container
|
|
94
|
+
|
|
95
|
+
```jsx
|
|
96
|
+
import { BreadCrumb, Container, Typography } from "cleanplate";
|
|
97
|
+
|
|
98
|
+
<Container padding="4">
|
|
99
|
+
<BreadCrumb
|
|
100
|
+
items={[
|
|
101
|
+
{ label: "Home", href: "/" },
|
|
102
|
+
{ label: "Products", href: "/products" },
|
|
103
|
+
{ label: "Current" },
|
|
104
|
+
]}
|
|
105
|
+
margin="b-2"
|
|
106
|
+
/>
|
|
107
|
+
<Typography variant="p">Page content below the breadcrumb.</Typography>
|
|
108
|
+
</Container>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Custom aria label
|
|
112
|
+
|
|
113
|
+
```jsx
|
|
114
|
+
<BreadCrumb
|
|
115
|
+
items={[{ label: "Home", href: "/" }, { label: "Here" }]}
|
|
116
|
+
ariaLabel="Page location"
|
|
117
|
+
/>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Behavior Notes
|
|
121
|
+
|
|
122
|
+
- **Current page:** The last item in `items` with no `href` is rendered as the current page (non-link) with `aria-current="page"`. Items without `href` elsewhere in the list are rendered as plain text.
|
|
123
|
+
- **Links:** Items with `href` are rendered as `<a href="...">` for navigation and accessibility.
|
|
124
|
+
- **Semantic markup:** Root is `<nav aria-label={ariaLabel}>` with `<ol>` and `<li>`. Schema.org `BreadcrumbList` and `ListItem` (itemScope, itemType, itemProp) are applied for SEO.
|
|
125
|
+
- **Separator:** Rendered with `aria-hidden="true"`. Chevron uses the Icon component (`chevron_right`); slash is the "/" character.
|
|
126
|
+
- **Spacing:** `margin` accepts the **spacing suffix**; the component adds the `m-` prefix via `getSpacingClass`.
|
|
127
|
+
|
|
128
|
+
## Related Components / Links
|
|
129
|
+
|
|
130
|
+
- Container (layout and spacing around the breadcrumb)
|
|
131
|
+
- Typography (page title or content below the breadcrumb)
|
|
132
|
+
- Icon (used internally for the chevron separator)
|
|
133
|
+
- Header (breadcrumbs are often placed inside or next to the header)
|
package/docs/Button.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Button Component
|
|
2
|
+
|
|
3
|
+
Purpose: A customizable action trigger for user interactions. Supports visual variants, size options, loading/disabled states, fluid layout, spacing utilities, and standard button behaviors.
|
|
4
|
+
|
|
5
|
+
## Props / Inputs
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Required | Default | Description |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| children | React.ReactNode | no | — | Content to display inside the button. |
|
|
10
|
+
| isLoading | boolean | no | false | Shows a loading spinner and disables the button. |
|
|
11
|
+
| isDisabled | boolean | no | false | Disables the button and prevents click events. |
|
|
12
|
+
| isFluid | boolean | no | false | Makes the button take full width of its container. |
|
|
13
|
+
| size | "small" \| "medium" | no | "medium" | Size variant of the button. |
|
|
14
|
+
| variant | "solid" \| "outline" \| "ghost" \| "icon" | no | "solid" | Visual style variant of the button (`icon` is a style variant, not an icon prop). |
|
|
15
|
+
| margin | string \| string[] | no | "m-0" | Spacing utility token(s), such as `m-0` or `["m-1", "m-b-2"]`. |
|
|
16
|
+
| onClick | function | no | — | Called with the click event when button is clicked. Prevents execution if `isDisabled` or `isLoading` is true. |
|
|
17
|
+
| className | string | no | "" | Additional class names for the root element. |
|
|
18
|
+
| type | "button" \| "submit" \| "reset" | no | "button" | HTML button type attribute. |
|
|
19
|
+
| ...rest | React.ButtonHTMLAttributes | no | — | All other standard HTML button attributes are supported. |
|
|
20
|
+
|
|
21
|
+
## Types
|
|
22
|
+
|
|
23
|
+
### ButtonSize
|
|
24
|
+
```typescript
|
|
25
|
+
type ButtonSize = "small" | "medium";
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### ButtonVariant
|
|
29
|
+
```typescript
|
|
30
|
+
type ButtonVariant = "solid" | "outline" | "ghost" | "icon";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### ButtonMargin
|
|
34
|
+
```typescript
|
|
35
|
+
type ButtonMargin = string | SpacingOption[];
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### SpacingOption
|
|
39
|
+
```typescript
|
|
40
|
+
type SpacingOption = typeof SPACING_OPTIONS[number];
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### ButtonProps
|
|
44
|
+
```typescript
|
|
45
|
+
interface ButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type" | "onClick"> {
|
|
46
|
+
children?: React.ReactNode;
|
|
47
|
+
isLoading?: boolean;
|
|
48
|
+
isDisabled?: boolean;
|
|
49
|
+
isFluid?: boolean;
|
|
50
|
+
size?: ButtonSize;
|
|
51
|
+
variant?: ButtonVariant;
|
|
52
|
+
margin?: ButtonMargin;
|
|
53
|
+
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
54
|
+
className?: string;
|
|
55
|
+
type?: "button" | "submit" | "reset";
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Usage Examples
|
|
60
|
+
|
|
61
|
+
### Basic button
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
import { Button } from "cleanplate";
|
|
65
|
+
|
|
66
|
+
export const Example = () => (
|
|
67
|
+
<Button onClick={() => console.log("Clicked")}>
|
|
68
|
+
Click me
|
|
69
|
+
</Button>
|
|
70
|
+
);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Variants
|
|
74
|
+
|
|
75
|
+
```jsx
|
|
76
|
+
import { Button } from "cleanplate";
|
|
77
|
+
|
|
78
|
+
export const Example = () => (
|
|
79
|
+
<>
|
|
80
|
+
<Button variant="solid">Solid</Button>
|
|
81
|
+
<Button variant="outline">Outline</Button>
|
|
82
|
+
<Button variant="ghost">Ghost</Button>
|
|
83
|
+
<Button variant="icon">Icon</Button>
|
|
84
|
+
</>
|
|
85
|
+
);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Icon variant (icon-only action)
|
|
89
|
+
|
|
90
|
+
```jsx
|
|
91
|
+
import { Button, Icon } from "cleanplate";
|
|
92
|
+
|
|
93
|
+
export const Example = () => (
|
|
94
|
+
<Button variant="icon" aria-label="Close dialog">
|
|
95
|
+
<Icon name="close" />
|
|
96
|
+
</Button>
|
|
97
|
+
);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Sizes
|
|
101
|
+
|
|
102
|
+
```jsx
|
|
103
|
+
import { Button } from "cleanplate";
|
|
104
|
+
|
|
105
|
+
export const Example = () => (
|
|
106
|
+
<>
|
|
107
|
+
<Button size="small">Small</Button>
|
|
108
|
+
<Button size="medium">Medium</Button>
|
|
109
|
+
</>
|
|
110
|
+
);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Loading state
|
|
114
|
+
|
|
115
|
+
```jsx
|
|
116
|
+
import { Button } from "cleanplate";
|
|
117
|
+
|
|
118
|
+
export const Example = () => (
|
|
119
|
+
<Button isLoading>
|
|
120
|
+
Loading...
|
|
121
|
+
</Button>
|
|
122
|
+
);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Disabled state
|
|
126
|
+
|
|
127
|
+
```jsx
|
|
128
|
+
import { Button } from "cleanplate";
|
|
129
|
+
|
|
130
|
+
export const Example = () => (
|
|
131
|
+
<Button isDisabled>
|
|
132
|
+
Disabled
|
|
133
|
+
</Button>
|
|
134
|
+
);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Fluid button
|
|
138
|
+
|
|
139
|
+
```jsx
|
|
140
|
+
import { Button } from "cleanplate";
|
|
141
|
+
|
|
142
|
+
export const Example = () => (
|
|
143
|
+
<Button isFluid>
|
|
144
|
+
Full Width Button
|
|
145
|
+
</Button>
|
|
146
|
+
);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### With margin spacing
|
|
150
|
+
|
|
151
|
+
```jsx
|
|
152
|
+
import { Button } from "cleanplate";
|
|
153
|
+
|
|
154
|
+
export const Example = () => (
|
|
155
|
+
<>
|
|
156
|
+
<Button margin="m-2">With margin</Button>
|
|
157
|
+
<Button margin={["m-1", "m-b-3"]}>With multiple margins</Button>
|
|
158
|
+
</>
|
|
159
|
+
);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Submit button
|
|
163
|
+
|
|
164
|
+
```jsx
|
|
165
|
+
import { Button } from "cleanplate";
|
|
166
|
+
|
|
167
|
+
export const Example = () => (
|
|
168
|
+
<form onSubmit={(e) => { e.preventDefault(); console.log("Submitted"); }}>
|
|
169
|
+
<Button type="submit">Submit</Button>
|
|
170
|
+
</form>
|
|
171
|
+
);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Behavior Notes
|
|
175
|
+
|
|
176
|
+
- When `isLoading` is true, an internal loading icon (`progress_activity`) is displayed and the button is automatically disabled.
|
|
177
|
+
- When `isDisabled` is true, click events are prevented and the button appears visually disabled.
|
|
178
|
+
- If both `isDisabled` and `isLoading` are true, the button is disabled and the loading icon is shown.
|
|
179
|
+
- The `onClick` handler is not called if the button is disabled or loading, even if the event is triggered.
|
|
180
|
+
- The button extends standard HTML button attributes, so you can use props like `aria-label`, `data-*`, etc.
|
|
181
|
+
- The `type` prop defaults to `"button"` to prevent accidental form submissions. Use `type="submit"` for form submission buttons.
|
|
182
|
+
- Margin spacing accepts either a single string token (e.g., `"m-2"`) or an array of tokens (e.g., `["m-1", "m-b-3"]`).
|
|
183
|
+
- `variant="icon"` is a visual style variant. For icon-only buttons, pass an accessible name using `aria-label`.
|
|
184
|
+
- In `size="medium"` + `variant="icon"`, styling uses compact horizontal padding and a 44px minimum width.
|
|
185
|
+
|
|
186
|
+
## Related Components / Links
|
|
187
|
+
|
|
188
|
+
- Icon (used internally for loading spinner)
|
|
189
|
+
- FormControls (often used alongside buttons in forms)
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# ConfirmDialog Component
|
|
2
|
+
|
|
3
|
+
Purpose: A modal dialog for confirmation actions (e.g. delete, discard, proceed). Shows a title, optional description, primary and secondary buttons, and optional close button. Use it for user confirmations, destructive actions, and warnings. Supports overlay click and Escape to close, body scroll lock when open, and focus management.
|
|
4
|
+
|
|
5
|
+
## Props / Inputs
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Required | Default | Description |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| isOpen | boolean | no | false | Whether the dialog is visible. |
|
|
10
|
+
| onClose | () => void | no | — | Called when the dialog should close (close button, overlay, Escape, or after primary/secondary click). |
|
|
11
|
+
| title | string | no | "Confirm Action" | Dialog title. |
|
|
12
|
+
| description | string | no | "" | Optional description below the title. |
|
|
13
|
+
| primaryButtonLabel | string | no | "Confirm" | Label for the primary (confirm) button. |
|
|
14
|
+
| onPrimaryButtonClick | () => void | no | — | Called when the primary button is clicked; onClose is also called. |
|
|
15
|
+
| secondaryButtonLabel | string | no | "Cancel" | Label for the secondary (cancel) button; empty string hides it. |
|
|
16
|
+
| onSecondaryButtonClick | () => void | no | — | Called when the secondary button is clicked; onClose is also called. |
|
|
17
|
+
| size | "small" \| "medium" \| "large" | no | "small" | Size of the dialog. |
|
|
18
|
+
| variant | "default" \| "destructive" \| "warning" | no | "default" | Visual variant. |
|
|
19
|
+
| showCloseButton | boolean | no | true | Whether to show the X close button. |
|
|
20
|
+
| closeOnOverlayClick | boolean | no | true | Whether clicking the overlay closes the dialog. |
|
|
21
|
+
| closeOnEscape | boolean | no | true | Whether pressing Escape closes the dialog. |
|
|
22
|
+
| className | string | no | "" | Additional class names for the dialog panel. |
|
|
23
|
+
| overlayClassName | string | no | "" | Additional class names for the overlay. |
|
|
24
|
+
|
|
25
|
+
## Types
|
|
26
|
+
|
|
27
|
+
### ConfirmDialogSize
|
|
28
|
+
```typescript
|
|
29
|
+
type ConfirmDialogSize = "small" | "medium" | "large";
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### ConfirmDialogVariant
|
|
33
|
+
```typescript
|
|
34
|
+
type ConfirmDialogVariant = "default" | "destructive" | "warning";
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### ConfirmDialogProps
|
|
38
|
+
```typescript
|
|
39
|
+
interface ConfirmDialogProps {
|
|
40
|
+
isOpen?: boolean;
|
|
41
|
+
onClose?: () => void;
|
|
42
|
+
title?: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
primaryButtonLabel?: string;
|
|
45
|
+
onPrimaryButtonClick?: () => void;
|
|
46
|
+
secondaryButtonLabel?: string;
|
|
47
|
+
onSecondaryButtonClick?: () => void;
|
|
48
|
+
size?: ConfirmDialogSize;
|
|
49
|
+
variant?: ConfirmDialogVariant;
|
|
50
|
+
showCloseButton?: boolean;
|
|
51
|
+
closeOnOverlayClick?: boolean;
|
|
52
|
+
closeOnEscape?: boolean;
|
|
53
|
+
className?: string;
|
|
54
|
+
overlayClassName?: string;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage Examples
|
|
59
|
+
|
|
60
|
+
### Basic
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
import { ConfirmDialog, Button } from "cleanplate";
|
|
64
|
+
import { useState } from "react";
|
|
65
|
+
|
|
66
|
+
const App = () => {
|
|
67
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
68
|
+
const handleConfirm = () => { /* ... */ setIsOpen(false); };
|
|
69
|
+
return (
|
|
70
|
+
<>
|
|
71
|
+
<Button onClick={() => setIsOpen(true)}>Delete</Button>
|
|
72
|
+
<ConfirmDialog
|
|
73
|
+
isOpen={isOpen}
|
|
74
|
+
onClose={() => setIsOpen(false)}
|
|
75
|
+
title="Delete Item"
|
|
76
|
+
description="Are you sure? This cannot be undone."
|
|
77
|
+
primaryButtonLabel="Delete"
|
|
78
|
+
onPrimaryButtonClick={handleConfirm}
|
|
79
|
+
secondaryButtonLabel="Cancel"
|
|
80
|
+
/>
|
|
81
|
+
</>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Variants
|
|
87
|
+
|
|
88
|
+
```jsx
|
|
89
|
+
<ConfirmDialog variant="default" title="Save?" ... />
|
|
90
|
+
<ConfirmDialog variant="destructive" title="Delete Account?" ... />
|
|
91
|
+
<ConfirmDialog variant="warning" title="Proceed Anyway?" ... />
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Sizes
|
|
95
|
+
|
|
96
|
+
```jsx
|
|
97
|
+
<ConfirmDialog size="small" title="Quick confirm" ... />
|
|
98
|
+
<ConfirmDialog size="medium" title="Standard confirm" ... />
|
|
99
|
+
<ConfirmDialog size="large" title="Important decision" ... />
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### No description, custom buttons
|
|
103
|
+
|
|
104
|
+
```jsx
|
|
105
|
+
<ConfirmDialog
|
|
106
|
+
isOpen={isOpen}
|
|
107
|
+
onClose={() => setIsOpen(false)}
|
|
108
|
+
title="Are you sure?"
|
|
109
|
+
primaryButtonLabel="Yes"
|
|
110
|
+
onPrimaryButtonClick={handleConfirm}
|
|
111
|
+
secondaryButtonLabel="No"
|
|
112
|
+
/>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Close behavior
|
|
116
|
+
|
|
117
|
+
```jsx
|
|
118
|
+
<ConfirmDialog
|
|
119
|
+
showCloseButton={true}
|
|
120
|
+
closeOnOverlayClick={true}
|
|
121
|
+
closeOnEscape={true}
|
|
122
|
+
onClose={handleClose}
|
|
123
|
+
...
|
|
124
|
+
/>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Behavior Notes
|
|
128
|
+
|
|
129
|
+
- **Rendering:** When `isOpen` is false, the component returns `null` (nothing in the DOM).
|
|
130
|
+
- **Close:** onClose is called when the user clicks the X button, the overlay (if closeOnOverlayClick), Escape (if closeOnEscape), or either action button (after their handler runs).
|
|
131
|
+
- **Body scroll:** When open, `document.body.style.overflow` is set to `"hidden"`; restored on close.
|
|
132
|
+
- **Focus:** On open, focus moves to the dialog panel (ref + tabIndex={-1}); on close, focus returns to the previously focused element.
|
|
133
|
+
- **ARIA:** The overlay has `role="dialog"`, `aria-modal="true"`, and `aria-labelledby` pointing to the title.
|
|
134
|
+
|
|
135
|
+
## Related Components / Links
|
|
136
|
+
|
|
137
|
+
- Button (used to open the dialog and for primary/secondary actions inside)
|
|
138
|
+
- Typography (used for title and description)
|
|
139
|
+
- Icon (used for the close button)
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Container Component
|
|
2
|
+
|
|
3
|
+
Purpose: A layout wrapper that controls display type, width, spacing (margin, padding, gap), and flex alignment. Use it to structure content, create flex layouts, and apply consistent spacing. Below the mobile breakpoint (600px), width variants collapse to full width for a responsive default. **Spacing (margin, padding, gap)** uses the **framework-wide suffix rule** (same for all CleanPlate components); see `llms.txt`.
|
|
4
|
+
|
|
5
|
+
## Props / Inputs
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Required | Default | Description |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| children | React.ReactNode | no | — | Content to render inside the container. |
|
|
10
|
+
| 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"`, `["1", "b-2"]`. |
|
|
11
|
+
| padding | string \| string[] | no | "p-4" | Spacing **suffix** for inner padding. The component adds the `p-` prefix (e.g. `"4"` → p-4, `"x-2"` → p-x-2). Use a single string or array: `"4"`, `["2", "x-4"]`. |
|
|
12
|
+
| display | "block" \| "flex" \| "inline-block" \| "" | no | "" | Layout mode. Use `"flex"` for flexbox; leave empty for no display class. |
|
|
13
|
+
| align | "start" \| "center" \| "end" \| "" | no | "" | Flex align-items. Only applies when `display="flex"`. |
|
|
14
|
+
| justify | "space-between" \| "center" \| "space-around" \| "space-evenly" \| "flex-end" \| "flex-start" \| "" | no | "" | Flex justify-content. Only applies when `display="flex"`. |
|
|
15
|
+
| width | "small" \| "medium" \| "large" \| "extra-large" \| "quarter" \| "half" \| "three-quarters" \| "full" \| "" | no | "" | Width variant. At viewports ≤600px, all variants become full width. |
|
|
16
|
+
| gap | string \| string[] | no | "4" | Spacing **suffix** for gap between flex children. The component adds the `g-` prefix (e.g. `"4"` → g-4). Meaningful when `display="flex"`. Use `"4"` or `["2", "3"]` for multiple. |
|
|
17
|
+
| showBorder | boolean | no | false | When true, shows a border around the container. |
|
|
18
|
+
| className | string | no | "" | Additional class names for the root element. |
|
|
19
|
+
| onClick | function | no | — | Click handler for the root div. |
|
|
20
|
+
| style | React.CSSProperties | no | — | Inline styles for the root element. |
|
|
21
|
+
| ...rest | React.HTMLAttributes<HTMLDivElement> | no | — | Any other div attributes (e.g. `id`, `data-*`, `aria-*`) are forwarded. |
|
|
22
|
+
|
|
23
|
+
## Types
|
|
24
|
+
|
|
25
|
+
### SpacingOption
|
|
26
|
+
```typescript
|
|
27
|
+
type SpacingOption = (typeof SPACING_OPTIONS)[number];
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### ContainerDisplay
|
|
31
|
+
```typescript
|
|
32
|
+
type ContainerDisplay = "inline-block" | "block" | "flex";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### ContainerWidth
|
|
36
|
+
```typescript
|
|
37
|
+
type ContainerWidth =
|
|
38
|
+
| "small"
|
|
39
|
+
| "medium"
|
|
40
|
+
| "large"
|
|
41
|
+
| "extra-large"
|
|
42
|
+
| "quarter"
|
|
43
|
+
| "half"
|
|
44
|
+
| "three-quarters"
|
|
45
|
+
| "full";
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### ContainerJustify
|
|
49
|
+
```typescript
|
|
50
|
+
type ContainerJustify =
|
|
51
|
+
| "space-between"
|
|
52
|
+
| "center"
|
|
53
|
+
| "space-around"
|
|
54
|
+
| "space-evenly"
|
|
55
|
+
| "flex-end"
|
|
56
|
+
| "flex-start";
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### ContainerAlign
|
|
60
|
+
```typescript
|
|
61
|
+
type ContainerAlign = "start" | "center" | "end";
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### ContainerSpacing
|
|
65
|
+
```typescript
|
|
66
|
+
type ContainerSpacing = string | SpacingOption[];
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### ContainerProps
|
|
70
|
+
```typescript
|
|
71
|
+
interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
72
|
+
children?: React.ReactNode;
|
|
73
|
+
margin?: ContainerSpacing;
|
|
74
|
+
padding?: ContainerSpacing;
|
|
75
|
+
display?: ContainerDisplay | "";
|
|
76
|
+
align?: ContainerAlign | "";
|
|
77
|
+
justify?: ContainerJustify | "";
|
|
78
|
+
width?: ContainerWidth | "";
|
|
79
|
+
showBorder?: boolean;
|
|
80
|
+
className?: string;
|
|
81
|
+
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
82
|
+
style?: React.CSSProperties;
|
|
83
|
+
gap?: ContainerSpacing;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Usage Examples
|
|
88
|
+
|
|
89
|
+
### Block container
|
|
90
|
+
|
|
91
|
+
```jsx
|
|
92
|
+
import { Container } from "cleanplate";
|
|
93
|
+
|
|
94
|
+
export const Example = () => (
|
|
95
|
+
<Container display="block" padding="4" showBorder>
|
|
96
|
+
<p>Block container: full width, content stacks vertically.</p>
|
|
97
|
+
</Container>
|
|
98
|
+
);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Flex container with alignment
|
|
102
|
+
|
|
103
|
+
```jsx
|
|
104
|
+
import { Container } from "cleanplate";
|
|
105
|
+
import { Button } from "cleanplate";
|
|
106
|
+
|
|
107
|
+
export const Example = () => (
|
|
108
|
+
<Container
|
|
109
|
+
display="flex"
|
|
110
|
+
justify="space-between"
|
|
111
|
+
align="center"
|
|
112
|
+
padding="3"
|
|
113
|
+
gap="2"
|
|
114
|
+
showBorder
|
|
115
|
+
>
|
|
116
|
+
<span>Left</span>
|
|
117
|
+
<Button size="small">Action</Button>
|
|
118
|
+
</Container>
|
|
119
|
+
);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Width variants
|
|
123
|
+
|
|
124
|
+
```jsx
|
|
125
|
+
import { Container } from "cleanplate";
|
|
126
|
+
|
|
127
|
+
export const Example = () => (
|
|
128
|
+
<>
|
|
129
|
+
<Container width="small" showBorder padding="3">Small</Container>
|
|
130
|
+
<Container width="medium" showBorder padding="3">Medium</Container>
|
|
131
|
+
<Container width="half" showBorder padding="3">Half</Container>
|
|
132
|
+
<Container width="full" showBorder padding="3">Full</Container>
|
|
133
|
+
</>
|
|
134
|
+
);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Inline-block (side by side)
|
|
138
|
+
|
|
139
|
+
```jsx
|
|
140
|
+
import { Container } from "cleanplate";
|
|
141
|
+
|
|
142
|
+
export const Example = () => (
|
|
143
|
+
<Container display="inline-block" showBorder padding="2" margin="r-2">
|
|
144
|
+
Block 1
|
|
145
|
+
</Container>
|
|
146
|
+
<Container display="inline-block" showBorder padding="2">
|
|
147
|
+
Block 2
|
|
148
|
+
</Container>
|
|
149
|
+
);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Margin and padding
|
|
153
|
+
|
|
154
|
+
```jsx
|
|
155
|
+
import { Container } from "cleanplate";
|
|
156
|
+
|
|
157
|
+
export const Example = () => (
|
|
158
|
+
<>
|
|
159
|
+
<Container margin="2" padding="4" showBorder>
|
|
160
|
+
Single suffix values
|
|
161
|
+
</Container>
|
|
162
|
+
<Container margin={["1", "b-3"]} padding={["2", "x-4"]} showBorder>
|
|
163
|
+
Multiple suffixes (component adds m- / p- prefix)
|
|
164
|
+
</Container>
|
|
165
|
+
</>
|
|
166
|
+
);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Flex grid (quarters)
|
|
170
|
+
|
|
171
|
+
```jsx
|
|
172
|
+
import { Container } from "cleanplate";
|
|
173
|
+
|
|
174
|
+
export const Example = () => (
|
|
175
|
+
<Container display="flex" padding="2" gap="2" showBorder>
|
|
176
|
+
<Container width="quarter" showBorder padding="3">1</Container>
|
|
177
|
+
<Container width="quarter" showBorder padding="3">2</Container>
|
|
178
|
+
<Container width="quarter" showBorder padding="3">3</Container>
|
|
179
|
+
<Container width="quarter" showBorder padding="3">4</Container>
|
|
180
|
+
</Container>
|
|
181
|
+
);
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Clickable container
|
|
185
|
+
|
|
186
|
+
```jsx
|
|
187
|
+
import { Container } from "cleanplate";
|
|
188
|
+
|
|
189
|
+
export const Example = () => (
|
|
190
|
+
<Container
|
|
191
|
+
showBorder
|
|
192
|
+
padding="4"
|
|
193
|
+
onClick={() => console.log("Clicked")}
|
|
194
|
+
>
|
|
195
|
+
Clickable area
|
|
196
|
+
</Container>
|
|
197
|
+
);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### With custom class and style
|
|
201
|
+
|
|
202
|
+
```jsx
|
|
203
|
+
import { Container } from "cleanplate";
|
|
204
|
+
|
|
205
|
+
export const Example = () => (
|
|
206
|
+
<Container
|
|
207
|
+
className="my-wrapper"
|
|
208
|
+
style={{ minHeight: 200 }}
|
|
209
|
+
padding="4"
|
|
210
|
+
showBorder
|
|
211
|
+
>
|
|
212
|
+
Custom wrapper
|
|
213
|
+
</Container>
|
|
214
|
+
);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Behavior Notes
|
|
218
|
+
|
|
219
|
+
- **Responsive width:** For viewport width ≤600px (mobile breakpoint), all `width` variants are overridden to `100%` in CSS. No prop change is required.
|
|
220
|
+
- **Flex:** When `display="flex"`, the root uses `display: flex` and `flex-wrap: wrap`. Use `align` and `justify` to control alignment; use `gap` for spacing between children.
|
|
221
|
+
- **Spacing:** `margin`, `padding`, and `gap` accept the **spacing suffix** (the component adds the `m-`, `p-`, or `g-` prefix via `getSpacingClass`). Use a single string (e.g. `"4"`, `"0"`, `"b-2"`) or an array of suffixes (e.g. `["1", "b-2"]`). Valid suffixes include `"0"`–`"9"`, `"auto"`, and directional forms like `"x-2"`, `"y-3"`, `"t-0"`, `"r-1"`, `"b-2"`, `"l-3"` (see `SPACING_OPTIONS`). **Note:** The component’s default props are currently `"m-0"` and `"p-4"` (full tokens); internally the util expects suffixes, so when passing values explicitly use suffix form (e.g. `"0"`, `"4"`).
|
|
222
|
+
- **Empty layout props:** Passing `""` or omitting `display`, `align`, `justify`, or `width` means no corresponding class is applied.
|
|
223
|
+
- **Border:** `showBorder` only affects border visibility; the container always reserves border space (border is 1px solid, transparent when not shown).
|
|
224
|
+
- The root element is a `div`; all standard HTML div attributes and ref are supported via `...rest`.
|
|
225
|
+
|
|
226
|
+
## Related Components / Links
|
|
227
|
+
|
|
228
|
+
- Typography (often used inside Container for text)
|
|
229
|
+
- Button (commonly placed inside flex Containers)
|
|
230
|
+
- MediaObject (often wrapped in Container for layout)
|