@j3m-quantum/ui 2.1.0 → 2.1.5
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 +6 -1
- package/cursor-rules-for-consumers.md +184 -107
- package/dist/cli/index.js +311 -109
- package/dist/cli/postinstall.js +45 -18
- package/dist/index.cjs +6376 -4548
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +361 -8
- package/dist/index.d.ts +361 -8
- package/dist/index.js +6375 -4565
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as fs2 from 'fs';
|
|
3
|
-
import * as
|
|
3
|
+
import * as path from 'path';
|
|
4
4
|
|
|
5
5
|
var CURSOR_RULES_CONTENT = `# J3M Design System Rules
|
|
6
6
|
|
|
@@ -10,21 +10,128 @@ var CURSOR_RULES_CONTENT = `# J3M Design System Rules
|
|
|
10
10
|
- Do NOT use shadcn CLI to add components - everything is already bundled
|
|
11
11
|
- Do NOT create local component copies - use the package exports
|
|
12
12
|
|
|
13
|
-
## CRITICAL:
|
|
13
|
+
## CRITICAL: Pre-built Blocks - USE THESE FIRST!
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
Before implementing ANY sidebar, navigation, header, or dashboard layout, ALWAYS import these pre-built blocks:
|
|
16
|
+
|
|
17
|
+
\`\`\`tsx
|
|
18
|
+
// Pre-built blocks - USE THESE, don't build from scratch!
|
|
19
|
+
import {
|
|
20
|
+
SiteHeader, // Header with breadcrumbs + search + sidebar trigger
|
|
21
|
+
NavMain, // Main navigation with icons + collapsible sub-items
|
|
22
|
+
NavSecondary, // Secondary nav (Support, Feedback links)
|
|
23
|
+
NavUser, // User profile with dropdown menu
|
|
24
|
+
NavProjects, // Project list navigation
|
|
25
|
+
SearchForm, // Search input for sidebar
|
|
26
|
+
} from '@j3m-quantum/ui'
|
|
27
|
+
\`\`\`
|
|
28
|
+
|
|
29
|
+
## \u26D4 NEVER Create These Manually
|
|
30
|
+
|
|
31
|
+
| Instead of building... | Use this block |
|
|
32
|
+
|------------------------|----------------|
|
|
33
|
+
| \u274C Custom sidebar navigation | \u2705 \`NavMain\` |
|
|
34
|
+
| \u274C Custom user menu/profile | \u2705 \`NavUser\` |
|
|
35
|
+
| \u274C Custom page header | \u2705 \`SiteHeader\` |
|
|
36
|
+
| \u274C Custom project list | \u2705 \`NavProjects\` |
|
|
37
|
+
| \u274C Custom secondary links | \u2705 \`NavSecondary\` |
|
|
38
|
+
| \u274C Custom search in sidebar | \u2705 \`SearchForm\` |
|
|
39
|
+
| \u274C Custom CSS tokens | \u2705 Package provides all tokens |
|
|
40
|
+
|
|
41
|
+
## Block Props Reference
|
|
42
|
+
|
|
43
|
+
### NavMain
|
|
44
|
+
\`\`\`tsx
|
|
45
|
+
import { NavMain, type NavItem } from '@j3m-quantum/ui'
|
|
46
|
+
import { Home, Settings, Users } from 'lucide-react'
|
|
47
|
+
|
|
48
|
+
const navItems: NavItem[] = [
|
|
49
|
+
{ title: "Home", url: "/", icon: Home, isActive: true },
|
|
50
|
+
{ title: "Settings", url: "/settings", icon: Settings, items: [
|
|
51
|
+
{ title: "General", url: "/settings/general" },
|
|
52
|
+
{ title: "Team", url: "/settings/team" },
|
|
53
|
+
]},
|
|
54
|
+
{ title: "Users", url: "/users", icon: Users },
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
<NavMain items={navItems} label="Navigation" />
|
|
58
|
+
\`\`\`
|
|
59
|
+
|
|
60
|
+
### NavUser
|
|
61
|
+
\`\`\`tsx
|
|
62
|
+
import { NavUser } from '@j3m-quantum/ui'
|
|
63
|
+
|
|
64
|
+
<NavUser
|
|
65
|
+
user={{
|
|
66
|
+
name: "John Doe",
|
|
67
|
+
email: "john@example.com",
|
|
68
|
+
avatar: "/avatar.jpg" // or "" for initials fallback
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
### SiteHeader
|
|
74
|
+
\`\`\`tsx
|
|
75
|
+
import { SiteHeader, SidebarTrigger } from '@j3m-quantum/ui'
|
|
76
|
+
|
|
77
|
+
<SiteHeader
|
|
78
|
+
trigger={<SidebarTrigger />}
|
|
79
|
+
breadcrumbs={[
|
|
80
|
+
{ label: "Dashboard", href: "/" },
|
|
81
|
+
{ label: "Settings" } // No href = current page
|
|
82
|
+
]}
|
|
83
|
+
showSearch={true}
|
|
84
|
+
/>
|
|
85
|
+
\`\`\`
|
|
86
|
+
|
|
87
|
+
### NavSecondary
|
|
88
|
+
\`\`\`tsx
|
|
89
|
+
import { NavSecondary } from '@j3m-quantum/ui'
|
|
90
|
+
import { LifeBuoy, Send } from 'lucide-react'
|
|
91
|
+
|
|
92
|
+
<NavSecondary items={[
|
|
93
|
+
{ title: "Support", url: "/support", icon: LifeBuoy },
|
|
94
|
+
{ title: "Feedback", url: "/feedback", icon: Send },
|
|
95
|
+
]} />
|
|
96
|
+
\`\`\`
|
|
97
|
+
|
|
98
|
+
## Sidebar Features Checklist
|
|
99
|
+
|
|
100
|
+
When using Sidebar, remember these features:
|
|
101
|
+
|
|
102
|
+
| Feature | Usage |
|
|
103
|
+
|---------|-------|
|
|
104
|
+
| \`collapsible="icon"\` | Collapses sidebar to icons only |
|
|
105
|
+
| \`collapsible="offcanvas"\` | Slides sidebar off screen |
|
|
106
|
+
| \`<SidebarRail />\` | Edge rail for drag-to-toggle |
|
|
107
|
+
| \`tooltip\` prop on SidebarMenuButton | Shows tooltips when collapsed |
|
|
108
|
+
| \`<SidebarMenuBadge>\` | Notification counts on menu items |
|
|
109
|
+
| \`<SidebarGroup>\` + \`<SidebarGroupLabel>\` | Organize sections |
|
|
110
|
+
|
|
111
|
+
\`\`\`tsx
|
|
112
|
+
<Sidebar collapsible="icon">
|
|
113
|
+
<SidebarContent>
|
|
114
|
+
<SidebarGroup>
|
|
115
|
+
<SidebarGroupLabel>Platform</SidebarGroupLabel>
|
|
116
|
+
<NavMain items={navItems} />
|
|
117
|
+
</SidebarGroup>
|
|
118
|
+
</SidebarContent>
|
|
119
|
+
<SidebarRail />
|
|
120
|
+
</Sidebar>
|
|
121
|
+
\`\`\`
|
|
19
122
|
|
|
20
123
|
## CSS Import Order (Critical)
|
|
21
|
-
The order in src/index.css must be:
|
|
22
124
|
\`\`\`css
|
|
23
125
|
@import "tailwindcss";
|
|
24
126
|
@import "tw-animate-css"; /* Required for animations */
|
|
25
127
|
@import "@j3m-quantum/ui/styles"; /* J3M theme and tokens */
|
|
128
|
+
|
|
129
|
+
/* REQUIRED: Tell Tailwind to scan the package for utility classes */
|
|
130
|
+
@source "../node_modules/@j3m-quantum/ui/dist/**/*.js";
|
|
26
131
|
\`\`\`
|
|
27
132
|
|
|
133
|
+
The @source directive is CRITICAL - without it, Tailwind v4 won't generate CSS for component classes.
|
|
134
|
+
|
|
28
135
|
## Theme Modes (4 Modes)
|
|
29
136
|
| Mode | Classes | Description |
|
|
30
137
|
|------|---------|-------------|
|
|
@@ -58,28 +165,17 @@ When you see these Figma layer names, use these components:
|
|
|
58
165
|
|
|
59
166
|
| Figma Layer Name | Import |
|
|
60
167
|
|------------------|--------|
|
|
61
|
-
| "Button", "CTA", "Primary Button"
|
|
62
|
-
| "Card", "Container", "Panel"
|
|
63
|
-
| "Input", "Text Field"
|
|
64
|
-
| "Dialog", "Modal", "Popup" | \`
|
|
65
|
-
| "Sheet", "Side Panel", "Drawer" | \`
|
|
66
|
-
| "
|
|
67
|
-
| "
|
|
68
|
-
| "
|
|
69
|
-
| "
|
|
70
|
-
| "
|
|
71
|
-
| "
|
|
72
|
-
| "Select", "Picker" | \`import { Select } from '@j3m-quantum/ui'\` |
|
|
73
|
-
| "Checkbox", "Check" | \`import { Checkbox } from '@j3m-quantum/ui'\` |
|
|
74
|
-
| "Switch", "Toggle" | \`import { Switch } from '@j3m-quantum/ui'\` |
|
|
75
|
-
| "Badge", "Tag", "Label" | \`import { Badge } from '@j3m-quantum/ui'\` |
|
|
76
|
-
| "Avatar", "Profile Image" | \`import { Avatar } from '@j3m-quantum/ui'\` |
|
|
77
|
-
| "Progress", "Progress Bar" | \`import { Progress } from '@j3m-quantum/ui'\` |
|
|
78
|
-
| "Tabs", "Tab Bar" | \`import { Tabs, TabsList, TabsTrigger, TabsContent } from '@j3m-quantum/ui'\` |
|
|
79
|
-
| "Accordion", "Expandable" | \`import { Accordion } from '@j3m-quantum/ui'\` |
|
|
80
|
-
| "Tooltip", "Hint" | \`import { Tooltip } from '@j3m-quantum/ui'\` |
|
|
81
|
-
| "Calendar", "Date Picker" | \`import { Calendar } from '@j3m-quantum/ui'\` |
|
|
82
|
-
| "Chart", "Graph" | \`import { Chart } from '@j3m-quantum/ui'\` |
|
|
168
|
+
| "Button", "CTA", "Primary Button" | \`Button\` |
|
|
169
|
+
| "Card", "Container", "Panel" | \`Card, CardHeader, CardContent\` |
|
|
170
|
+
| "Input", "Text Field" | \`Input\` |
|
|
171
|
+
| "Dialog", "Modal", "Popup" | \`Dialog, DialogContent, DialogHeader\` |
|
|
172
|
+
| "Sheet", "Side Panel", "Drawer" | \`Sheet, SheetContent\` |
|
|
173
|
+
| "Sidebar", "Navigation", "Nav" | \`SidebarProvider, Sidebar, NavMain\` |
|
|
174
|
+
| "Header", "Page Header", "Toolbar" | \`SiteHeader\` |
|
|
175
|
+
| "User Menu", "Profile", "Avatar Menu" | \`NavUser\` |
|
|
176
|
+
| "Table", "Data Grid" | \`Table\` |
|
|
177
|
+
| "Planning Grid", "Week Table" | \`PlanningTable\` |
|
|
178
|
+
| "Calibration Table" | \`CalibrationTable\` |
|
|
83
179
|
|
|
84
180
|
## Available Components (60+)
|
|
85
181
|
|
|
@@ -109,83 +205,108 @@ Map, MapTileLayer, MapMarker, MapPopup, MapTooltip, MapZoomControl
|
|
|
109
205
|
|
|
110
206
|
## DO
|
|
111
207
|
- Import all components from @j3m-quantum/ui
|
|
208
|
+
- Use pre-built blocks (NavMain, NavUser, SiteHeader) instead of building custom
|
|
112
209
|
- Use Tailwind semantic classes: bg-primary, text-muted-foreground, bg-accent
|
|
113
|
-
- Use CSS variables for custom styling: var(--primary), var(--background)
|
|
114
210
|
- Use \`glass-context\` class on Cards with interactive components in glass mode
|
|
115
|
-
- Check the component list above
|
|
116
|
-
- Use the j3m-app-bg class on root element for proper backgrounds
|
|
211
|
+
- Check the component/block list above BEFORE building anything custom
|
|
117
212
|
|
|
118
213
|
## DON'T
|
|
119
|
-
- Don't create new component files for UI
|
|
214
|
+
- Don't create new component files for UI that exists in @j3m-quantum/ui
|
|
215
|
+
- Don't build custom sidebar/navigation - use NavMain, NavUser, etc.
|
|
120
216
|
- Don't use shadcn CLI - components are already bundled
|
|
121
|
-
- Don't
|
|
217
|
+
- Don't add custom CSS tokens - the package provides everything
|
|
122
218
|
- Don't use arbitrary color values like bg-[#F58446] - use bg-primary
|
|
123
|
-
- Don't modify component border-radius - pill shapes are intentional
|
|
124
|
-
- Don't style portal components manually - they auto-adapt to theme
|
|
125
219
|
|
|
126
|
-
##
|
|
220
|
+
## Complete Dashboard Example (Header on Top)
|
|
127
221
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
import { Card, CardHeader, CardTitle, CardContent, Input, Button } from '@j3m-quantum/ui'
|
|
222
|
+
The recommended layout places the header at the top spanning full width,
|
|
223
|
+
with the sidebar positioned below it:
|
|
131
224
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
</Card>
|
|
225
|
+
\`\`\`
|
|
226
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
227
|
+
\u2502 SiteHeader \u2502 \u2190 Full width, sticky
|
|
228
|
+
\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
|
|
229
|
+
\u2502 \u2502 \u2502
|
|
230
|
+
\u2502 Sidebar \u2502 SidebarInset \u2502
|
|
231
|
+
\u2502 \u2502 (content) \u2502
|
|
232
|
+
\u2502 \u2502 \u2502
|
|
233
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
142
234
|
\`\`\`
|
|
143
235
|
|
|
144
|
-
### Dashboard Layout
|
|
145
236
|
\`\`\`tsx
|
|
146
237
|
import {
|
|
147
|
-
SidebarProvider, Sidebar, SidebarContent, SidebarFooter, SidebarInset,
|
|
148
|
-
SiteHeader, SidebarTrigger, NavMain, NavUser
|
|
238
|
+
SidebarProvider, Sidebar, SidebarContent, SidebarFooter, SidebarInset, SidebarRail,
|
|
239
|
+
SiteHeader, SidebarTrigger, NavMain, NavUser, NavSecondary,
|
|
240
|
+
SIDEBAR_BELOW_HEADER_CLASS, type NavItem
|
|
149
241
|
} from '@j3m-quantum/ui'
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
242
|
+
import { Home, Settings, LifeBuoy, Send } from 'lucide-react'
|
|
243
|
+
|
|
244
|
+
const navItems: NavItem[] = [
|
|
245
|
+
{ title: "Home", url: "/", icon: Home, isActive: true },
|
|
246
|
+
{ title: "Settings", url: "/settings", icon: Settings },
|
|
247
|
+
]
|
|
248
|
+
|
|
249
|
+
function App() {
|
|
250
|
+
return (
|
|
251
|
+
<div
|
|
252
|
+
className="j3m-app-bg min-h-screen"
|
|
253
|
+
style={{ "--header-height": "3.5rem" } as React.CSSProperties}
|
|
254
|
+
>
|
|
255
|
+
<SidebarProvider className="flex flex-col min-h-screen">
|
|
256
|
+
{/* Header FIRST - spans full width */}
|
|
257
|
+
<SiteHeader
|
|
258
|
+
trigger={<SidebarTrigger />}
|
|
259
|
+
breadcrumbs={[{ label: "Dashboard" }]}
|
|
260
|
+
/>
|
|
261
|
+
|
|
262
|
+
{/* Sidebar + Content below header */}
|
|
263
|
+
<div className="flex flex-1">
|
|
264
|
+
<Sidebar collapsible="icon" className={SIDEBAR_BELOW_HEADER_CLASS}>
|
|
265
|
+
<SidebarContent>
|
|
266
|
+
<NavMain items={navItems} />
|
|
267
|
+
</SidebarContent>
|
|
268
|
+
<SidebarFooter>
|
|
269
|
+
<NavSecondary items={[
|
|
270
|
+
{ title: "Support", url: "#", icon: LifeBuoy },
|
|
271
|
+
{ title: "Feedback", url: "#", icon: Send },
|
|
272
|
+
]} />
|
|
273
|
+
<NavUser user={{ name: "John Doe", email: "john@example.com", avatar: "" }} />
|
|
274
|
+
</SidebarFooter>
|
|
275
|
+
<SidebarRail />
|
|
276
|
+
</Sidebar>
|
|
277
|
+
<SidebarInset>
|
|
278
|
+
<main className="p-4">
|
|
279
|
+
{/* Your content here */}
|
|
280
|
+
</main>
|
|
281
|
+
</SidebarInset>
|
|
282
|
+
</div>
|
|
283
|
+
</SidebarProvider>
|
|
284
|
+
</div>
|
|
285
|
+
)
|
|
286
|
+
}
|
|
165
287
|
\`\`\`
|
|
166
288
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
<Button>Open Form</Button>
|
|
174
|
-
</DialogTrigger>
|
|
175
|
-
<DialogContent>
|
|
176
|
-
<DialogHeader>
|
|
177
|
-
<DialogTitle>Edit Profile</DialogTitle>
|
|
178
|
-
</DialogHeader>
|
|
179
|
-
{/* No glass-context needed - Dialog is a portal */}
|
|
180
|
-
<Input placeholder="Name" />
|
|
181
|
-
<Button>Save</Button>
|
|
182
|
-
</DialogContent>
|
|
183
|
-
</Dialog>
|
|
184
|
-
\`\`\`
|
|
289
|
+
Key points:
|
|
290
|
+
- Set \`--header-height: 3.5rem\` on the wrapper div
|
|
291
|
+
- \`SidebarProvider\` needs \`className="flex flex-col min-h-screen"\`
|
|
292
|
+
- \`SiteHeader\` comes FIRST (before the sidebar)
|
|
293
|
+
- Wrap Sidebar + SidebarInset in \`<div className="flex flex-1">\`
|
|
294
|
+
- Add \`SIDEBAR_BELOW_HEADER_CLASS\` to Sidebar (or use: \`className="top-[var(--header-height)] h-[calc(100svh-var(--header-height))]!"\`)
|
|
185
295
|
|
|
186
|
-
##
|
|
296
|
+
## Recommended Prompts for AI
|
|
297
|
+
|
|
298
|
+
**Good prompts:**
|
|
299
|
+
- "Create a dashboard using @j3m-quantum/ui blocks: NavMain, NavUser, SiteHeader"
|
|
300
|
+
- "Use only pre-built blocks from @j3m-quantum/ui, don't create custom components"
|
|
301
|
+
- "Import SiteHeader for the header and NavMain for navigation from @j3m-quantum/ui"
|
|
302
|
+
- "Check the j3m-quantum cursor rules before implementing"
|
|
187
303
|
|
|
188
|
-
|
|
304
|
+
**Bad prompts (avoid these):**
|
|
305
|
+
- "Create a sidebar" \u2192 AI might build from scratch
|
|
306
|
+
- "Add navigation" \u2192 Too vague, specify NavMain
|
|
307
|
+
- "Make a header" \u2192 Specify SiteHeader instead
|
|
308
|
+
|
|
309
|
+
## CLI Commands
|
|
189
310
|
|
|
190
311
|
\`\`\`bash
|
|
191
312
|
npx @j3m-quantum/ui init # Set up these rules (already done!)
|
|
@@ -193,12 +314,53 @@ npx @j3m-quantum/ui list # List all available components
|
|
|
193
314
|
npx @j3m-quantum/ui doctor # Check if setup is correct
|
|
194
315
|
\`\`\`
|
|
195
316
|
`;
|
|
317
|
+
var SOURCE_DIRECTIVE = '@source "../node_modules/@j3m-quantum/ui/dist/**/*.js";';
|
|
318
|
+
function findCssFile(cwd) {
|
|
319
|
+
const possiblePaths = [
|
|
320
|
+
path.join(cwd, "src", "index.css"),
|
|
321
|
+
path.join(cwd, "src", "styles", "globals.css"),
|
|
322
|
+
path.join(cwd, "src", "styles", "index.css"),
|
|
323
|
+
path.join(cwd, "src", "app", "globals.css"),
|
|
324
|
+
path.join(cwd, "app", "globals.css"),
|
|
325
|
+
path.join(cwd, "styles", "globals.css"),
|
|
326
|
+
path.join(cwd, "styles", "index.css")
|
|
327
|
+
];
|
|
328
|
+
for (const cssPath of possiblePaths) {
|
|
329
|
+
if (fs2.existsSync(cssPath)) {
|
|
330
|
+
return cssPath;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
function updateCssFile(cssPath) {
|
|
336
|
+
const content = fs2.readFileSync(cssPath, "utf-8");
|
|
337
|
+
if (content.includes("@j3m-quantum/ui/dist")) {
|
|
338
|
+
return { updated: false, message: "already configured" };
|
|
339
|
+
}
|
|
340
|
+
if (!content.includes("@j3m-quantum/ui/styles")) {
|
|
341
|
+
return { updated: false, message: "missing @j3m-quantum/ui/styles import" };
|
|
342
|
+
}
|
|
343
|
+
const lines = content.split("\n");
|
|
344
|
+
let insertIndex = -1;
|
|
345
|
+
for (let i = 0; i < lines.length; i++) {
|
|
346
|
+
if (lines[i].includes("@j3m-quantum/ui/styles")) {
|
|
347
|
+
insertIndex = i + 1;
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (insertIndex === -1) {
|
|
352
|
+
return { updated: false, message: "could not find insertion point" };
|
|
353
|
+
}
|
|
354
|
+
lines.splice(insertIndex, 0, "", "/* Required: Tell Tailwind v4 to scan package for utility classes */", SOURCE_DIRECTIVE);
|
|
355
|
+
fs2.writeFileSync(cssPath, lines.join("\n"), "utf-8");
|
|
356
|
+
return { updated: true, message: "added @source directive" };
|
|
357
|
+
}
|
|
196
358
|
async function init() {
|
|
197
359
|
const cwd = process.cwd();
|
|
198
|
-
const cursorDir =
|
|
199
|
-
const rulesDir =
|
|
200
|
-
const rulesFile =
|
|
201
|
-
const cursorRulesFile =
|
|
360
|
+
const cursorDir = path.join(cwd, ".cursor");
|
|
361
|
+
const rulesDir = path.join(cursorDir, "rules");
|
|
362
|
+
const rulesFile = path.join(rulesDir, "j3m-quantum.md");
|
|
363
|
+
const cursorRulesFile = path.join(cwd, ".cursorrules");
|
|
202
364
|
console.log("");
|
|
203
365
|
console.log("\u{1F3A8} Setting up @j3m-quantum/ui...");
|
|
204
366
|
console.log("");
|
|
@@ -217,24 +379,49 @@ async function init() {
|
|
|
217
379
|
}
|
|
218
380
|
}
|
|
219
381
|
console.log("");
|
|
382
|
+
console.log("Configuring Tailwind v4...");
|
|
383
|
+
const cssFile = findCssFile(cwd);
|
|
384
|
+
if (cssFile) {
|
|
385
|
+
const relativePath = cssFile.replace(cwd, "").replace(/^\//, "");
|
|
386
|
+
const result = updateCssFile(cssFile);
|
|
387
|
+
if (result.updated) {
|
|
388
|
+
console.log(` \u2713 Updated ${relativePath} - ${result.message}`);
|
|
389
|
+
} else if (result.message === "already configured") {
|
|
390
|
+
console.log(` \u2713 ${relativePath} - already configured`);
|
|
391
|
+
} else {
|
|
392
|
+
console.log(` \u26A0 ${relativePath} - ${result.message}`);
|
|
393
|
+
console.log(" You may need to manually add:");
|
|
394
|
+
console.log(` ${SOURCE_DIRECTIVE}`);
|
|
395
|
+
}
|
|
396
|
+
} else {
|
|
397
|
+
console.log(" \u26A0 Could not find CSS entry file");
|
|
398
|
+
console.log(" Add this to your main CSS file after the @j3m-quantum/ui/styles import:");
|
|
399
|
+
console.log("");
|
|
400
|
+
console.log(` ${SOURCE_DIRECTIVE}`);
|
|
401
|
+
}
|
|
402
|
+
console.log("");
|
|
220
403
|
console.log("\u2705 Setup complete!");
|
|
221
404
|
console.log("");
|
|
405
|
+
console.log("What was configured:");
|
|
406
|
+
console.log(" \u2022 AI cursor rules for correct component usage");
|
|
407
|
+
console.log(" \u2022 Tailwind v4 @source directive to scan package classes");
|
|
408
|
+
console.log("");
|
|
222
409
|
console.log("AI assistants will now:");
|
|
223
410
|
console.log(" \u2022 Use components from @j3m-quantum/ui");
|
|
224
411
|
console.log(" \u2022 Know about all 60+ available components");
|
|
225
412
|
console.log(" \u2022 Map Figma layers to correct components");
|
|
226
413
|
console.log(" \u2022 Follow J3M styling guidelines");
|
|
227
414
|
console.log("");
|
|
228
|
-
console.log("
|
|
229
|
-
console.log(
|
|
230
|
-
console.log('
|
|
231
|
-
console.log('
|
|
232
|
-
console.log(
|
|
415
|
+
console.log("Required CSS imports (if not already present):");
|
|
416
|
+
console.log(' @import "tailwindcss";');
|
|
417
|
+
console.log(' @import "tw-animate-css";');
|
|
418
|
+
console.log(' @import "@j3m-quantum/ui/styles";');
|
|
419
|
+
console.log(` ${SOURCE_DIRECTIVE}`);
|
|
233
420
|
console.log("");
|
|
234
|
-
console.log("
|
|
421
|
+
console.log("Run 'npx @j3m-quantum/ui doctor' to verify setup");
|
|
235
422
|
console.log("");
|
|
236
423
|
} catch (error) {
|
|
237
|
-
console.error("\u274C Failed to set up
|
|
424
|
+
console.error("\u274C Failed to set up:", error.message);
|
|
238
425
|
process.exit(1);
|
|
239
426
|
}
|
|
240
427
|
}
|
|
@@ -410,7 +597,7 @@ async function doctor() {
|
|
|
410
597
|
console.log("");
|
|
411
598
|
console.log("Checking your project setup...");
|
|
412
599
|
console.log("");
|
|
413
|
-
const packageJsonPath =
|
|
600
|
+
const packageJsonPath = path.join(cwd, "package.json");
|
|
414
601
|
if (fs2.existsSync(packageJsonPath)) {
|
|
415
602
|
const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
|
|
416
603
|
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
@@ -475,8 +662,8 @@ async function doctor() {
|
|
|
475
662
|
message: "Not found - run from project root"
|
|
476
663
|
});
|
|
477
664
|
}
|
|
478
|
-
const cursorRulesPath =
|
|
479
|
-
const altCursorRulesPath =
|
|
665
|
+
const cursorRulesPath = path.join(cwd, ".cursor", "rules", "j3m-quantum.md");
|
|
666
|
+
const altCursorRulesPath = path.join(cwd, ".cursorrules");
|
|
480
667
|
if (fs2.existsSync(cursorRulesPath)) {
|
|
481
668
|
results.push({
|
|
482
669
|
name: "Cursor rules configured",
|
|
@@ -508,11 +695,11 @@ async function doctor() {
|
|
|
508
695
|
});
|
|
509
696
|
}
|
|
510
697
|
const possibleCssPaths = [
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
698
|
+
path.join(cwd, "src", "index.css"),
|
|
699
|
+
path.join(cwd, "src", "styles", "globals.css"),
|
|
700
|
+
path.join(cwd, "src", "app", "globals.css"),
|
|
701
|
+
path.join(cwd, "app", "globals.css"),
|
|
702
|
+
path.join(cwd, "styles", "globals.css")
|
|
516
703
|
];
|
|
517
704
|
let cssFound = false;
|
|
518
705
|
let cssContent = "";
|
|
@@ -529,6 +716,7 @@ async function doctor() {
|
|
|
529
716
|
const hasJ3mStyles = cssContent.includes("@j3m-quantum/ui/styles");
|
|
530
717
|
const hasTailwind = cssContent.includes("tailwindcss");
|
|
531
718
|
cssContent.includes("tw-animate-css");
|
|
719
|
+
const hasSourceDirective = cssContent.includes("@j3m-quantum/ui/dist");
|
|
532
720
|
if (hasJ3mStyles && hasTailwind) {
|
|
533
721
|
const tailwindIndex = cssContent.indexOf("tailwindcss");
|
|
534
722
|
const twAnimateIndex = cssContent.indexOf("tw-animate-css");
|
|
@@ -563,6 +751,20 @@ async function doctor() {
|
|
|
563
751
|
fix: 'Add: @import "tailwindcss";'
|
|
564
752
|
});
|
|
565
753
|
}
|
|
754
|
+
if (hasSourceDirective) {
|
|
755
|
+
results.push({
|
|
756
|
+
name: "Tailwind @source directive",
|
|
757
|
+
status: "pass",
|
|
758
|
+
message: `${foundCssPath} - @source configured for package scanning`
|
|
759
|
+
});
|
|
760
|
+
} else {
|
|
761
|
+
results.push({
|
|
762
|
+
name: "Tailwind @source directive",
|
|
763
|
+
status: "fail",
|
|
764
|
+
message: `${foundCssPath} - missing @source directive (components will be unstyled!)`,
|
|
765
|
+
fix: 'Add: @source "../node_modules/@j3m-quantum/ui/dist/**/*.js";'
|
|
766
|
+
});
|
|
767
|
+
}
|
|
566
768
|
} else {
|
|
567
769
|
results.push({
|
|
568
770
|
name: "CSS imports configured",
|
|
@@ -571,8 +773,8 @@ async function doctor() {
|
|
|
571
773
|
fix: "Create src/index.css with required imports"
|
|
572
774
|
});
|
|
573
775
|
}
|
|
574
|
-
const viteConfigPath =
|
|
575
|
-
const viteConfigJsPath =
|
|
776
|
+
const viteConfigPath = path.join(cwd, "vite.config.ts");
|
|
777
|
+
const viteConfigJsPath = path.join(cwd, "vite.config.js");
|
|
576
778
|
if (fs2.existsSync(viteConfigPath) || fs2.existsSync(viteConfigJsPath)) {
|
|
577
779
|
const configPath = fs2.existsSync(viteConfigPath) ? viteConfigPath : viteConfigJsPath;
|
|
578
780
|
const configContent = fs2.readFileSync(configPath, "utf-8");
|
package/dist/cli/postinstall.js
CHANGED
|
@@ -3,23 +3,50 @@
|
|
|
3
3
|
var isCI = process.env.CI || process.env.CONTINUOUS_INTEGRATION;
|
|
4
4
|
if (!isCI) {
|
|
5
5
|
console.log(`
|
|
6
|
-
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
7
|
-
\u2502
|
|
8
|
-
\
|
|
9
|
-
|
|
10
|
-
\
|
|
11
|
-
\
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
6
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
7
|
+
\u2502 \u{1F3A8} @j3m-quantum/ui installed successfully! \u2502
|
|
8
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
9
|
+
|
|
10
|
+
\u{1F4E6} Quick Start - Dashboard Layout (Header on Top):
|
|
11
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
12
|
+
import {
|
|
13
|
+
SidebarProvider, Sidebar, SidebarContent, SidebarFooter, SidebarInset,
|
|
14
|
+
SiteHeader, SidebarTrigger, NavMain, NavUser, SIDEBAR_BELOW_HEADER_CLASS
|
|
15
|
+
} from '@j3m-quantum/ui'
|
|
16
|
+
|
|
17
|
+
<div className="j3m-app-bg min-h-screen" style={{ "--header-height": "3.5rem" }}>
|
|
18
|
+
<SidebarProvider className="flex flex-col min-h-screen">
|
|
19
|
+
{/* Header FIRST - spans full width */}
|
|
20
|
+
<SiteHeader trigger={<SidebarTrigger />} breadcrumbs={[{ label: "Home" }]} />
|
|
21
|
+
|
|
22
|
+
{/* Sidebar + Content below header */}
|
|
23
|
+
<div className="flex flex-1">
|
|
24
|
+
<Sidebar collapsible="icon" className={SIDEBAR_BELOW_HEADER_CLASS}>
|
|
25
|
+
<SidebarContent>
|
|
26
|
+
<NavMain items={[{ title: "Home", url: "/", icon: Home, isActive: true }]} />
|
|
27
|
+
</SidebarContent>
|
|
28
|
+
<SidebarFooter>
|
|
29
|
+
<NavUser user={{ name: "User", email: "user@example.com", avatar: "" }} />
|
|
30
|
+
</SidebarFooter>
|
|
31
|
+
</Sidebar>
|
|
32
|
+
<SidebarInset>
|
|
33
|
+
<main className="p-4">{/* content */}</main>
|
|
34
|
+
</SidebarInset>
|
|
35
|
+
</div>
|
|
36
|
+
</SidebarProvider>
|
|
37
|
+
</div>
|
|
38
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
39
|
+
|
|
40
|
+
\u26A1 IMPORTANT: Run this to set up AI assistance:
|
|
41
|
+
|
|
42
|
+
npx @j3m-quantum/ui init
|
|
43
|
+
|
|
44
|
+
This configures Cursor/Copilot to use the correct components
|
|
45
|
+
and adds the required @source directive for Tailwind v4.
|
|
46
|
+
|
|
47
|
+
\u{1F4CB} Other commands:
|
|
48
|
+
npx @j3m-quantum/ui list - List all 60+ components
|
|
49
|
+
npx @j3m-quantum/ui doctor - Check if setup is correct
|
|
50
|
+
|
|
24
51
|
`);
|
|
25
52
|
}
|