cleanplate 0.3.27 → 0.3.29

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.
@@ -0,0 +1,2 @@
1
+ export declare function useMediaQuery(matchesQuery: string): boolean;
2
+ //# sourceMappingURL=use-media-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-query.d.ts","sourceRoot":"","sources":["../../src/utils/use-media-query.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CA4B3D"}
package/docs/Drawer.md ADDED
@@ -0,0 +1,194 @@
1
+ # Drawer Component
2
+
3
+ Purpose: A slide-in overlay panel for navigation, filters, settings, or detail views. On desktop (≥768px), slides from a configurable edge (`left`, `right`, `top`, or `bottom`). Below 768px, always renders as a bottom sheet (max height 90dvh). Includes fade/slide transitions, focus management, and Modal-like optional chrome (title, close button, footer actions).
4
+
5
+ ## Props / Inputs
6
+
7
+ | Prop | Type | Required | Default | Description |
8
+ | --- | --- | --- | --- | --- |
9
+ | children | React.ReactNode | yes | — | Drawer body content. |
10
+ | isOpen | boolean | no | false | Whether the drawer is visible. |
11
+ | onClose | () => void | no | — | Called when the drawer should close (close button, overlay, or Escape). |
12
+ | placement | "left" \| "right" \| "top" \| "bottom" | no | "right" | Edge the drawer slides from on desktop; ignored on mobile (always bottom sheet). |
13
+ | size | "small" \| "medium" \| "large" \| "full" | no | "medium" | Panel size preset (width for side drawers, height for top/bottom). |
14
+ | title | string | no | "" | Title displayed in the drawer header. |
15
+ | showCloseButton | boolean | no | true | Whether to show the X close button in the header. |
16
+ | closeOnOverlayClick | boolean | no | true | Whether clicking the overlay closes the drawer. |
17
+ | closeOnEscape | boolean | no | true | Whether pressing Escape closes the drawer. |
18
+ | margin | string \| SpacingOption[] | no | "0" | Margin spacing (suffix or array of suffixes; component adds `m-` prefix). |
19
+ | className | string | no | "" | Additional class names for the drawer panel. |
20
+ | overlayClassName | string | no | "" | Additional class names for the overlay. |
21
+ | contentClassName | string | no | "" | Additional class names for the content wrapper. |
22
+ | headerClassName | string | no | "" | Additional class names for the header row. |
23
+ | bodyClassName | string | no | "" | Additional class names for the body region. |
24
+ | footerClassName | string | no | "" | Additional class names for the footer row. |
25
+ | ariaLabel | string | no | — | Accessible name when no `title` is provided. Required for a11y when `title` is omitted. |
26
+ | primaryButtonLabel | string | no | "" | Label for the primary footer button; empty hides it. |
27
+ | onPrimaryButtonClick | () => void | no | — | Called when the primary footer button is clicked. |
28
+ | secondaryButtonLabel | string | no | "" | Label for the secondary footer button; empty hides it. |
29
+ | onSecondaryButtonClick | () => void | no | — | Called when the secondary footer button is clicked. |
30
+ | dataTestId | string | no | — | Root `data-testid` on the dialog panel; suffixed ids on overlay, header, title, close, body, footer, and action buttons (see **E2E / test selectors**). |
31
+
32
+ ## Types
33
+
34
+ ### SpacingOption
35
+ ```typescript
36
+ type SpacingOption = (typeof SPACING_OPTIONS)[number];
37
+ ```
38
+
39
+ ### DrawerPlacement
40
+ ```typescript
41
+ type DrawerPlacement = "left" | "right" | "top" | "bottom";
42
+ ```
43
+
44
+ ### DrawerSize
45
+ ```typescript
46
+ type DrawerSize = "small" | "medium" | "large" | "full";
47
+ ```
48
+
49
+ ### DrawerMargin
50
+ ```typescript
51
+ type DrawerMargin = string | SpacingOption[];
52
+ ```
53
+
54
+ ### DrawerProps
55
+ ```typescript
56
+ interface DrawerProps {
57
+ children: React.ReactNode;
58
+ isOpen?: boolean;
59
+ onClose?: () => void;
60
+ placement?: DrawerPlacement;
61
+ size?: DrawerSize;
62
+ title?: string;
63
+ showCloseButton?: boolean;
64
+ closeOnOverlayClick?: boolean;
65
+ closeOnEscape?: boolean;
66
+ margin?: DrawerMargin;
67
+ className?: string;
68
+ overlayClassName?: string;
69
+ contentClassName?: string;
70
+ headerClassName?: string;
71
+ bodyClassName?: string;
72
+ footerClassName?: string;
73
+ ariaLabel?: string;
74
+ primaryButtonLabel?: string;
75
+ onPrimaryButtonClick?: () => void;
76
+ secondaryButtonLabel?: string;
77
+ onSecondaryButtonClick?: () => void;
78
+ dataTestId?: string;
79
+ }
80
+ ```
81
+
82
+ ## E2E / test selectors
83
+
84
+ Pass `dataTestId="filters-drawer"` to get stable Playwright / Testing Library hooks:
85
+
86
+ | Suffix | Element |
87
+ | --- | --- |
88
+ | *(root)* | Dialog panel (`role="dialog"`) |
89
+ | `-overlay` | Backdrop overlay |
90
+ | `-header` | Header row (title + close button) |
91
+ | `-title` | Title text |
92
+ | `-close` | Header close (X) button |
93
+ | `-body` | Main content area |
94
+ | `-footer` | Footer action row |
95
+ | `-primary` | Primary footer button |
96
+ | `-secondary` | Secondary footer button |
97
+
98
+ Header, title, close, footer, and button suffixes are omitted when those regions are not rendered.
99
+
100
+ ### Playwright example
101
+
102
+ ```ts
103
+ await page.getByRole("button", { name: "Open filters" }).click();
104
+ await expect(page.getByTestId("filters-drawer")).toBeVisible();
105
+ await page.getByTestId("filters-drawer-body").getByLabel("Category").selectOption("books");
106
+ await page.getByTestId("filters-drawer-primary").click();
107
+ await expect(page.getByTestId("filters-drawer")).toBeHidden();
108
+ ```
109
+
110
+ ## Usage Examples
111
+
112
+ ### Basic
113
+
114
+ ```jsx
115
+ import { Drawer, Button, Typography } from "cleanplate";
116
+ import { useState } from "react";
117
+
118
+ const App = () => {
119
+ const [isOpen, setIsOpen] = useState(false);
120
+ return (
121
+ <>
122
+ <Button onClick={() => setIsOpen(true)}>Open Drawer</Button>
123
+ <Drawer
124
+ isOpen={isOpen}
125
+ onClose={() => setIsOpen(false)}
126
+ title="Filters"
127
+ placement="right"
128
+ >
129
+ <Typography variant="p">Filter options go here.</Typography>
130
+ </Drawer>
131
+ </>
132
+ );
133
+ };
134
+ ```
135
+
136
+ ### Placements (desktop)
137
+
138
+ ```jsx
139
+ <Drawer placement="left" title="Navigation" isOpen={isOpen} onClose={onClose}>...</Drawer>
140
+ <Drawer placement="right" title="Details" isOpen={isOpen} onClose={onClose}>...</Drawer>
141
+ <Drawer placement="top" title="Announcements" isOpen={isOpen} onClose={onClose}>...</Drawer>
142
+ <Drawer placement="bottom" title="Actions" isOpen={isOpen} onClose={onClose}>...</Drawer>
143
+ ```
144
+
145
+ ### With footer buttons
146
+
147
+ ```jsx
148
+ <Drawer
149
+ isOpen={isOpen}
150
+ onClose={() => setIsOpen(false)}
151
+ title="Apply Filters"
152
+ primaryButtonLabel="Apply"
153
+ onPrimaryButtonClick={handleApply}
154
+ secondaryButtonLabel="Reset"
155
+ onSecondaryButtonClick={handleReset}
156
+ >
157
+ <Typography variant="p">Choose filter criteria.</Typography>
158
+ </Drawer>
159
+ ```
160
+
161
+ ### Custom class names
162
+
163
+ ```jsx
164
+ <Drawer
165
+ isOpen={isOpen}
166
+ onClose={onClose}
167
+ title="Settings"
168
+ className="my-drawer-panel"
169
+ overlayClassName="my-drawer-overlay"
170
+ bodyClassName="my-drawer-body"
171
+ dataTestId="settings-drawer"
172
+ >
173
+ ...
174
+ </Drawer>
175
+ ```
176
+
177
+ ## Behavior Notes
178
+
179
+ - **Desktop (≥768px):** Panel slides from the configured `placement` edge with subtle opacity fade. Side drawers use full viewport height; top/bottom drawers use full viewport width.
180
+ - **Mobile (<768px):** Always renders as a bottom sheet regardless of `placement`. Max height is **90dvh** with rounded top corners and safe-area padding at the bottom.
181
+ - **Rendering:** Mounts when `isOpen` is true and stays mounted briefly after close so the exit transition can finish.
182
+ - **Close:** `onClose` is called when the user clicks the X button (if `showCloseButton`), the overlay (if `closeOnOverlayClick`), or Escape (if `closeOnEscape`). Footer buttons do not auto-close; call `onClose` in their handlers if desired.
183
+ - **Body scroll:** Locked while open and restored on close.
184
+ - **Focus:** Trapped while open; returned to the previously focused element on close.
185
+ - **ARIA:** `role="dialog"`, `aria-modal="true"`, `aria-labelledby` when `title` is present, or `aria-label` via `ariaLabel`. Provide **`title` or `ariaLabel`** — a dev warning is logged when the drawer opens without either.
186
+ - **Spacing:** `margin` uses the suffix API (e.g. `"0"`, `"b-2"`); component adds `m-` prefix.
187
+
188
+ ## Related Components / Links
189
+
190
+ - Modal (centered overlay dialog)
191
+ - BottomSheet (drag gestures and snap points from bottom only)
192
+ - ConfirmDialog (simple confirmation overlay)
193
+ - Button (open trigger and footer actions)
194
+ - Typography (title and body content)
package/llms.txt CHANGED
@@ -151,6 +151,13 @@ All component documentation is located in the `docs/` folder. The following docu
151
151
  - Types: ModalProps, ModalSize, ModalMargin, SpacingOption
152
152
  - Related Components: ConfirmDialog (simpler confirm-only), Button, Typography, Icon (used internally)
153
153
 
154
+ ### Drawer Component
155
+ - File: `docs/Drawer.md`
156
+ - Purpose: Slide-in overlay panel from a configurable edge (left, right, top, bottom) on desktop; below 768px always renders as a bottom sheet (max 90dvh). Optional title, close button, footer actions; fade/slide transitions, focus trap, scroll lock.
157
+ - Key Features: placement (left, right, top, bottom), size (small, medium, large, full), showCloseButton, closeOnOverlayClick, closeOnEscape, margin (suffix API), className/overlayClassName/contentClassName/headerClassName/bodyClassName/footerClassName, dataTestId with suffixed E2E hooks, ariaLabel
158
+ - Types: DrawerProps, DrawerPlacement, DrawerSize, DrawerMargin, SpacingOption
159
+ - Related Components: Modal (centered dialog), BottomSheet (drag/snap from bottom), Button, Typography, Icon (used internally)
160
+
154
161
  ### Pagination Component
155
162
  - File: `docs/Pagination.md`
156
163
  - Purpose: Navigate large content sets by pages. Shows total count, prev/next and page-number buttons with ellipsis, and optional rows-per-page select. Controlled via currentPage and rowsPerPage.
@@ -273,6 +280,7 @@ All documentation files follow a consistent format:
273
280
  | Accordion | `docs/Accordion.md` | Collapsible panels and FAQ sections |
274
281
  | ConfirmDialog | `docs/ConfirmDialog.md` | Confirmation modals and destructive actions |
275
282
  | Modal | `docs/Modal.md` | Forms, long content, and custom dialogs |
283
+ | Drawer | `docs/Drawer.md` | Edge slide-in panel; bottom sheet on mobile |
276
284
  | Pagination | `docs/Pagination.md` | Page navigation for tables and lists |
277
285
  | Table | `docs/Table.md` | Structured tabular data with optional pagination and mobile view |
278
286
  | Badge | `docs/Badge.md` | Status labels, tags, and counts with colored variants |
@@ -304,5 +312,5 @@ npm install cleanplate
304
312
  ## Usage
305
313
 
306
314
  ```jsx
307
- import { Button, Typography, Icon, MediaObject, Avatar, Container, Dropdown, Alert, FeedbackState, Spinner, Stepper, BreadCrumb, Accordion, ConfirmDialog, Modal, Pagination, Table, Badge, Pills, Animated, FormControls, Toast, MenuList, Header, PageHeader, BottomSheet, Footer, AppShell } from "cleanplate";
315
+ import { Button, Typography, Icon, MediaObject, Avatar, Container, Dropdown, Alert, FeedbackState, Spinner, Stepper, BreadCrumb, Accordion, ConfirmDialog, Modal, Drawer, Pagination, Table, Badge, Pills, Animated, FormControls, Toast, MenuList, Header, PageHeader, BottomSheet, Footer, AppShell } from "cleanplate";
308
316
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cleanplate",
3
- "version": "0.3.27",
3
+ "version": "0.3.29",
4
4
  "description": "CleanPlate - A Headless React UI Framework",
5
5
  "files": [
6
6
  "dist",