@dismissible/react-client 0.0.1-canary.10

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 ADDED
@@ -0,0 +1,435 @@
1
+ # @dismissible/react-client
2
+
3
+ A React component library for creating dismissible UI elements with persistent state management.
4
+
5
+ [![npm version](https://badge.fury.io/js/@dismissible%2Freact-client.svg)](https://badge.fury.io/js/@dismissible%2Freact-client)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - 🎯 **Easy to use** - Simple component API for dismissible content
11
+ - 💾 **Persistent state** - Dismissal state is saved and restored across sessions
12
+ - 🎨 **Customizable** - Custom loading, error, and dismiss button components
13
+ - ♿ **Accessible** - Built with accessibility best practices
14
+ - 🪝 **Hook-based** - Includes `useDismissibleItem` hook for custom implementations
15
+ - 📦 **Lightweight** - Minimal bundle size with tree-shaking support
16
+ - 🔧 **TypeScript** - Full TypeScript support with complete type definitions
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @dismissible/react-client
22
+ ```
23
+
24
+ ### Peer Dependencies
25
+
26
+ Make sure you have React 18+ installed:
27
+
28
+ ```bash
29
+ npm install react react-dom
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```tsx
35
+ import React from 'react';
36
+ import { Dismissible } from '@dismissible/react-client';
37
+
38
+ function App() {
39
+ return (
40
+ <Dismissible id="welcome-banner-123-413-31-1">
41
+ <div className="banner">
42
+ <h2>Welcome to our app!</h2>
43
+ <p>This banner can be dismissed and won't show again.</p>
44
+ </div>
45
+ </Dismissible>
46
+ );
47
+ }
48
+ ```
49
+
50
+ ## API Reference
51
+
52
+ ### `<Dismissible>` Component
53
+
54
+ The main component for creating dismissible content.
55
+
56
+ #### Props
57
+
58
+ | Prop | Type | Required | Description |
59
+ |------|------|----------|-------------|
60
+ | `id` | `string` | ✅ | Unique identifier for the dismissible item |
61
+ | `children` | `ReactNode` | ✅ | Content to render when not dismissed |
62
+ | `onDismiss` | `() => void` | ❌ | Callback fired when item is dismissed |
63
+ | `LoadingComponent` | `ComponentType<{id: string}>` | ❌ | Custom loading component |
64
+ | `ErrorComponent` | `ComponentType<{id: string, error: Error}>` | ❌ | Custom error component |
65
+ | `DismissButtonComponent` | `ComponentType<{id: string, onDismiss: () => Promise<void>, ariaLabel: string}>` | ❌ | Custom dismiss button |
66
+
67
+ #### Example
68
+
69
+ ```tsx
70
+ <Dismissible
71
+ id="promo-banner"
72
+ onDismiss={() => console.log('Banner dismissed')}
73
+ onRestore={() => console.log('Banner restored')}
74
+ >
75
+ <div className="promo">
76
+ <h3>Special Offer!</h3>
77
+ <p>Get 50% off your first order</p>
78
+ </div>
79
+ </Dismissible>
80
+ ```
81
+
82
+ ### `useDismissibleItem` Hook
83
+
84
+ For custom implementations and advanced use cases.
85
+
86
+ #### Parameters
87
+
88
+ | Parameter | Type | Required | Description |
89
+ |-----------|------|----------|-------------|
90
+ | `id` | `string` | ✅ | Unique identifier for the dismissible item |
91
+
92
+ #### Returns
93
+
94
+ | Property | Type | Description |
95
+ |----------|------|-------------|
96
+ | `dismissedOn` | `string \| null` | ISO date string when item was dismissed, or null |
97
+ | `dismiss` | `() => Promise<void>` | Function to dismiss the item |
98
+ | `isLoading` | `boolean` | Loading state indicator |
99
+ | `error` | `Error \| null` | Error state, if any |
100
+
101
+ #### Example
102
+
103
+ ```tsx
104
+ import { useDismissibleItem } from '@dismissible/react-client';
105
+
106
+ function CustomDismissible({ id, children }) {
107
+ const { dismissedOn, dismiss, isLoading, error } = useDismissibleItem(id);
108
+
109
+ if (dismissedOn) {
110
+ return null; // Item is dismissed
111
+ }
112
+
113
+ if (isLoading) {
114
+ return <div>Loading...</div>;
115
+ }
116
+
117
+ if (error) {
118
+ return <div>Error: {error.message}</div>;
119
+ }
120
+
121
+ return (
122
+ <div>
123
+ {children}
124
+ <button onClick={dismiss}>
125
+ Dismiss
126
+ </button>
127
+ </div>
128
+ );
129
+ }
130
+ ```
131
+
132
+ ## Usage Examples
133
+
134
+ ### Basic Dismissible Banner
135
+
136
+ ```tsx
137
+ import { Dismissible } from '@dismissible/react-client';
138
+
139
+ function WelcomeBanner() {
140
+ return (
141
+ <Dismissible id="welcome-banner-234-432-432-1">
142
+ <div className="alert alert-info">
143
+ <h4>Welcome!</h4>
144
+ <p>Thanks for joining our platform. Here are some quick tips to get started.</p>
145
+ </div>
146
+ </Dismissible>
147
+ );
148
+ }
149
+ ```
150
+
151
+ ### Custom Dismiss Button
152
+
153
+ ```tsx
154
+ import { Dismissible } from '@dismissible/react-client';
155
+
156
+ const CustomDismissButton = ({ onDismiss, ariaLabel }) => (
157
+ <button
158
+ onClick={onDismiss}
159
+ className="custom-close-btn"
160
+ aria-label={ariaLabel}
161
+ >
162
+
163
+ </button>
164
+ );
165
+
166
+ function CustomBanner() {
167
+ return (
168
+ <Dismissible
169
+ id="custom-banner"
170
+ DismissButtonComponent={CustomDismissButton}
171
+ >
172
+ <div className="banner">
173
+ <p>This banner has a custom dismiss button!</p>
174
+ </div>
175
+ </Dismissible>
176
+ );
177
+ }
178
+ ```
179
+
180
+ ### Custom Loading and Error Components
181
+
182
+ ```tsx
183
+ import { Dismissible } from '@dismissible/react-client';
184
+
185
+ const CustomLoader = ({ id }) => (
186
+ <div className="spinner">
187
+ <div className="bounce1"></div>
188
+ <div className="bounce2"></div>
189
+ <div className="bounce3"></div>
190
+ </div>
191
+ );
192
+
193
+ const CustomError = ({ error }) => (
194
+ <div className="error-card">
195
+ <h4>Oops! Something went wrong</h4>
196
+ <p>{error.message}</p>
197
+ <button onClick={() => window.location.reload()}>
198
+ Try Again
199
+ </button>
200
+ </div>
201
+ );
202
+
203
+ function AdvancedBanner() {
204
+ return (
205
+ <Dismissible
206
+ id="advanced-banner"
207
+ LoadingComponent={CustomLoader}
208
+ ErrorComponent={CustomError}
209
+ >
210
+ <div className="banner">
211
+ <p>This banner has custom loading and error states!</p>
212
+ </div>
213
+ </Dismissible>
214
+ );
215
+ }
216
+ ```
217
+
218
+ ### Multiple Dismissible Items
219
+
220
+ ```tsx
221
+ import { Dismissible } from '@dismissible/react-client';
222
+
223
+ function Dashboard() {
224
+ return (
225
+ <div>
226
+ <Dismissible id="feature-announcement-234-432-432-1">
227
+ <div className="alert alert-success">
228
+ 🎉 New feature: Dark mode is now available!
229
+ </div>
230
+ </Dismissible>
231
+
232
+ <Dismissible id="maintenance-notice-234-432-432-1">
233
+ <div className="alert alert-warning">
234
+ ⚠️ Scheduled maintenance: Sunday 2AM-4AM EST
235
+ </div>
236
+ </Dismissible>
237
+
238
+ <Dismissible id="survey-request-234-432-432-1">
239
+ <div className="alert alert-info">
240
+ 📝 Help us improve! Take our 2-minute survey.
241
+ </div>
242
+ </Dismissible>
243
+ </div>
244
+ );
245
+ }
246
+ ```
247
+
248
+ ### Conditional Dismissible Content
249
+
250
+ ```tsx
251
+ import { Dismissible } from '@dismissible/react-client';
252
+
253
+ function ConditionalBanner({ user }) {
254
+ // Only show to new users
255
+ if (user.isReturning) {
256
+ return null;
257
+ }
258
+
259
+ return (
260
+ <Dismissible id={`onboarding-${user.id}`}>
261
+ <div className="onboarding-tips">
262
+ <h3>Getting Started</h3>
263
+ <ul>
264
+ <li>Complete your profile</li>
265
+ <li>Connect with friends</li>
266
+ <li>Explore our features</li>
267
+ </ul>
268
+ </div>
269
+ </Dismissible>
270
+ );
271
+ }
272
+ ```
273
+
274
+ ### Using the Hook for Complex Logic
275
+
276
+ ```tsx
277
+ import { useDismissibleItem } from '@dismissible/react-client';
278
+ import { useState, useEffect } from 'react';
279
+
280
+ function SmartNotification({ id, message, type = 'info' }) {
281
+ const { dismissedOn, dismiss, isLoading } = useDismissibleItem(id);
282
+ const [autoHide, setAutoHide] = useState(false);
283
+
284
+ // Auto-hide after 10 seconds for info messages
285
+ useEffect(() => {
286
+ if (type === 'info' && !dismissedOn) {
287
+ const timer = setTimeout(() => {
288
+ setAutoHide(true);
289
+ dismiss();
290
+ }, 10000);
291
+
292
+ return () => clearTimeout(timer);
293
+ }
294
+ }, [type, dismissedOn, dismiss]);
295
+
296
+ if (dismissedOn || autoHide) {
297
+ return null;
298
+ }
299
+
300
+ return (
301
+ <div className={`notification notification-${type}`}>
302
+ <span>{message}</span>
303
+ <button
304
+ onClick={dismiss}
305
+ disabled={isLoading}
306
+ className="dismiss-btn"
307
+ >
308
+ {isLoading ? '...' : '×'}
309
+ </button>
310
+ </div>
311
+ );
312
+ }
313
+ ```
314
+
315
+ ## Styling
316
+
317
+ The library includes minimal default styles. You can override them or provide your own:
318
+
319
+ ```css
320
+ /* Default classes you can style */
321
+ .dismissible-container {
322
+ /* Container for the dismissible content */
323
+ }
324
+
325
+ .dismissible-loading {
326
+ /* Loading state */
327
+ }
328
+
329
+ .dismissible-error {
330
+ /* Error state */
331
+ }
332
+
333
+ .dismissible-dismiss-btn {
334
+ /* Default dismiss button */
335
+ }
336
+ ```
337
+
338
+ ## TypeScript Support
339
+
340
+ The library is written in TypeScript and exports all type definitions:
341
+
342
+ ```tsx
343
+ import type {
344
+ DismissibleProps,
345
+ IDismissibleItem
346
+ } from '@dismissible/react-client';
347
+
348
+ const MyComponent: React.FC<DismissibleProps> = (props) => {
349
+ // Your component implementation
350
+ };
351
+ ```
352
+
353
+ ## Development
354
+
355
+ ### Prerequisites
356
+
357
+ - Node.js 18+
358
+ - npm or yarn
359
+
360
+ ### Setup
361
+
362
+ ```bash
363
+ # Clone the repository
364
+ git clone https://github.com/your-org/dismissible.git
365
+ cd dismissible/react-client
366
+
367
+ # Install dependencies
368
+ npm install
369
+
370
+ # Start development server
371
+ npm run dev
372
+ ```
373
+
374
+ ### Available Scripts
375
+
376
+ - `npm run dev` - Start development server with Vite
377
+ - `npm run build` - Build the library for production
378
+ - `npm run test` - Run tests with Vitest
379
+ - `npm run test:watch` - Run tests in watch mode
380
+ - `npm run lint` - Run ESLint
381
+ - `npm run format` - Format code with Prettier
382
+ - `npm run storybook` - Start Storybook development server
383
+ - `npm run build-storybook` - Build Storybook for production
384
+
385
+ ### Testing
386
+
387
+ ```bash
388
+ # Run all tests
389
+ npm run test
390
+
391
+ # Run tests in watch mode
392
+ npm run test:watch
393
+
394
+ # Run tests with coverage
395
+ npm run test -- --coverage
396
+ ```
397
+
398
+ ### Storybook
399
+
400
+ The library includes Storybook for component development and documentation:
401
+
402
+ ```bash
403
+ npm run storybook
404
+ ```
405
+
406
+ ## Contributing
407
+
408
+ We welcome contributions! Please see our [Contributing Guide](../CONTRIBUTING.md) for details.
409
+
410
+ ### Development Workflow
411
+
412
+ 1. Fork the repository
413
+ 2. Create a feature branch: `git checkout -b feature/my-new-feature`
414
+ 3. Make your changes
415
+ 4. Add tests for new functionality
416
+ 5. Run tests: `npm run test`
417
+ 6. Run linting: `npm run lint`
418
+ 7. Commit your changes: `git commit -am 'Add new feature'`
419
+ 8. Push to the branch: `git push origin feature/my-new-feature`
420
+ 9. Submit a pull request
421
+
422
+ ## License
423
+
424
+ MIT © [Your Organization](https://github.com/your-org)
425
+
426
+ ## Support
427
+
428
+ - 📖 [Documentation](https://docs.dismissible.io)
429
+ - 🐛 [Issue Tracker](https://github.com/your-org/dismissible/issues)
430
+ - 💬 [Discussions](https://github.com/your-org/dismissible/discussions)
431
+ - 📧 [Email Support](mailto:support@dismissible.io)
432
+
433
+ ## Changelog
434
+
435
+ See [CHANGELOG.md](./CHANGELOG.md) for a detailed list of changes.