@abhir9/pd-design-system 0.1.18 → 0.1.20
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 +276 -32
- package/dist/index.cjs +264 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1098 -429
- package/dist/index.d.cts +126 -60
- package/dist/index.d.ts +126 -60
- package/dist/index.js +264 -81
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1061 -417
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ This design system follows a **headless-first, adapter-based architecture**:
|
|
|
9
9
|
- **Props-only API**: Consumers use only props and variants, no className required
|
|
10
10
|
- **Full TypeScript**: Complete autocomplete and type safety
|
|
11
11
|
- **Adapter Layer**: Switch between UI engines (shadcn, Material, etc.) without app changes
|
|
12
|
-
- **Semantic Tokens**:
|
|
12
|
+
- **Semantic Tokens**: Design tokens that work across themes
|
|
13
13
|
- **Framework Agnostic**: Design tokens and semantics are framework-agnostic
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
@@ -21,21 +21,38 @@ npm install @pd-design/system
|
|
|
21
21
|
## Quick Start
|
|
22
22
|
|
|
23
23
|
```tsx
|
|
24
|
-
import {
|
|
25
|
-
import '@pd-design/system/styles';
|
|
24
|
+
import { PdThemeProvider, Button, Input } from '@pd-design/system';
|
|
25
|
+
import '@pd-design/system/styles.css';
|
|
26
26
|
|
|
27
27
|
function App() {
|
|
28
28
|
return (
|
|
29
|
-
<
|
|
30
|
-
<Button variant="
|
|
29
|
+
<PdThemeProvider theme="base" mode="light">
|
|
30
|
+
<Button variant="destructive" size="md">
|
|
31
31
|
Delete
|
|
32
32
|
</Button>
|
|
33
33
|
<Input placeholder="Enter text..." size="md" />
|
|
34
|
-
</
|
|
34
|
+
</PdThemeProvider>
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
### Important: Style Isolation
|
|
40
|
+
|
|
41
|
+
The design system uses **scoped styling** to prevent style conflicts:
|
|
42
|
+
|
|
43
|
+
- ✅ **All Tailwind classes are prefixed with `pd-`** - No collision with consumer Tailwind
|
|
44
|
+
- ✅ **All CSS variables are scoped under `.pd-root`** - No token leakage
|
|
45
|
+
- ✅ **Preflight is disabled** - Consumer styles are never reset
|
|
46
|
+
- ✅ **Works with any consumer setup** - Tailwind, MUI, AntD, Bootstrap, or plain CSS
|
|
47
|
+
|
|
48
|
+
**Always wrap your components with `PdThemeProvider`** to create the scoped boundary:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
<PdThemeProvider theme="base" mode="light">
|
|
52
|
+
{/* Your design system components */}
|
|
53
|
+
</PdThemeProvider>
|
|
54
|
+
```
|
|
55
|
+
|
|
39
56
|
## Configuration
|
|
40
57
|
|
|
41
58
|
Configure the design system globally:
|
|
@@ -51,7 +68,7 @@ setDesignSystemConfig({
|
|
|
51
68
|
});
|
|
52
69
|
```
|
|
53
70
|
|
|
54
|
-
Or use the `ThemeProvider
|
|
71
|
+
Or use the `ThemeProvider` (full-featured with context):
|
|
55
72
|
|
|
56
73
|
```tsx
|
|
57
74
|
<ThemeProvider adapter="shadcn" theme="base" mode="light">
|
|
@@ -59,22 +76,47 @@ Or use the `ThemeProvider`:
|
|
|
59
76
|
</ThemeProvider>
|
|
60
77
|
```
|
|
61
78
|
|
|
79
|
+
### PdThemeProvider vs ThemeProvider
|
|
80
|
+
|
|
81
|
+
- **`PdThemeProvider`**: Lightweight wrapper that creates the `.pd-root` scoped boundary. Use for simple theming needs.
|
|
82
|
+
- **`ThemeProvider`**: Full-featured provider with React context, system preference detection, and CSS variable management. Use when you need theme context access via `useTheme()` hook.
|
|
83
|
+
|
|
84
|
+
Both support the same `theme` and `mode` props.
|
|
85
|
+
|
|
62
86
|
## Components
|
|
63
87
|
|
|
64
88
|
### Button
|
|
65
89
|
|
|
66
90
|
```tsx
|
|
67
91
|
<Button
|
|
68
|
-
variant="primary" // primary | secondary | ghost |
|
|
69
|
-
intent="danger" // primary | success | warning | danger | neutral
|
|
92
|
+
variant="primary" // primary | secondary | ghost | destructive
|
|
70
93
|
size="md" // sm | md | lg
|
|
94
|
+
startIcon="Download" // Icon name (TypeScript autocomplete)
|
|
95
|
+
endIcon="ArrowRight" // Icon name (TypeScript autocomplete)
|
|
71
96
|
loading={false}
|
|
72
97
|
disabled={false}
|
|
98
|
+
asChild={false} // Render as child element
|
|
73
99
|
>
|
|
74
100
|
Click me
|
|
75
101
|
</Button>
|
|
76
102
|
```
|
|
77
103
|
|
|
104
|
+
**For form submission buttons:**
|
|
105
|
+
```tsx
|
|
106
|
+
<form onSubmit={handleSubmit}>
|
|
107
|
+
<Button type="submit">Submit Form</Button>
|
|
108
|
+
<Button type="reset">Reset</Button>
|
|
109
|
+
</form>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Button with Icons:**
|
|
113
|
+
```tsx
|
|
114
|
+
<Button startIcon="Download">Download</Button>
|
|
115
|
+
<Button endIcon="ArrowRight">Next</Button>
|
|
116
|
+
<Button startIcon="Trash2" variant="destructive">Delete</Button>
|
|
117
|
+
<Button startIcon="Save">Save</Button>
|
|
118
|
+
```
|
|
119
|
+
|
|
78
120
|
### Input
|
|
79
121
|
|
|
80
122
|
```tsx
|
|
@@ -173,17 +215,62 @@ Or use the `ThemeProvider`:
|
|
|
173
215
|
onOpenChange={setOpen}
|
|
174
216
|
title="Success"
|
|
175
217
|
description="Action completed"
|
|
176
|
-
intent="success"
|
|
177
218
|
/>
|
|
178
219
|
</ToastProvider>
|
|
179
220
|
```
|
|
180
221
|
|
|
222
|
+
## Icons
|
|
223
|
+
|
|
224
|
+
The design system includes all [Lucide React icons](https://lucide.dev/) with TypeScript autocomplete support.
|
|
225
|
+
|
|
226
|
+
### Using Icons with Components
|
|
227
|
+
|
|
228
|
+
Use icon names as strings. TypeScript will autocomplete available icon names:
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
import { Button } from '@pd-design/system';
|
|
232
|
+
|
|
233
|
+
<Button startIcon="Download">Download</Button>
|
|
234
|
+
<Button endIcon="ArrowRight">Next</Button>
|
|
235
|
+
<Button startIcon="Trash2" variant="destructive">Delete</Button>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Using Icons Standalone
|
|
239
|
+
|
|
240
|
+
Import icons from the `Icons` namespace for standalone use:
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
import { Icons } from '@pd-design/system';
|
|
244
|
+
|
|
245
|
+
<Icons.Download className="h-4 w-4" />
|
|
246
|
+
<Icons.Trash2 className="h-5 w-5 text-red-500" />
|
|
247
|
+
<Icons.Heart className="h-6 w-6 fill-red-500" />
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Combining Icons and Components
|
|
251
|
+
|
|
252
|
+
You can use icons standalone alongside components:
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
import { Button, Icons } from '@pd-design/system';
|
|
256
|
+
|
|
257
|
+
<Button startIcon="Download">
|
|
258
|
+
<Icons.Check className="ml-2 h-4 w-4" />
|
|
259
|
+
Download Complete
|
|
260
|
+
</Button>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Available Icons
|
|
264
|
+
|
|
265
|
+
All Lucide React icons are available. TypeScript provides autocomplete for icon names when using with components. Browse all icons in Storybook or check the [Lucide Icons website](https://lucide.dev/icons/).
|
|
266
|
+
|
|
267
|
+
**Popular icons:** `Download`, `Upload`, `Trash2`, `Edit`, `Save`, `Search`, `Settings`, `User`, `Mail`, `Bell`, `Heart`, `Star`, `Share`, `Copy`, `Check`, `X`, `Plus`, `Minus`, `ArrowRight`, `ArrowLeft`, `Home`, `Menu`, and 1000+ more.
|
|
268
|
+
|
|
181
269
|
## Variant System
|
|
182
270
|
|
|
183
271
|
All components follow a strict, typed variant system:
|
|
184
272
|
|
|
185
|
-
- **variant**: `primary` | `secondary` | `ghost` | `
|
|
186
|
-
- **intent**: `primary` | `success` | `warning` | `danger` | `neutral`
|
|
273
|
+
- **variant**: `primary` | `secondary` | `ghost` | `destructive`
|
|
187
274
|
- **size**: `sm` | `md` | `lg`
|
|
188
275
|
- **state**: `loading` | `disabled`
|
|
189
276
|
|
|
@@ -191,25 +278,69 @@ No arbitrary strings or raw class overrides are allowed.
|
|
|
191
278
|
|
|
192
279
|
## Theming
|
|
193
280
|
|
|
194
|
-
The design system
|
|
281
|
+
The design system supports **themes** and **modes** as separate concepts:
|
|
282
|
+
|
|
283
|
+
- **Theme** (`theme`): The design theme name - `'base'` | `'brand'`
|
|
284
|
+
- **Mode** (`mode`): The color scheme - `'light'` | `'dark'` | `'system'`
|
|
285
|
+
|
|
286
|
+
The design system uses **scoped CSS variables** under `.pd-root`. Themes and modes can be switched without rebuilding:
|
|
195
287
|
|
|
196
288
|
```tsx
|
|
197
|
-
<
|
|
198
|
-
{/*
|
|
199
|
-
</
|
|
289
|
+
<PdThemeProvider theme="base" mode="dark">
|
|
290
|
+
{/* Base theme, dark mode */}
|
|
291
|
+
</PdThemeProvider>
|
|
292
|
+
|
|
293
|
+
<PdThemeProvider theme="brand" mode="light">
|
|
294
|
+
{/* Brand theme, light mode */}
|
|
295
|
+
</PdThemeProvider>
|
|
296
|
+
|
|
297
|
+
<PdThemeProvider theme="base" mode="system">
|
|
298
|
+
{/* Base theme, follows OS preference */}
|
|
299
|
+
</PdThemeProvider>
|
|
200
300
|
```
|
|
201
301
|
|
|
302
|
+
### Default Values
|
|
303
|
+
|
|
304
|
+
- **adapter**: `'shadcn'` (default)
|
|
305
|
+
- **theme**: `'base'` (default)
|
|
306
|
+
- **mode**: `'system'` (default - follows OS preference)
|
|
307
|
+
|
|
202
308
|
### Custom Themes
|
|
203
309
|
|
|
204
|
-
You can
|
|
310
|
+
You can override tokens using CSS variables scoped to `.pd-root`:
|
|
311
|
+
|
|
312
|
+
```tsx
|
|
313
|
+
<PdThemeProvider
|
|
314
|
+
theme="base"
|
|
315
|
+
mode="light"
|
|
316
|
+
className="pd-root [--pd-primary:220_80%_50%]"
|
|
317
|
+
>
|
|
318
|
+
{/* Custom primary color */}
|
|
319
|
+
</PdThemeProvider>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Or via CSS:
|
|
205
323
|
|
|
206
324
|
```css
|
|
207
|
-
|
|
208
|
-
--pd-
|
|
209
|
-
--pd-
|
|
325
|
+
.pd-root {
|
|
326
|
+
--pd-primary: 220 80% 50%;
|
|
327
|
+
--pd-primary-foreground: 0 0% 98%;
|
|
210
328
|
}
|
|
211
329
|
```
|
|
212
330
|
|
|
331
|
+
### Per-Widget Theming
|
|
332
|
+
|
|
333
|
+
You can wrap only part of your page with `PdThemeProvider` for widget-level theming:
|
|
334
|
+
|
|
335
|
+
```tsx
|
|
336
|
+
<div>
|
|
337
|
+
{/* Consumer styles */}
|
|
338
|
+
<PdThemeProvider theme="base" mode="dark">
|
|
339
|
+
{/* Design system widget with dark theme */}
|
|
340
|
+
</PdThemeProvider>
|
|
341
|
+
</div>
|
|
342
|
+
```
|
|
343
|
+
|
|
213
344
|
## Adapter Layer
|
|
214
345
|
|
|
215
346
|
The adapter layer allows switching UI engines without changing application code:
|
|
@@ -234,10 +365,13 @@ npm run storybook
|
|
|
234
365
|
Storybook includes:
|
|
235
366
|
- All component variants
|
|
236
367
|
- Interactive controls
|
|
237
|
-
- Theme switcher (
|
|
238
|
-
-
|
|
368
|
+
- Theme switcher (base/brand)
|
|
369
|
+
- Mode switcher (light/dark/system)
|
|
370
|
+
- Adapter switcher (shadcn/material)
|
|
371
|
+
- Icons browser with search
|
|
239
372
|
- Accessibility panel
|
|
240
373
|
- Code snippets
|
|
374
|
+
- Live examples
|
|
241
375
|
|
|
242
376
|
## Architecture
|
|
243
377
|
|
|
@@ -247,28 +381,138 @@ src/
|
|
|
247
381
|
├── theme/ # Theme system & provider
|
|
248
382
|
├── primitives/ # Headless components
|
|
249
383
|
├── adapters/ # UI engine adapters
|
|
250
|
-
|
|
384
|
+
├── components/ # Public components
|
|
385
|
+
└── styles/ # Scoped CSS (tokens.css, base.css)
|
|
251
386
|
```
|
|
252
387
|
|
|
388
|
+
### Style Isolation Architecture
|
|
389
|
+
|
|
390
|
+
The design system implements **4 guardrails** to prevent style conflicts:
|
|
391
|
+
|
|
392
|
+
1. **Prefix all Tailwind classes** (`pd-`) - Utilities never collide with consumer Tailwind
|
|
393
|
+
2. **Disable Tailwind preflight** - Consumer styles are never reset
|
|
394
|
+
3. **Scope all tokens under `.pd-root`** - Tokens never leak outside the boundary
|
|
395
|
+
4. **Ship compiled CSS** - Consumer doesn't need Tailwind to use components
|
|
396
|
+
|
|
397
|
+
This ensures the design system works seamlessly with:
|
|
398
|
+
- ✅ Consumer Tailwind projects
|
|
399
|
+
- ✅ Material UI (MUI)
|
|
400
|
+
- ✅ Ant Design
|
|
401
|
+
- ✅ Bootstrap
|
|
402
|
+
- ✅ Plain CSS projects
|
|
403
|
+
- ✅ Any CSS framework or reset
|
|
404
|
+
|
|
253
405
|
## TypeScript
|
|
254
406
|
|
|
255
|
-
Full TypeScript support with autocomplete:
|
|
407
|
+
Full TypeScript support with autocomplete for all props:
|
|
256
408
|
|
|
257
409
|
```tsx
|
|
258
410
|
<Button
|
|
259
|
-
variant="primary"
|
|
260
|
-
|
|
261
|
-
|
|
411
|
+
variant="primary" // ✅ Autocomplete: primary | secondary | ghost | destructive
|
|
412
|
+
size="md" // ✅ Autocomplete: sm | md | lg
|
|
413
|
+
startIcon="Download" // ✅ Autocomplete: All Lucide icon names
|
|
414
|
+
endIcon="ArrowRight" // ✅ Autocomplete: All Lucide icon names
|
|
415
|
+
/>
|
|
416
|
+
|
|
417
|
+
<PdThemeProvider
|
|
418
|
+
theme="base" // ✅ Autocomplete: base | brand
|
|
419
|
+
mode="system" // ✅ Autocomplete: light | dark | system
|
|
262
420
|
/>
|
|
263
421
|
```
|
|
264
422
|
|
|
423
|
+
All types are exported and available for use:
|
|
424
|
+
|
|
425
|
+
```tsx
|
|
426
|
+
import type {
|
|
427
|
+
Variant,
|
|
428
|
+
Size,
|
|
429
|
+
ButtonType,
|
|
430
|
+
ThemeName,
|
|
431
|
+
ThemeMode,
|
|
432
|
+
LucideIconName
|
|
433
|
+
} from '@pd-design/system';
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## API Reference
|
|
437
|
+
|
|
438
|
+
### Exports
|
|
439
|
+
|
|
440
|
+
```tsx
|
|
441
|
+
// Components
|
|
442
|
+
import {
|
|
443
|
+
Button,
|
|
444
|
+
ButtonGroup,
|
|
445
|
+
PdThemeProvider,
|
|
446
|
+
Icons
|
|
447
|
+
} from '@pd-design/system';
|
|
448
|
+
|
|
449
|
+
// Theme
|
|
450
|
+
import {
|
|
451
|
+
ThemeProvider,
|
|
452
|
+
useTheme,
|
|
453
|
+
setDesignSystemConfig,
|
|
454
|
+
getDesignSystemConfig
|
|
455
|
+
} from '@pd-design/system';
|
|
456
|
+
|
|
457
|
+
// Types
|
|
458
|
+
import type {
|
|
459
|
+
Variant,
|
|
460
|
+
Size,
|
|
461
|
+
ButtonType,
|
|
462
|
+
ThemeName,
|
|
463
|
+
ThemeMode,
|
|
464
|
+
AdapterType,
|
|
465
|
+
LucideIconName
|
|
466
|
+
} from '@pd-design/system';
|
|
467
|
+
|
|
468
|
+
// Icons
|
|
469
|
+
import { Icons } from '@pd-design/system';
|
|
470
|
+
// or individual icons
|
|
471
|
+
import { Download, Trash2 } from '@pd-design/system';
|
|
472
|
+
|
|
473
|
+
// Utilities
|
|
474
|
+
import {
|
|
475
|
+
getIcon,
|
|
476
|
+
renderIcon,
|
|
477
|
+
iconExists,
|
|
478
|
+
getAvailableIconNames
|
|
479
|
+
} from '@pd-design/system';
|
|
480
|
+
|
|
481
|
+
// Styles (required)
|
|
482
|
+
import '@pd-design/system/styles.css';
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Component Props
|
|
486
|
+
|
|
487
|
+
All components use consistent prop patterns:
|
|
488
|
+
|
|
489
|
+
- **variant**: Visual style (`primary`, `secondary`, `ghost`, `destructive`)
|
|
490
|
+
- **size**: Component size (`sm`, `md`, `lg`)
|
|
491
|
+
- **disabled**: Disabled state
|
|
492
|
+
- **loading**: Loading state (where applicable)
|
|
493
|
+
- **startIcon/endIcon**: Icon names with TypeScript autocomplete
|
|
494
|
+
|
|
265
495
|
## Accessibility
|
|
266
496
|
|
|
267
|
-
- Radix UI primitives for ARIA compliance
|
|
268
|
-
- Keyboard navigation support
|
|
269
|
-
- Focus ring standards
|
|
270
|
-
- Screen reader labels
|
|
271
|
-
- Contrast-safe tokens
|
|
497
|
+
- ✅ Radix UI primitives for ARIA compliance
|
|
498
|
+
- ✅ Keyboard navigation support (Tab, Enter, Space, Arrow keys)
|
|
499
|
+
- ✅ Focus ring standards (visible focus indicators)
|
|
500
|
+
- ✅ Screen reader labels (aria-label, aria-describedby)
|
|
501
|
+
- ✅ Contrast-safe tokens (WCAG AA compliant)
|
|
502
|
+
- ✅ Disabled state handling (aria-disabled, pointer-events)
|
|
503
|
+
- ✅ Loading state indicators (aria-busy)
|
|
504
|
+
|
|
505
|
+
## Browser Support
|
|
506
|
+
|
|
507
|
+
- Chrome (latest)
|
|
508
|
+
- Firefox (latest)
|
|
509
|
+
- Safari (latest)
|
|
510
|
+
- Edge (latest)
|
|
511
|
+
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
512
|
+
|
|
513
|
+
## Contributing
|
|
514
|
+
|
|
515
|
+
This is an internal design system. For contributions, please follow the architecture guidelines in `ARCHITECTURE.md`.
|
|
272
516
|
|
|
273
517
|
## License
|
|
274
518
|
|