@phsa.tec/design-system-react 0.1.9 → 0.2.0
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 +372 -371
- package/dist/index.css +2549 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +148 -35
- package/dist/index.d.ts +148 -35
- package/dist/index.js +1114 -1357
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1064 -1309
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -2534
- package/dist/styles.js +1 -0
- package/package.json +12 -4
- package/dist/styles.css.map +0 -1
- package/dist/styles.d.mts +0 -2
- package/dist/styles.d.ts +0 -2
package/README.md
CHANGED
|
@@ -1,149 +1,233 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🎨 PHSA Design System React
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A modern, **fully isolated** React component library built with TypeScript, Tailwind CSS, and Radix UI. **No Tailwind installation required** in your project!
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## ✨ Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- 🎯 **Zero Configuration** - Works out of the box, no Tailwind setup needed
|
|
8
|
+
- 🔒 **Fully Isolated** - CSS is completely isolated, won't conflict with your project's styles
|
|
9
|
+
- 🎨 **Customizable** - Easy theme customization via Provider props
|
|
10
|
+
- 📦 **Lightweight** - Only includes the CSS you actually use
|
|
11
|
+
- ♿ **Accessible** - Built with Radix UI primitives
|
|
12
|
+
- 🌙 **Dark Mode** - Built-in dark mode support
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
## 📚 Documentation
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
🌐 **[View Live Documentation](https://henriques4nti4go.github.io/phsa-design-system/)**
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
- 🎨 **Tailwind CSS Ready** - Pre-styled components with customizable themes
|
|
15
|
-
- 🔧 **Form Management** - Integrated with React Hook Form + Zod validation
|
|
16
|
-
- 📊 **Advanced Data Tables** - Built with TanStack Table
|
|
17
|
-
- 🌙 **Dark/Light Theme** - Built-in theme switching
|
|
18
|
-
- 🔍 **Full TypeScript Support** - Complete type safety
|
|
19
|
-
- 📱 **Responsive & Accessible** - Mobile-first and WCAG compliant
|
|
18
|
+
## 🚀 Quick Start
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
### 1. Install
|
|
22
21
|
|
|
23
22
|
```bash
|
|
24
23
|
npm install @phsa.tec/design-system-react
|
|
24
|
+
# or
|
|
25
|
+
yarn add @phsa.tec/design-system-react
|
|
26
|
+
# or
|
|
27
|
+
pnpm add @phsa.tec/design-system-react
|
|
25
28
|
```
|
|
26
29
|
|
|
27
|
-
###
|
|
30
|
+
### 2. Wrap Your App
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
```tsx
|
|
33
|
+
import { DesignSystemProvider, Button, Card } from "@phsa.tec/design-system-react";
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
function App() {
|
|
36
|
+
return (
|
|
37
|
+
<DesignSystemProvider>
|
|
38
|
+
<Card>
|
|
39
|
+
<Button>Click me</Button>
|
|
40
|
+
</Card>
|
|
41
|
+
</DesignSystemProvider>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
33
44
|
```
|
|
34
45
|
|
|
35
|
-
|
|
46
|
+
**That's it!** The CSS is automatically injected. No configuration needed.
|
|
36
47
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
## 🎨 Customization
|
|
49
|
+
|
|
50
|
+
You can customize **all Tailwind properties** through the `DesignSystemProvider`:
|
|
51
|
+
|
|
52
|
+
### Complete Theme Customization
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { DesignSystemProvider } from "@phsa.tec/design-system-react";
|
|
40
56
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
module.exports = {
|
|
50
|
-
content: [
|
|
51
|
-
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
|
52
|
-
"./node_modules/@phsa.tec/design-system-react/**/*.{js,ts,jsx,tsx}",
|
|
53
|
-
],
|
|
54
|
-
theme: {
|
|
55
|
-
extend: {
|
|
56
|
-
colors: {
|
|
57
|
-
border: "hsl(var(--border))",
|
|
58
|
-
background: "hsl(var(--background))",
|
|
59
|
-
foreground: "hsl(var(--foreground))",
|
|
60
|
-
primary: {
|
|
61
|
-
DEFAULT: "hsl(var(--primary))",
|
|
62
|
-
foreground: "hsl(var(--primary-foreground))",
|
|
57
|
+
function App() {
|
|
58
|
+
return (
|
|
59
|
+
<DesignSystemProvider
|
|
60
|
+
theme={{
|
|
61
|
+
colors: {
|
|
62
|
+
primary: "#3b82f6",
|
|
63
|
+
secondary: "#10b981",
|
|
64
|
+
// ... all color options
|
|
63
65
|
},
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
spacing: {
|
|
67
|
+
base: "0.25rem", // 4px
|
|
68
|
+
sm: "0.5rem", // 8px
|
|
69
|
+
md: "1rem", // 16px
|
|
70
|
+
lg: "1.5rem", // 24px
|
|
71
|
+
xl: "2rem", // 32px
|
|
67
72
|
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
typography: {
|
|
74
|
+
fontFamily: "Inter, sans-serif",
|
|
75
|
+
fontSize: {
|
|
76
|
+
sm: "0.875rem",
|
|
77
|
+
base: "1rem",
|
|
78
|
+
lg: "1.125rem",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
borderRadius: {
|
|
82
|
+
sm: "0.25rem",
|
|
83
|
+
md: "0.5rem",
|
|
84
|
+
lg: "0.75rem",
|
|
85
|
+
},
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
{/* Your app */}
|
|
89
|
+
</DesignSystemProvider>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
74
92
|
```
|
|
75
93
|
|
|
76
|
-
###
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
94
|
+
### Simple Color Customization (Legacy)
|
|
95
|
+
|
|
96
|
+
For backward compatibility, you can still use the `colors` prop:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<DesignSystemProvider
|
|
100
|
+
colors={{
|
|
101
|
+
primary: "#3b82f6",
|
|
102
|
+
secondary: "#10b981",
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
{/* Your app */}
|
|
106
|
+
</DesignSystemProvider>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Available Theme Properties
|
|
110
|
+
|
|
111
|
+
#### Colors (`theme.colors`)
|
|
112
|
+
|
|
113
|
+
- `primary`, `primaryForeground`
|
|
114
|
+
- `secondary`, `secondaryForeground`
|
|
115
|
+
- `accent`, `accentForeground`
|
|
116
|
+
- `destructive`, `destructiveForeground`
|
|
117
|
+
- `success`, `successForeground`
|
|
118
|
+
- `warning`
|
|
119
|
+
- `muted`, `mutedForeground`
|
|
120
|
+
- `background`, `foreground`
|
|
121
|
+
- `card`, `cardForeground`
|
|
122
|
+
- `popover`, `popoverForeground`
|
|
123
|
+
- `border`, `input`, `ring`
|
|
124
|
+
- `radius`
|
|
125
|
+
|
|
126
|
+
**Color formats supported:**
|
|
127
|
+
- **Hex**: `"#3b82f6"`
|
|
128
|
+
- **HSL**: `"217 91% 60%"` (without `hsl()` wrapper)
|
|
129
|
+
- **RGB**: Standard RGB values
|
|
130
|
+
|
|
131
|
+
#### Spacing (`theme.spacing`)
|
|
132
|
+
|
|
133
|
+
Customize spacing scale used by padding, margin, gap utilities:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
theme={{
|
|
137
|
+
spacing: {
|
|
138
|
+
base: "0.25rem", // Base unit (default: 4px)
|
|
139
|
+
xs: "0.5rem", // Extra small
|
|
140
|
+
sm: "0.75rem", // Small
|
|
141
|
+
md: "1rem", // Medium
|
|
142
|
+
lg: "1.5rem", // Large
|
|
143
|
+
xl: "2rem", // Extra large
|
|
144
|
+
"2xl": "3rem", // 2x extra large
|
|
145
|
+
"3xl": "4rem", // 3x extra large
|
|
107
146
|
}
|
|
147
|
+
}}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Typography (`theme.typography`)
|
|
108
151
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
152
|
+
```tsx
|
|
153
|
+
theme={{
|
|
154
|
+
typography: {
|
|
155
|
+
fontFamily: "Inter, sans-serif",
|
|
156
|
+
fontSize: {
|
|
157
|
+
xs: "0.75rem",
|
|
158
|
+
sm: "0.875rem",
|
|
159
|
+
base: "1rem",
|
|
160
|
+
lg: "1.125rem",
|
|
161
|
+
xl: "1.25rem",
|
|
162
|
+
"2xl": "1.5rem",
|
|
163
|
+
"3xl": "1.875rem",
|
|
164
|
+
"4xl": "2.25rem",
|
|
165
|
+
"5xl": "3rem",
|
|
166
|
+
},
|
|
167
|
+
fontWeight: {
|
|
168
|
+
light: "300",
|
|
169
|
+
normal: "400",
|
|
170
|
+
medium: "500",
|
|
171
|
+
semibold: "600",
|
|
172
|
+
bold: "700",
|
|
173
|
+
},
|
|
174
|
+
lineHeight: {
|
|
175
|
+
none: "1",
|
|
176
|
+
tight: "1.25",
|
|
177
|
+
snug: "1.375",
|
|
178
|
+
normal: "1.5",
|
|
179
|
+
relaxed: "1.75",
|
|
180
|
+
loose: "2",
|
|
181
|
+
},
|
|
129
182
|
}
|
|
130
|
-
}
|
|
183
|
+
}}
|
|
131
184
|
```
|
|
132
185
|
|
|
133
|
-
|
|
186
|
+
#### Border Radius (`theme.borderRadius`)
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
theme={{
|
|
190
|
+
borderRadius: {
|
|
191
|
+
none: "0px",
|
|
192
|
+
sm: "0.25rem",
|
|
193
|
+
md: "0.5rem",
|
|
194
|
+
lg: "0.75rem",
|
|
195
|
+
xl: "1rem",
|
|
196
|
+
"2xl": "1.5rem",
|
|
197
|
+
"3xl": "2rem",
|
|
198
|
+
full: "9999px",
|
|
199
|
+
}
|
|
200
|
+
}}
|
|
201
|
+
```
|
|
134
202
|
|
|
135
|
-
|
|
203
|
+
#### Box Shadow (`theme.boxShadow`)
|
|
136
204
|
|
|
137
205
|
```tsx
|
|
138
|
-
|
|
206
|
+
theme={{
|
|
207
|
+
boxShadow: {
|
|
208
|
+
sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
|
209
|
+
md: "0 4px 6px -1px rgb(0 0 0 / 0.1)",
|
|
210
|
+
lg: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
|
|
211
|
+
xl: "0 20px 25px -5px rgb(0 0 0 / 0.1)",
|
|
212
|
+
"2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
|
|
213
|
+
inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
|
|
214
|
+
none: "none",
|
|
215
|
+
}
|
|
216
|
+
}}
|
|
217
|
+
```
|
|
139
218
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
219
|
+
#### Breakpoints (`theme.breakpoints`)
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
theme={{
|
|
223
|
+
breakpoints: {
|
|
224
|
+
sm: "640px",
|
|
225
|
+
md: "768px",
|
|
226
|
+
lg: "1024px",
|
|
227
|
+
xl: "1280px",
|
|
228
|
+
"2xl": "1536px",
|
|
229
|
+
}
|
|
230
|
+
}}
|
|
147
231
|
```
|
|
148
232
|
|
|
149
233
|
## 🎯 Usage Examples
|
|
@@ -154,214 +238,106 @@ function App() {
|
|
|
154
238
|
import {
|
|
155
239
|
Button,
|
|
156
240
|
Input,
|
|
157
|
-
Badge,
|
|
158
241
|
Card,
|
|
159
242
|
CardContent,
|
|
160
243
|
CardHeader,
|
|
161
244
|
CardTitle,
|
|
245
|
+
DesignSystemProvider,
|
|
162
246
|
} from "@phsa.tec/design-system-react";
|
|
163
247
|
|
|
164
|
-
function
|
|
248
|
+
function App() {
|
|
165
249
|
return (
|
|
166
|
-
<
|
|
167
|
-
<
|
|
168
|
-
<
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
<
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
<Button>
|
|
175
|
-
<Button variant="secondary">Secondary</Button>
|
|
250
|
+
<DesignSystemProvider>
|
|
251
|
+
<Card>
|
|
252
|
+
<CardHeader>
|
|
253
|
+
<CardTitle>Hello World</CardTitle>
|
|
254
|
+
</CardHeader>
|
|
255
|
+
<CardContent>
|
|
256
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
257
|
+
<Input placeholder="Enter text..." />
|
|
258
|
+
<Button>Click me</Button>
|
|
176
259
|
</div>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
</Card>
|
|
260
|
+
</CardContent>
|
|
261
|
+
</Card>
|
|
262
|
+
</DesignSystemProvider>
|
|
181
263
|
);
|
|
182
264
|
}
|
|
183
265
|
```
|
|
184
266
|
|
|
185
|
-
###
|
|
267
|
+
### With Custom Theme
|
|
186
268
|
|
|
187
269
|
```tsx
|
|
188
|
-
import {
|
|
189
|
-
Form,
|
|
190
|
-
FormControl,
|
|
191
|
-
FormField,
|
|
192
|
-
FormItem,
|
|
193
|
-
FormLabel,
|
|
194
|
-
FormMessage,
|
|
195
|
-
Input,
|
|
196
|
-
Button,
|
|
197
|
-
Select,
|
|
198
|
-
SelectContent,
|
|
199
|
-
SelectItem,
|
|
200
|
-
SelectTrigger,
|
|
201
|
-
SelectValue,
|
|
202
|
-
} from "@phsa.tec/design-system-react";
|
|
203
|
-
import { useForm } from "react-hook-form";
|
|
204
|
-
import { zodResolver } from "@hookform/resolvers/zod";
|
|
205
|
-
import * as z from "zod";
|
|
206
|
-
|
|
207
|
-
const formSchema = z.object({
|
|
208
|
-
name: z.string().min(2, "Name must be at least 2 characters"),
|
|
209
|
-
email: z.string().email("Invalid email address"),
|
|
210
|
-
role: z.string().min(1, "Please select a role"),
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
function UserForm() {
|
|
214
|
-
const form = useForm<z.infer<typeof formSchema>>({
|
|
215
|
-
resolver: zodResolver(formSchema),
|
|
216
|
-
defaultValues: {
|
|
217
|
-
name: "",
|
|
218
|
-
email: "",
|
|
219
|
-
role: "",
|
|
220
|
-
},
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
function onSubmit(values: z.infer<typeof formSchema>) {
|
|
224
|
-
console.log(values);
|
|
225
|
-
}
|
|
270
|
+
import { DesignSystemProvider, Button } from "@phsa.tec/design-system-react";
|
|
226
271
|
|
|
272
|
+
function App() {
|
|
227
273
|
return (
|
|
228
|
-
<
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
name="email"
|
|
247
|
-
render={({ field }) => (
|
|
248
|
-
<FormItem>
|
|
249
|
-
<FormLabel>Email</FormLabel>
|
|
250
|
-
<FormControl>
|
|
251
|
-
<Input placeholder="john@example.com" {...field} />
|
|
252
|
-
</FormControl>
|
|
253
|
-
<FormMessage />
|
|
254
|
-
</FormItem>
|
|
255
|
-
)}
|
|
256
|
-
/>
|
|
257
|
-
|
|
258
|
-
<FormField
|
|
259
|
-
control={form.control}
|
|
260
|
-
name="role"
|
|
261
|
-
render={({ field }) => (
|
|
262
|
-
<FormItem>
|
|
263
|
-
<FormLabel>Role</FormLabel>
|
|
264
|
-
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
|
265
|
-
<FormControl>
|
|
266
|
-
<SelectTrigger>
|
|
267
|
-
<SelectValue placeholder="Select a role" />
|
|
268
|
-
</SelectTrigger>
|
|
269
|
-
</FormControl>
|
|
270
|
-
<SelectContent>
|
|
271
|
-
<SelectItem value="admin">Admin</SelectItem>
|
|
272
|
-
<SelectItem value="user">User</SelectItem>
|
|
273
|
-
<SelectItem value="viewer">Viewer</SelectItem>
|
|
274
|
-
</SelectContent>
|
|
275
|
-
</Select>
|
|
276
|
-
<FormMessage />
|
|
277
|
-
</FormItem>
|
|
278
|
-
)}
|
|
279
|
-
/>
|
|
280
|
-
|
|
281
|
-
<Button type="submit">Submit</Button>
|
|
282
|
-
</form>
|
|
283
|
-
</Form>
|
|
274
|
+
<DesignSystemProvider
|
|
275
|
+
theme={{
|
|
276
|
+
colors: {
|
|
277
|
+
primary: "#8b5cf6", // Purple
|
|
278
|
+
secondary: "#06b6d4", // Cyan
|
|
279
|
+
},
|
|
280
|
+
spacing: {
|
|
281
|
+
md: "1.25rem", // Custom medium spacing
|
|
282
|
+
lg: "2rem", // Custom large spacing
|
|
283
|
+
},
|
|
284
|
+
typography: {
|
|
285
|
+
fontFamily: "Inter, sans-serif",
|
|
286
|
+
},
|
|
287
|
+
}}
|
|
288
|
+
>
|
|
289
|
+
<Button variant="default">Primary Button</Button>
|
|
290
|
+
<Button variant="secondary">Secondary Button</Button>
|
|
291
|
+
</DesignSystemProvider>
|
|
284
292
|
);
|
|
285
293
|
}
|
|
286
294
|
```
|
|
287
295
|
|
|
288
|
-
###
|
|
296
|
+
### Advanced Customization Example
|
|
289
297
|
|
|
290
298
|
```tsx
|
|
291
|
-
import {
|
|
292
|
-
import { ColumnDef } from "@tanstack/react-table";
|
|
293
|
-
|
|
294
|
-
type User = {
|
|
295
|
-
id: string;
|
|
296
|
-
name: string;
|
|
297
|
-
email: string;
|
|
298
|
-
role: string;
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
const columns: ColumnDef<User>[] = [
|
|
302
|
-
{
|
|
303
|
-
accessorKey: "name",
|
|
304
|
-
header: "Name",
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
accessorKey: "email",
|
|
308
|
-
header: "Email",
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
accessorKey: "role",
|
|
312
|
-
header: "Role",
|
|
313
|
-
},
|
|
314
|
-
];
|
|
315
|
-
|
|
316
|
-
function UsersTable() {
|
|
317
|
-
const data: User[] = [
|
|
318
|
-
{ id: "1", name: "John Doe", email: "john@example.com", role: "Admin" },
|
|
319
|
-
{ id: "2", name: "Jane Smith", email: "jane@example.com", role: "User" },
|
|
320
|
-
];
|
|
299
|
+
import { DesignSystemProvider, Card, Button } from "@phsa.tec/design-system-react";
|
|
321
300
|
|
|
301
|
+
function App() {
|
|
322
302
|
return (
|
|
323
|
-
<
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
</
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
<Button>Confirm</Button>
|
|
362
|
-
</div>
|
|
363
|
-
</DialogContent>
|
|
364
|
-
</Dialog>
|
|
303
|
+
<DesignSystemProvider
|
|
304
|
+
theme={{
|
|
305
|
+
colors: {
|
|
306
|
+
primary: "#6366f1",
|
|
307
|
+
secondary: "#8b5cf6",
|
|
308
|
+
},
|
|
309
|
+
spacing: {
|
|
310
|
+
base: "0.5rem", // 8px base (instead of 4px)
|
|
311
|
+
md: "1.5rem", // 24px medium
|
|
312
|
+
lg: "3rem", // 48px large
|
|
313
|
+
},
|
|
314
|
+
typography: {
|
|
315
|
+
fontFamily: "'Inter', 'Roboto', sans-serif",
|
|
316
|
+
fontSize: {
|
|
317
|
+
base: "16px",
|
|
318
|
+
lg: "18px",
|
|
319
|
+
xl: "20px",
|
|
320
|
+
},
|
|
321
|
+
fontWeight: {
|
|
322
|
+
normal: "400",
|
|
323
|
+
semibold: "600",
|
|
324
|
+
bold: "700",
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
borderRadius: {
|
|
328
|
+
md: "0.75rem",
|
|
329
|
+
lg: "1rem",
|
|
330
|
+
},
|
|
331
|
+
boxShadow: {
|
|
332
|
+
md: "0 8px 16px -4px rgb(0 0 0 / 0.15)",
|
|
333
|
+
lg: "0 16px 32px -8px rgb(0 0 0 / 0.2)",
|
|
334
|
+
},
|
|
335
|
+
}}
|
|
336
|
+
>
|
|
337
|
+
<Card>
|
|
338
|
+
<Button>Customized Button</Button>
|
|
339
|
+
</Card>
|
|
340
|
+
</DesignSystemProvider>
|
|
365
341
|
);
|
|
366
342
|
}
|
|
367
343
|
```
|
|
@@ -369,107 +345,132 @@ function MyDialog() {
|
|
|
369
345
|
## 🧩 Available Components
|
|
370
346
|
|
|
371
347
|
### Layout
|
|
372
|
-
|
|
373
|
-
-
|
|
374
|
-
-
|
|
375
|
-
-
|
|
376
|
-
-
|
|
348
|
+
- **Card** - Container component with header, content, and footer
|
|
349
|
+
- **Sheet** - Slide-over panel
|
|
350
|
+
- **Tabs** - Tab navigation
|
|
351
|
+
- **Separator** - Visual divider
|
|
352
|
+
- **PageLayout** - Full page layout wrapper
|
|
353
|
+
|
|
354
|
+
### Forms
|
|
355
|
+
- **Input** - Text input with validation support
|
|
356
|
+
- **Button** - Button with multiple variants
|
|
357
|
+
- **Select** - Dropdown selection
|
|
358
|
+
- **Checkbox** - Checkbox input
|
|
359
|
+
- **Switch** - Toggle switch
|
|
360
|
+
- **Form** - Form wrapper with React Hook Form integration
|
|
377
361
|
|
|
378
362
|
### Data Display
|
|
379
|
-
|
|
380
|
-
-
|
|
381
|
-
-
|
|
382
|
-
-
|
|
383
|
-
- `Tooltip`, `TooltipContent`, `TooltipProvider`, `TooltipTrigger`
|
|
384
|
-
|
|
385
|
-
### Data Input
|
|
386
|
-
|
|
387
|
-
- `Input` - Text input with validation
|
|
388
|
-
- `Button` - Customizable button component
|
|
389
|
-
- `Select`, `SelectContent`, `SelectItem`, `SelectTrigger`, `SelectValue`
|
|
390
|
-
- `Checkbox` - Checkbox input
|
|
391
|
-
- `Switch` - Toggle switch
|
|
392
|
-
- `Form`, `FormControl`, `FormField`, `FormItem`, `FormLabel`, `FormMessage`
|
|
363
|
+
- **DataTable** - Advanced table with sorting, filtering, pagination
|
|
364
|
+
- **Badge** - Status badge
|
|
365
|
+
- **Avatar** - User avatar
|
|
366
|
+
- **Text** - Typography component
|
|
393
367
|
|
|
394
368
|
### Feedback
|
|
395
|
-
|
|
396
|
-
-
|
|
397
|
-
-
|
|
398
|
-
-
|
|
399
|
-
-
|
|
369
|
+
- **Dialog** - Modal dialog
|
|
370
|
+
- **AlertDialog** - Confirmation dialog
|
|
371
|
+
- **Toast** - Notification toast
|
|
372
|
+
- **Alert** - Alert message
|
|
373
|
+
- **Spinner** - Loading spinner
|
|
400
374
|
|
|
401
375
|
### Navigation
|
|
376
|
+
- **DropdownMenu** - Dropdown menu
|
|
377
|
+
- **Breadcrumbs** - Breadcrumb navigation
|
|
378
|
+
- **Command** - Command palette
|
|
402
379
|
|
|
403
|
-
|
|
404
|
-
- `Command`, `CommandDialog`, `CommandInput`, `CommandList`
|
|
405
|
-
|
|
406
|
-
## 🎨 Customization
|
|
407
|
-
|
|
408
|
-
### Component Variants
|
|
380
|
+
## 🌙 Dark Mode
|
|
409
381
|
|
|
410
|
-
|
|
382
|
+
The design system supports dark mode automatically. Add the `dark` class to your root element:
|
|
411
383
|
|
|
412
384
|
```tsx
|
|
413
|
-
//
|
|
414
|
-
|
|
415
|
-
<Button variant="destructive">Delete</Button>
|
|
416
|
-
<Button variant="outline">Outline</Button>
|
|
417
|
-
<Button variant="secondary">Secondary</Button>
|
|
418
|
-
<Button variant="ghost">Ghost</Button>
|
|
419
|
-
<Button variant="link">Link</Button>
|
|
420
|
-
|
|
421
|
-
// Button sizes
|
|
422
|
-
<Button size="sm">Small</Button>
|
|
423
|
-
<Button size="default">Default</Button>
|
|
424
|
-
<Button size="lg">Large</Button>
|
|
385
|
+
// Toggle dark mode
|
|
386
|
+
document.documentElement.classList.toggle('dark');
|
|
425
387
|
```
|
|
426
388
|
|
|
427
|
-
|
|
389
|
+
Or use `next-themes` for React:
|
|
428
390
|
|
|
429
|
-
|
|
391
|
+
```bash
|
|
392
|
+
npm install next-themes
|
|
393
|
+
```
|
|
430
394
|
|
|
431
395
|
```tsx
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
396
|
+
import { ThemeProvider } from "next-themes";
|
|
397
|
+
import { DesignSystemProvider } from "@phsa.tec/design-system-react";
|
|
398
|
+
|
|
399
|
+
function App() {
|
|
400
|
+
return (
|
|
401
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
|
402
|
+
<DesignSystemProvider>
|
|
403
|
+
{/* Your app */}
|
|
404
|
+
</DesignSystemProvider>
|
|
405
|
+
</ThemeProvider>
|
|
406
|
+
);
|
|
407
|
+
}
|
|
435
408
|
```
|
|
436
409
|
|
|
437
|
-
##
|
|
410
|
+
## 🔒 Isolation & Compatibility
|
|
438
411
|
|
|
439
|
-
|
|
412
|
+
### ✅ Works With
|
|
440
413
|
|
|
441
|
-
|
|
442
|
-
|
|
414
|
+
- ✅ Projects **without** Tailwind CSS
|
|
415
|
+
- ✅ Projects **with** Tailwind CSS (no conflicts!)
|
|
416
|
+
- ✅ Next.js, Vite, Create React App, etc.
|
|
417
|
+
- ✅ Any React framework
|
|
443
418
|
|
|
444
|
-
|
|
445
|
-
isLoading?: boolean;
|
|
446
|
-
}
|
|
419
|
+
### How It Works
|
|
447
420
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
421
|
+
The design system:
|
|
422
|
+
1. **Compiles CSS at build time** - All Tailwind classes are pre-compiled
|
|
423
|
+
2. **Uses unique class prefixes** - Classes are prefixed with `phsa-` to avoid conflicts
|
|
424
|
+
3. **Scopes CSS with `.ds`** - All styles are scoped to prevent interference
|
|
425
|
+
4. **Auto-injects CSS** - CSS is automatically loaded when you use `DesignSystemProvider`
|
|
426
|
+
|
|
427
|
+
## 📦 Package Exports
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
// Components
|
|
431
|
+
import { Button, Card } from "@phsa.tec/design-system-react";
|
|
432
|
+
|
|
433
|
+
// Styles (if you need manual import)
|
|
434
|
+
import "@phsa.tec/design-system-react/styles";
|
|
435
|
+
// or
|
|
436
|
+
import styles from "@phsa.tec/design-system-react/styles";
|
|
455
437
|
```
|
|
456
438
|
|
|
457
|
-
##
|
|
439
|
+
## 🛠️ Development
|
|
458
440
|
|
|
459
|
-
|
|
460
|
-
- **Interactive Examples**: All components include interactive Storybook stories
|
|
461
|
-
- **Props Documentation**: Complete API reference for all components
|
|
441
|
+
For local development and contributing:
|
|
462
442
|
|
|
463
|
-
|
|
443
|
+
```bash
|
|
444
|
+
# Install dependencies
|
|
445
|
+
yarn install
|
|
464
446
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
447
|
+
# Run Storybook
|
|
448
|
+
yarn storybook
|
|
449
|
+
|
|
450
|
+
# Build library
|
|
451
|
+
yarn build:lib
|
|
452
|
+
|
|
453
|
+
# Watch mode
|
|
454
|
+
yarn build:lib:watch
|
|
455
|
+
|
|
456
|
+
# Run tests
|
|
457
|
+
yarn test
|
|
458
|
+
```
|
|
468
459
|
|
|
469
460
|
## 📄 License
|
|
470
461
|
|
|
471
|
-
MIT License - see
|
|
462
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
463
|
+
|
|
464
|
+
## 🤝 Contributing
|
|
465
|
+
|
|
466
|
+
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
|
|
467
|
+
|
|
468
|
+
## 📞 Support
|
|
469
|
+
|
|
470
|
+
- **Documentation**: [View Live Docs](https://henriques4nti4go.github.io/phsa-design-system/)
|
|
471
|
+
- **Issues**: [GitHub Issues](https://github.com/henriques4nti4go/phsa-design-system/issues)
|
|
472
|
+
- **Package**: [npm](https://www.npmjs.com/package/@phsa.tec/design-system-react)
|
|
472
473
|
|
|
473
474
|
---
|
|
474
475
|
|
|
475
|
-
Built with ❤️
|
|
476
|
+
Built with ❤️ by the PHSA team
|