cleanplate 0.2.0 → 0.2.2

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/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)
@@ -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)