cyberui-2045 1.4.0 → 2.0.1
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/AGENT.md +85 -85
- package/LICENSE +21 -21
- package/README.md +160 -72
- package/bin/init.js +178 -0
- package/bin/usage-content.js +120 -0
- package/dist/components/Badge.d.ts +17 -0
- package/dist/components/Button.d.ts +14 -0
- package/dist/components/Card.d.ts +16 -0
- package/dist/components/CircularProgress.d.ts +11 -0
- package/dist/components/Input.d.ts +22 -0
- package/dist/components/LinearProgress.d.ts +13 -0
- package/dist/components/Modal.d.ts +13 -0
- package/dist/components/Notification.d.ts +13 -0
- package/dist/components/SegmentedProgress.d.ts +10 -0
- package/dist/components/Select.d.ts +22 -0
- package/dist/components/Skeleton.d.ts +12 -0
- package/dist/components/TabNavigation.d.ts +21 -0
- package/dist/components/Toggle.d.ts +14 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/contexts/NotificationContext.d.ts +9 -0
- package/dist/cyberui-2045.css +1 -1
- package/dist/hooks/useCyberScrollbar.d.ts +12 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +4525 -3158
- package/dist/index.js +33 -33
- package/dist/utils/cn.d.ts +10 -0
- package/package.json +118 -104
package/AGENT.md
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
# CyberUI 2045 - Agent Guide
|
|
2
|
-
|
|
3
|
-
You are an expert frontend developer building a futuristic, cyberpunk-themed application using the `cyberui-2045` library.
|
|
4
|
-
|
|
5
|
-
## 1. Setup & Installation
|
|
6
|
-
|
|
7
|
-
**Install the package:**
|
|
8
|
-
```bash
|
|
9
|
-
npm install cyberui-2045
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
**Import the styles (CRITICAL):**
|
|
13
|
-
Add this to your root entry file (e.g., `main.tsx`, `App.tsx`):
|
|
14
|
-
```tsx
|
|
15
|
-
import "cyberui-2045/styles.css";
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 2. Vibe Coding Principles (Consumer Edition)
|
|
19
|
-
|
|
20
|
-
* **Dark Mode Only**: CyberUI is designed for dark backgrounds. Always set your page background to a dark color (e.g., `bg-slate-900`, `#050505`).
|
|
21
|
-
* **Use the Library**: Do not build custom UI components if a CyberUI component exists.
|
|
22
|
-
* **Neon Pop**: Use the library's built-in glow effects. Don't override them with flat colors unless necessary.
|
|
23
|
-
* **Responsive**: Use the `ResponsiveValue` prop pattern for mobile-first designs.
|
|
24
|
-
|
|
25
|
-
## 3. Component Reference
|
|
26
|
-
|
|
27
|
-
| Component | Description |
|
|
28
|
-
| :--- | :--- |
|
|
29
|
-
| `Button` | Neon-styled button. Variants: `primary`, `secondary`, `danger`, `ghost`. |
|
|
30
|
-
| `Card` | Glassmorphism container with borders. |
|
|
31
|
-
| `Input` | Cyberpunk text input with focus glows. |
|
|
32
|
-
| `Modal` | CRT-style modal dialog. |
|
|
33
|
-
| `Notification` | Toast notifications. Use `useCyberNotifications` hook. |
|
|
34
|
-
| `CircularProgress` | Dual-ring progress indicator. |
|
|
35
|
-
| `TabNavigation` | Animated tab bar. |
|
|
36
|
-
| `Badge` | Status indicator. Variants: `default`, `success`, `warning`, `danger`. |
|
|
37
|
-
| `Toggle` | Cyberpunk switch. |
|
|
38
|
-
| `Select` | Styled dropdown. |
|
|
39
|
-
| `Skeleton` | Loading placeholder. |
|
|
40
|
-
| `Image` | Image with cyberpunk frame/effects. |
|
|
41
|
-
| `Carousel` | Image carousel. |
|
|
42
|
-
| `Checkbox` | Neon-styled checkbox with SVG icons. |
|
|
43
|
-
| `Divider` | Gradient/solid/dashed content separator. |
|
|
44
|
-
| `GradientText` | Text with cyberpunk gradient effects. |
|
|
45
|
-
| `SectionTitle` | Title with decorative gradient line. |
|
|
46
|
-
| `Steps` | Multi-step progress indicator. |
|
|
47
|
-
| `Timeline` | Vertical event history display. |
|
|
48
|
-
|
|
49
|
-
## 4. Usage Patterns (Few-Shot)
|
|
50
|
-
|
|
51
|
-
### Basic Card with Action
|
|
52
|
-
```tsx
|
|
53
|
-
import { Card, Button, Badge } from "cyberui-2045";
|
|
54
|
-
|
|
55
|
-
export const UserProfile = () => (
|
|
56
|
-
<Card variant="default" className="max-w-md">
|
|
57
|
-
<div className="flex justify-between items-center mb-4">
|
|
58
|
-
<h2 className="text-xl text-cyan-400 font-bold">Operative Status</h2>
|
|
59
|
-
<Badge variant="success">ONLINE</Badge>
|
|
60
|
-
</div>
|
|
61
|
-
<p className="text-gray-300 mb-6">System synchronization at 98%.</p>
|
|
62
|
-
<Button variant="primary" onClick={() => console.log("Syncing...")}>
|
|
63
|
-
INITIATE SYNC
|
|
64
|
-
</Button>
|
|
65
|
-
</Card>
|
|
66
|
-
);
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Responsive Layout
|
|
70
|
-
```tsx
|
|
71
|
-
import { Button } from "cyberui-2045";
|
|
72
|
-
|
|
73
|
-
// Resize button based on screen width
|
|
74
|
-
<Button
|
|
75
|
-
size={{ base: 'sm', md: 'md', lg: 'lg' }}
|
|
76
|
-
variant="secondary"
|
|
77
|
-
>
|
|
78
|
-
Responsive Action
|
|
79
|
-
</Button>
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## 5. Troubleshooting
|
|
83
|
-
|
|
84
|
-
* **Missing Styles?** Ensure `import "cyberui-2045/styles.css"` is present.
|
|
85
|
-
* **Text Invisible?** Check if you are on a white background. Switch to dark mode.
|
|
1
|
+
# CyberUI 2045 - Agent Guide
|
|
2
|
+
|
|
3
|
+
You are an expert frontend developer building a futuristic, cyberpunk-themed application using the `cyberui-2045` library.
|
|
4
|
+
|
|
5
|
+
## 1. Setup & Installation
|
|
6
|
+
|
|
7
|
+
**Install the package:**
|
|
8
|
+
```bash
|
|
9
|
+
npm install cyberui-2045
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
**Import the styles (CRITICAL):**
|
|
13
|
+
Add this to your root entry file (e.g., `main.tsx`, `App.tsx`):
|
|
14
|
+
```tsx
|
|
15
|
+
import "cyberui-2045/styles.css";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 2. Vibe Coding Principles (Consumer Edition)
|
|
19
|
+
|
|
20
|
+
* **Dark Mode Only**: CyberUI is designed for dark backgrounds. Always set your page background to a dark color (e.g., `bg-slate-900`, `#050505`).
|
|
21
|
+
* **Use the Library**: Do not build custom UI components if a CyberUI component exists.
|
|
22
|
+
* **Neon Pop**: Use the library's built-in glow effects. Don't override them with flat colors unless necessary.
|
|
23
|
+
* **Responsive**: Use the `ResponsiveValue` prop pattern for mobile-first designs.
|
|
24
|
+
|
|
25
|
+
## 3. Component Reference
|
|
26
|
+
|
|
27
|
+
| Component | Description |
|
|
28
|
+
| :--- | :--- |
|
|
29
|
+
| `Button` | Neon-styled button. Variants: `primary`, `secondary`, `danger`, `ghost`. |
|
|
30
|
+
| `Card` | Glassmorphism container with borders. |
|
|
31
|
+
| `Input` | Cyberpunk text input with focus glows. |
|
|
32
|
+
| `Modal` | CRT-style modal dialog. |
|
|
33
|
+
| `Notification` | Toast notifications. Use `useCyberNotifications` hook. |
|
|
34
|
+
| `CircularProgress` | Dual-ring progress indicator. |
|
|
35
|
+
| `TabNavigation` | Animated tab bar. |
|
|
36
|
+
| `Badge` | Status indicator. Variants: `default`, `success`, `warning`, `danger`. |
|
|
37
|
+
| `Toggle` | Cyberpunk switch. |
|
|
38
|
+
| `Select` | Styled dropdown. |
|
|
39
|
+
| `Skeleton` | Loading placeholder. |
|
|
40
|
+
| `Image` | Image with cyberpunk frame/effects. |
|
|
41
|
+
| `Carousel` | Image carousel. |
|
|
42
|
+
| `Checkbox` | Neon-styled checkbox with SVG icons. |
|
|
43
|
+
| `Divider` | Gradient/solid/dashed content separator. |
|
|
44
|
+
| `GradientText` | Text with cyberpunk gradient effects. |
|
|
45
|
+
| `SectionTitle` | Title with decorative gradient line. |
|
|
46
|
+
| `Steps` | Multi-step progress indicator. |
|
|
47
|
+
| `Timeline` | Vertical event history display. |
|
|
48
|
+
|
|
49
|
+
## 4. Usage Patterns (Few-Shot)
|
|
50
|
+
|
|
51
|
+
### Basic Card with Action
|
|
52
|
+
```tsx
|
|
53
|
+
import { Card, Button, Badge } from "cyberui-2045";
|
|
54
|
+
|
|
55
|
+
export const UserProfile = () => (
|
|
56
|
+
<Card variant="default" className="max-w-md">
|
|
57
|
+
<div className="flex justify-between items-center mb-4">
|
|
58
|
+
<h2 className="text-xl text-cyan-400 font-bold">Operative Status</h2>
|
|
59
|
+
<Badge variant="success">ONLINE</Badge>
|
|
60
|
+
</div>
|
|
61
|
+
<p className="text-gray-300 mb-6">System synchronization at 98%.</p>
|
|
62
|
+
<Button variant="primary" onClick={() => console.log("Syncing...")}>
|
|
63
|
+
INITIATE SYNC
|
|
64
|
+
</Button>
|
|
65
|
+
</Card>
|
|
66
|
+
);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Responsive Layout
|
|
70
|
+
```tsx
|
|
71
|
+
import { Button } from "cyberui-2045";
|
|
72
|
+
|
|
73
|
+
// Resize button based on screen width
|
|
74
|
+
<Button
|
|
75
|
+
size={{ base: 'sm', md: 'md', lg: 'lg' }}
|
|
76
|
+
variant="secondary"
|
|
77
|
+
>
|
|
78
|
+
Responsive Action
|
|
79
|
+
</Button>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 5. Troubleshooting
|
|
83
|
+
|
|
84
|
+
* **Missing Styles?** Ensure `import "cyberui-2045/styles.css"` is present.
|
|
85
|
+
* **Text Invisible?** Check if you are on a white background. Switch to dark mode.
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Patrick Yang
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Patrick Yang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,72 +1,160 @@
|
|
|
1
|
-
# CyberUI
|
|
2
|
-
|
|
3
|
-
A cyberpunk-themed React UI library with neon-styled components and futuristic aesthetics.
|
|
4
|
-
|
|
5
|
-
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
<details>
|
|
10
|
-
<summary>Check out the Demo Video 🎬</summary>
|
|
11
|
-
<video src="https://github.com/user-attachments/assets/00d3de8d-d243-4ae0-80c4-e6b97b71c0f0">
|
|
12
|
-
</video>
|
|
13
|
-
</details>
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
import
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
1
|
+
# CyberUI
|
|
2
|
+
|
|
3
|
+
A cyberpunk-themed React UI library with neon-styled components and futuristic aesthetics.
|
|
4
|
+
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
## Demo & Documentation
|
|
8
|
+
|
|
9
|
+
<details>
|
|
10
|
+
<summary>Check out the Demo Video 🎬</summary>
|
|
11
|
+
<video src="https://github.com/user-attachments/assets/00d3de8d-d243-4ae0-80c4-e6b97b71c0f0">
|
|
12
|
+
</video>
|
|
13
|
+
</details>
|
|
14
|
+
|
|
15
|
+
- **[Live Demo & Storybook](https://patrickkuei.github.io/CyberUI)** — interactive component docs and examples
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install cyberui-2045
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Import the stylesheet once in your app entry, then use any component:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import 'cyberui-2045/styles.css';
|
|
27
|
+
import { Button, Card, CircularProgress } from 'cyberui-2045';
|
|
28
|
+
|
|
29
|
+
function App() {
|
|
30
|
+
return (
|
|
31
|
+
<Card>
|
|
32
|
+
<CircularProgress progress={75} radius={20}>
|
|
33
|
+
<span>75%</span>
|
|
34
|
+
</CircularProgress>
|
|
35
|
+
<Button variant="primary">Jack In</Button>
|
|
36
|
+
</Card>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
| Component | Category | Docs |
|
|
44
|
+
|-----------|----------|------|
|
|
45
|
+
| Button | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/button--docs) |
|
|
46
|
+
| Input | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/input--docs) |
|
|
47
|
+
| Select | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/select--docs) |
|
|
48
|
+
| Toggle | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/toggle--docs) |
|
|
49
|
+
| Card | Layout | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/card--docs) |
|
|
50
|
+
| Modal | Layout | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/modal--docs) |
|
|
51
|
+
| Badge | Feedback | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/badge--docs) |
|
|
52
|
+
| Notification | Feedback | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/notification--docs) |
|
|
53
|
+
| Skeleton | Feedback | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/skeleton--docs) |
|
|
54
|
+
| CircularProgress | Progress | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/circularprogress--docs) |
|
|
55
|
+
| LinearProgress | Progress | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/linearprogress--docs) |
|
|
56
|
+
| SegmentedProgress | Progress | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/segmentedprogress--docs) |
|
|
57
|
+
| TabNavigation | Navigation | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/tabnavigation--docs) |
|
|
58
|
+
| Carousel | Navigation | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/carousel--docs) |
|
|
59
|
+
| Steps | Navigation | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/steps--docs) |
|
|
60
|
+
| Image | Media | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/image--docs) |
|
|
61
|
+
| Checkbox | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/checkbox--docs) |
|
|
62
|
+
| Divider | Layout | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/divider--docs) |
|
|
63
|
+
| GradientText | Typography | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/gradienttext--docs) |
|
|
64
|
+
| SectionTitle | Typography | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/sectiontitle--docs) |
|
|
65
|
+
| Timeline | Display | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/timeline--docs) |
|
|
66
|
+
|
|
67
|
+
Also includes hooks (`useCyberNotifications`, `useAnimatedProgress`, `useCyberScrollbar`) and `CyberNotificationProvider` context.
|
|
68
|
+
|
|
69
|
+
## AI Coding Setup
|
|
70
|
+
|
|
71
|
+
If you use an AI coding assistant (Claude Code, Cursor, GitHub Copilot), run this once after installing:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx cyberui-2045 init
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
It writes a concise CyberUI usage guide — components, hooks, tokens, and patterns — directly into your AI config file (`CLAUDE.md`, `.cursorrules`, or `.github/copilot-instructions.md`). Idempotent: safe to re-run after upgrades.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx cyberui-2045 init --claude # Claude Code only
|
|
81
|
+
npx cyberui-2045 init --cursor # Cursor only
|
|
82
|
+
npx cyberui-2045 init --copilot # GitHub Copilot only
|
|
83
|
+
npx cyberui-2045 init --all # all three
|
|
84
|
+
npx cyberui-2045 init --dry-run # preview without writing
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Customization
|
|
88
|
+
|
|
89
|
+
CyberUI is an opinionated design system. Layout, spacing, and motion are intentional and fixed. You own the **color palette**.
|
|
90
|
+
|
|
91
|
+
### CSS token overrides
|
|
92
|
+
|
|
93
|
+
Override in your global CSS after importing `cyberui-2045/styles.css`:
|
|
94
|
+
|
|
95
|
+
```css
|
|
96
|
+
:root {
|
|
97
|
+
--color-primary: #ff005d; /* neon pink */
|
|
98
|
+
--color-secondary: #00fff9; /* cyan */
|
|
99
|
+
--color-accent: #fffb00; /* yellow */
|
|
100
|
+
--color-success: #00ff9e; /* green */
|
|
101
|
+
--color-error: #ff4f4f; /* red */
|
|
102
|
+
--color-warning: #ffaa00; /* orange */
|
|
103
|
+
--color-base: #1a1a2e; /* page background */
|
|
104
|
+
--color-surface: #2d2d44; /* card / component surface */
|
|
105
|
+
--color-border-default: #3c3c5e; /* borders */
|
|
106
|
+
--color-default: #e0e0e0; /* primary text */
|
|
107
|
+
--color-muted: #8888aa; /* secondary text */
|
|
108
|
+
--color-inverse: #1a1a2e; /* inverted text */
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
These tokens are **guaranteed stable** across minor versions. All other CSS variables (shadows, gradients, animation values, `--tw-*`) are internal and may change.
|
|
113
|
+
|
|
114
|
+
### className prop
|
|
115
|
+
|
|
116
|
+
All components accept a `className` prop, merged via [`tailwind-merge`](https://github.com/dcastil/tailwind-merge) — your classes win on conflict:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<Button className="mt-8 w-full">Full width with margin</Button>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use `className` for layout and spacing. Overriding color or variant classes is supported but visual coherence becomes your responsibility.
|
|
123
|
+
|
|
124
|
+
### cn() utility
|
|
125
|
+
|
|
126
|
+
CyberUI re-exports its `cn()` helper (clsx + tailwind-merge) for use in your own components:
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { cn } from 'cyberui-2045';
|
|
130
|
+
|
|
131
|
+
<div className={cn('base-classes', isActive && 'active', userClassName)} />
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Changelog
|
|
135
|
+
|
|
136
|
+
See [CHANGELOG.md](./CHANGELOG.md) for the full history.
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
git clone https://github.com/patrickkuei/CyberUI.git
|
|
142
|
+
cd CyberUI
|
|
143
|
+
npm install
|
|
144
|
+
npm run dev # demo app
|
|
145
|
+
npm run storybook # Storybook on :6006
|
|
146
|
+
npm run test # unit + Storybook tests
|
|
147
|
+
npm run build # typecheck + bundle → dist/
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT — see [LICENSE](LICENSE) for details.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
Made with ⚡ by [Patrick Yang](https://github.com/patrickkuei)
|
package/bin/init.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createInterface } from 'node:readline';
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
5
|
+
import { join, dirname } from 'node:path';
|
|
6
|
+
import { getUsageContent } from './usage-content.js';
|
|
7
|
+
|
|
8
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
const MARKER_START = '<!-- cyberui-2045:start -->';
|
|
11
|
+
const MARKER_END = '<!-- cyberui-2045:end -->';
|
|
12
|
+
|
|
13
|
+
const TARGETS = {
|
|
14
|
+
claude: {
|
|
15
|
+
label: 'Claude Code → CLAUDE.md',
|
|
16
|
+
file: 'CLAUDE.md',
|
|
17
|
+
},
|
|
18
|
+
cursor: {
|
|
19
|
+
label: 'Cursor → .cursorrules',
|
|
20
|
+
file: '.cursorrules',
|
|
21
|
+
},
|
|
22
|
+
copilot: {
|
|
23
|
+
label: 'GitHub Copilot → .github/copilot-instructions.md',
|
|
24
|
+
file: '.github/copilot-instructions.md',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// ─── Arg parsing ──────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
const args = process.argv.slice(2);
|
|
31
|
+
const isDryRun = args.includes('--dry-run');
|
|
32
|
+
|
|
33
|
+
let selectedKeys = [];
|
|
34
|
+
if (args.includes('--all')) {
|
|
35
|
+
selectedKeys = Object.keys(TARGETS);
|
|
36
|
+
} else {
|
|
37
|
+
if (args.includes('--claude')) selectedKeys.push('claude');
|
|
38
|
+
if (args.includes('--cursor')) selectedKeys.push('cursor');
|
|
39
|
+
if (args.includes('--copilot')) selectedKeys.push('copilot');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
async function main() {
|
|
45
|
+
console.log('\n cyberui-2045 — AI assistant setup\n');
|
|
46
|
+
|
|
47
|
+
if (selectedKeys.length === 0) {
|
|
48
|
+
if (!process.stdin.isTTY) {
|
|
49
|
+
// Non-interactive (CI / piped input)
|
|
50
|
+
console.log(' Non-interactive environment detected. Run one of:\n');
|
|
51
|
+
console.log(' npx cyberui-2045 init --claude');
|
|
52
|
+
console.log(' npx cyberui-2045 init --cursor');
|
|
53
|
+
console.log(' npx cyberui-2045 init --copilot');
|
|
54
|
+
console.log(' npx cyberui-2045 init --all\n');
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
selectedKeys = await promptTargets();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (selectedKeys.length === 0) {
|
|
61
|
+
console.log('\n Nothing written. Exiting.\n');
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(isDryRun ? '\n [dry-run] Would write:\n' : '');
|
|
66
|
+
|
|
67
|
+
for (const key of selectedKeys) {
|
|
68
|
+
writeTarget(key);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log('\n Done! Your AI assistant now has CyberUI context.\n');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ─── Interactive prompt ───────────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
function promptTargets() {
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
const keys = Object.keys(TARGETS);
|
|
79
|
+
const cwd = process.cwd();
|
|
80
|
+
|
|
81
|
+
console.log(' Which AI config file should the CyberUI usage guide be added to?\n');
|
|
82
|
+
|
|
83
|
+
keys.forEach((key, i) => {
|
|
84
|
+
const target = TARGETS[key];
|
|
85
|
+
const filePath = join(cwd, target.file);
|
|
86
|
+
const exists = existsSync(filePath);
|
|
87
|
+
const hasSection = exists && readFileSync(filePath, 'utf8').includes(MARKER_START);
|
|
88
|
+
const status = hasSection ? ' (update)' : exists ? ' (append)' : ' (create)';
|
|
89
|
+
console.log(` ${i + 1}. ${target.label}${status}`);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
console.log(` ${keys.length + 1}. All of the above`);
|
|
93
|
+
console.log('\n Enter number(s) separated by commas (e.g. 1,3), or press Enter to cancel:');
|
|
94
|
+
|
|
95
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
96
|
+
|
|
97
|
+
rl.question(' > ', (answer) => {
|
|
98
|
+
rl.close();
|
|
99
|
+
|
|
100
|
+
const raw = answer.trim();
|
|
101
|
+
if (!raw) return resolve([]);
|
|
102
|
+
|
|
103
|
+
const chosen = [];
|
|
104
|
+
for (const part of raw.split(',')) {
|
|
105
|
+
const n = parseInt(part.trim(), 10);
|
|
106
|
+
if (n === keys.length + 1) return resolve([...keys]); // "All"
|
|
107
|
+
if (n >= 1 && n <= keys.length) {
|
|
108
|
+
const key = keys[n - 1];
|
|
109
|
+
if (!chosen.includes(key)) chosen.push(key);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
resolve(chosen);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ─── Write / update target file ───────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
function writeTarget(key) {
|
|
121
|
+
const target = TARGETS[key];
|
|
122
|
+
const cwd = process.cwd();
|
|
123
|
+
const filePath = join(cwd, target.file);
|
|
124
|
+
|
|
125
|
+
// Read current package version
|
|
126
|
+
let version = '1.3.2';
|
|
127
|
+
try {
|
|
128
|
+
const pkgPath = new URL('../package.json', import.meta.url).pathname;
|
|
129
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
130
|
+
version = pkg.version ?? version;
|
|
131
|
+
} catch {
|
|
132
|
+
// fallback to hardcoded version
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const block = `${MARKER_START}\n${getUsageContent(version)}\n${MARKER_END}`;
|
|
136
|
+
|
|
137
|
+
if (isDryRun) {
|
|
138
|
+
console.log(` ── ${target.file} ──\n${block}\n`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Ensure parent directory exists (e.g. .github/)
|
|
143
|
+
const dir = dirname(filePath);
|
|
144
|
+
if (!existsSync(dir)) {
|
|
145
|
+
mkdirSync(dir, { recursive: true });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let finalContent;
|
|
149
|
+
|
|
150
|
+
if (existsSync(filePath)) {
|
|
151
|
+
const existing = readFileSync(filePath, 'utf8');
|
|
152
|
+
|
|
153
|
+
if (existing.includes(MARKER_START) && existing.includes(MARKER_END)) {
|
|
154
|
+
// Replace existing section
|
|
155
|
+
const before = existing.slice(0, existing.indexOf(MARKER_START));
|
|
156
|
+
const after = existing.slice(existing.indexOf(MARKER_END) + MARKER_END.length);
|
|
157
|
+
finalContent = `${before}${block}${after}`;
|
|
158
|
+
console.log(` ✓ Updated ${target.file}`);
|
|
159
|
+
} else {
|
|
160
|
+
// Append new section
|
|
161
|
+
finalContent = `${existing.trimEnd()}\n\n${block}\n`;
|
|
162
|
+
console.log(` ✓ Appended ${target.file}`);
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
// Create new file
|
|
166
|
+
finalContent = `${block}\n`;
|
|
167
|
+
console.log(` ✓ Created ${target.file}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
writeFileSync(filePath, finalContent, 'utf8');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ─── Run ──────────────────────────────────────────────────────────────────────
|
|
174
|
+
|
|
175
|
+
main().catch((err) => {
|
|
176
|
+
console.error('\n Error:', err.message, '\n');
|
|
177
|
+
process.exit(1);
|
|
178
|
+
});
|