@galvyn-io/design 0.1.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 +316 -0
- package/dist/components/index.cjs +134 -0
- package/dist/components/index.d.cts +47 -0
- package/dist/components/index.d.ts +47 -0
- package/dist/components/index.js +126 -0
- package/dist/galvyn.css +478 -0
- package/dist/index.cjs +26 -0
- package/dist/index.d.cts +30 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +22 -0
- package/dist/preset.cjs +160 -0
- package/dist/preset.d.cts +21 -0
- package/dist/preset.d.ts +21 -0
- package/dist/preset.js +158 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# @galvyn-io/design
|
|
2
|
+
|
|
3
|
+
Dark-first design system with monotone canvas and surgical accent color. Built for internal tools and admin panels.
|
|
4
|
+
|
|
5
|
+
Works with **Next.js + Tailwind CSS + shadcn/ui** out of the box.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
### 1. Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @galvyn-io/design
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Import CSS
|
|
16
|
+
|
|
17
|
+
In your `app/globals.css` (or wherever your global styles live):
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
/* Import BEFORE Tailwind directives and shadcn styles */
|
|
21
|
+
@import "@galvyn-io/design/css";
|
|
22
|
+
|
|
23
|
+
/* Then your existing Tailwind + shadcn imports */
|
|
24
|
+
@tailwind base;
|
|
25
|
+
@tailwind components;
|
|
26
|
+
@tailwind utilities;
|
|
27
|
+
|
|
28
|
+
/* Optional: set accent hue per-project */
|
|
29
|
+
:root {
|
|
30
|
+
--galvyn-accent-hue: 220; /* blue (default) */
|
|
31
|
+
/* Try: 180 (teal), 270 (purple), 340 (pink), 150 (green), 30 (amber) */
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 3. Add Tailwind Preset
|
|
36
|
+
|
|
37
|
+
In your `tailwind.config.ts`:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import type { Config } from 'tailwindcss';
|
|
41
|
+
import galvynPreset from '@galvyn-io/design/preset';
|
|
42
|
+
|
|
43
|
+
export default {
|
|
44
|
+
presets: [galvynPreset], // ← adds galvyn-* utilities
|
|
45
|
+
content: [
|
|
46
|
+
'./app/**/*.{ts,tsx}',
|
|
47
|
+
'./components/**/*.{ts,tsx}',
|
|
48
|
+
// ... your paths
|
|
49
|
+
],
|
|
50
|
+
// ... rest of your config (shadcn, etc.)
|
|
51
|
+
} satisfies Config;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> **Note:** The preset _extends_ your config. It does NOT override shadcn or any existing utilities. All galvyn classes are namespaced with `galvyn-*`.
|
|
55
|
+
|
|
56
|
+
### 4. Use It
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
// Tailwind classes
|
|
60
|
+
<div className="bg-galvyn-bg-000 text-galvyn-text-100">
|
|
61
|
+
<button className="bg-galvyn-accent-400 text-white rounded-galvyn-md">
|
|
62
|
+
Deploy
|
|
63
|
+
</button>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
// Gradient border utility class
|
|
67
|
+
<div className="galvyn-border-gradient rounded-galvyn-lg bg-galvyn-surface-100 p-4">
|
|
68
|
+
Card with gradient border
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
// React components (optional)
|
|
72
|
+
import { Button, Card, Badge } from '@galvyn-io/design/components';
|
|
73
|
+
|
|
74
|
+
<Card border="strong">
|
|
75
|
+
<Badge variant="success" dot>Healthy</Badge>
|
|
76
|
+
<Button variant="accent">Deploy</Button>
|
|
77
|
+
</Card>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Architecture
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
@galvyn-io/design
|
|
86
|
+
├── /css → CSS custom properties + utility classes (the core)
|
|
87
|
+
├── /preset → Tailwind preset (extends, never overrides)
|
|
88
|
+
├── /components → React primitives (Button, Card, Badge, etc.)
|
|
89
|
+
├── /tokens → Token constants + helper functions
|
|
90
|
+
└── index → Re-exports tokens, types, helpers
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Three import paths, each independent:
|
|
94
|
+
|
|
95
|
+
| Import | What | Required? |
|
|
96
|
+
|--------|------|-----------|
|
|
97
|
+
| `@galvyn-io/design/css` | CSS variables + utility classes | **Yes** |
|
|
98
|
+
| `@galvyn-io/design/preset` | Tailwind preset | **Yes** (if using Tailwind) |
|
|
99
|
+
| `@galvyn-io/design/components` | React components | Optional |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Accent Hue System
|
|
104
|
+
|
|
105
|
+
The entire accent palette is driven by a single CSS variable:
|
|
106
|
+
|
|
107
|
+
```css
|
|
108
|
+
:root {
|
|
109
|
+
--galvyn-accent-hue: 220; /* Change this to rotate everything */
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
| Hue | Color | Vibe |
|
|
114
|
+
|-----|-------|------|
|
|
115
|
+
| `220` | Blue | Default / Vercel |
|
|
116
|
+
| `180` | Teal | Cloud / infra |
|
|
117
|
+
| `270` | Purple | Raycast |
|
|
118
|
+
| `340` | Pink | Warm |
|
|
119
|
+
| `150` | Green | Growth |
|
|
120
|
+
| `30` | Amber | Alert |
|
|
121
|
+
|
|
122
|
+
You can also set it per-component or per-section:
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
import { galvynAccent } from '@galvyn-io/design';
|
|
126
|
+
|
|
127
|
+
// Different accent per project
|
|
128
|
+
<div style={galvynAccent('teal')}>
|
|
129
|
+
This section uses teal accent
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
// Or with a raw hue value
|
|
133
|
+
<div style={galvynAccent(300)}>
|
|
134
|
+
Custom hue
|
|
135
|
+
</div>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## shadcn Compatibility
|
|
141
|
+
|
|
142
|
+
Galvyn is designed to coexist with shadcn/ui:
|
|
143
|
+
|
|
144
|
+
- All CSS variables are prefixed `--galvyn-*` (no collision with shadcn's `--` vars)
|
|
145
|
+
- The Tailwind preset uses `extend` (never replaces shadcn utilities)
|
|
146
|
+
- All Tailwind classes are namespaced: `bg-galvyn-*`, `text-galvyn-*`, etc.
|
|
147
|
+
- You can use shadcn components alongside Galvyn components
|
|
148
|
+
|
|
149
|
+
**Recommended approach:** Use shadcn for complex components (Dialog, Dropdown, etc.) and style them with Galvyn CSS variables for consistent theming.
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
// shadcn Dialog, styled with Galvyn tokens
|
|
153
|
+
<Dialog>
|
|
154
|
+
<DialogContent className="bg-galvyn-surface-100 border-galvyn-border-200">
|
|
155
|
+
<DialogTitle className="text-galvyn-text-000">Settings</DialogTitle>
|
|
156
|
+
</DialogContent>
|
|
157
|
+
</Dialog>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Gradient Borders
|
|
163
|
+
|
|
164
|
+
The signature effect. Four tiers:
|
|
165
|
+
|
|
166
|
+
```html
|
|
167
|
+
<!-- Subtle (default cards) -->
|
|
168
|
+
<div class="galvyn-border-gradient">...</div>
|
|
169
|
+
|
|
170
|
+
<!-- Medium (focused elements) -->
|
|
171
|
+
<div class="galvyn-border-gradient galvyn-border-gradient-medium">...</div>
|
|
172
|
+
|
|
173
|
+
<!-- Strong (accent-tinted) -->
|
|
174
|
+
<div class="galvyn-border-gradient galvyn-border-gradient-strong">...</div>
|
|
175
|
+
|
|
176
|
+
<!-- Accent (full gradient) -->
|
|
177
|
+
<div class="galvyn-border-gradient galvyn-border-gradient-accent">...</div>
|
|
178
|
+
|
|
179
|
+
<!-- Shimmer (animated, use sparingly) -->
|
|
180
|
+
<div class="galvyn-border-gradient galvyn-border-shimmer">...</div>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Or with the React helper:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import { GradientBorder } from '@galvyn-io/design/components';
|
|
187
|
+
|
|
188
|
+
<GradientBorder variant="strong" className="p-4 rounded-galvyn-lg">
|
|
189
|
+
Premium content
|
|
190
|
+
</GradientBorder>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Multi-Project Setup
|
|
196
|
+
|
|
197
|
+
Each project installs the same package but can customize:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
galvyn-dashboard/ → --galvyn-accent-hue: 220 (blue)
|
|
201
|
+
jarvis-agent/ → --galvyn-accent-hue: 180 (teal)
|
|
202
|
+
golf-booking-agent/ → --galvyn-accent-hue: 150 (green)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
When you update the package:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# In each project
|
|
209
|
+
npm update @galvyn-io/design
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Or pin to a version in `package.json` and update when ready.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Components
|
|
217
|
+
|
|
218
|
+
All components use CSS variables — they automatically respond to theme and accent changes.
|
|
219
|
+
|
|
220
|
+
### Button
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { Button } from '@galvyn-io/design/components';
|
|
224
|
+
|
|
225
|
+
<Button variant="default" size="md">Default</Button>
|
|
226
|
+
<Button variant="accent">Deploy</Button>
|
|
227
|
+
<Button variant="danger" size="sm">Delete</Button>
|
|
228
|
+
<Button variant="ghost" loading>Loading...</Button>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Badge
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
import { Badge } from '@galvyn-io/design/components';
|
|
235
|
+
|
|
236
|
+
<Badge variant="success" dot>Healthy</Badge>
|
|
237
|
+
<Badge variant="error">3 errors</Badge>
|
|
238
|
+
<Badge variant="accent">New</Badge>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Card
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
import { Card } from '@galvyn-io/design/components';
|
|
245
|
+
|
|
246
|
+
<Card border="subtle" padding="md">Default card</Card>
|
|
247
|
+
<Card border="strong" padding="lg" hover>Clickable card</Card>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Input
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import { Input } from '@galvyn-io/design/components';
|
|
254
|
+
|
|
255
|
+
<Input label="Project" placeholder="my-project" hint="Lowercase only" />
|
|
256
|
+
<Input label="Endpoint" mono placeholder="https://..." />
|
|
257
|
+
<Input label="Region" error="Invalid region" />
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### StatusDot, Kbd
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
import { StatusDot, Kbd } from '@galvyn-io/design/components';
|
|
264
|
+
|
|
265
|
+
<StatusDot status="online" label="API Gateway" />
|
|
266
|
+
<Kbd>⌘</Kbd><Kbd>K</Kbd>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Development
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
git clone https://github.com/galvyn-io/galvyn-design.git
|
|
275
|
+
cd galvyn-design
|
|
276
|
+
npm install
|
|
277
|
+
npm run build # builds to dist/
|
|
278
|
+
npm run dev # watch mode
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Publishing
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
npm run release # builds + publishes to npm
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Token Reference
|
|
290
|
+
|
|
291
|
+
### Color Tokens
|
|
292
|
+
|
|
293
|
+
| Token | Dark | Light | Usage |
|
|
294
|
+
|-------|------|-------|-------|
|
|
295
|
+
| `--galvyn-bg-000` | `#09090b` | `#ffffff` | Page background |
|
|
296
|
+
| `--galvyn-bg-100` | `#0c0c0e` | `#fafafa` | App background |
|
|
297
|
+
| `--galvyn-surface-100` | `#141416` | `#ffffff` | Card/panel bg |
|
|
298
|
+
| `--galvyn-surface-hover` | `#2a2a2d` | `#ededf0` | Hover state |
|
|
299
|
+
| `--galvyn-text-100` | `#fafafa` | `#18181b` | Primary text |
|
|
300
|
+
| `--galvyn-text-200` | `#a1a1aa` | `#52525b` | Secondary text |
|
|
301
|
+
| `--galvyn-text-300` | `#71717a` | `#71717a` | Tertiary text |
|
|
302
|
+
| `--galvyn-accent-400` | hsl-based | hsl-based | Primary accent |
|
|
303
|
+
|
|
304
|
+
### Spacing (4px grid)
|
|
305
|
+
|
|
306
|
+
`space-1` = 4px, `space-2` = 8px, `space-3` = 12px, `space-4` = 16px, `space-6` = 24px, `space-8` = 32px
|
|
307
|
+
|
|
308
|
+
### Radii
|
|
309
|
+
|
|
310
|
+
`sm` = 4px, `md` = 6px, `lg` = 8px, `xl` = 12px, `2xl` = 16px
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## License
|
|
315
|
+
|
|
316
|
+
MIT
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/components/index.tsx
|
|
7
|
+
|
|
8
|
+
// src/tokens/index.ts
|
|
9
|
+
function galvynBorderClass(variant = "subtle") {
|
|
10
|
+
if (variant === "none") return "";
|
|
11
|
+
const base = "galvyn-border-gradient";
|
|
12
|
+
if (variant === "subtle") return base;
|
|
13
|
+
if (variant === "shimmer") return `${base} galvyn-border-shimmer`;
|
|
14
|
+
return `${base} galvyn-border-gradient-${variant}`;
|
|
15
|
+
}
|
|
16
|
+
function cn(...classes) {
|
|
17
|
+
return classes.filter(Boolean).join(" ");
|
|
18
|
+
}
|
|
19
|
+
var GradientBorder = react.forwardRef(
|
|
20
|
+
({ variant = "subtle", className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
21
|
+
"div",
|
|
22
|
+
{
|
|
23
|
+
ref,
|
|
24
|
+
className: cn(galvynBorderClass(variant), className),
|
|
25
|
+
...props,
|
|
26
|
+
children
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
GradientBorder.displayName = "GradientBorder";
|
|
31
|
+
var BUTTON_VARIANT_CLASSES = {
|
|
32
|
+
default: "galvyn-btn-default",
|
|
33
|
+
secondary: "galvyn-btn-secondary",
|
|
34
|
+
ghost: "galvyn-btn-ghost",
|
|
35
|
+
accent: "galvyn-btn-accent",
|
|
36
|
+
danger: "galvyn-btn-danger"
|
|
37
|
+
};
|
|
38
|
+
var BUTTON_SIZE_CLASSES = {
|
|
39
|
+
sm: "galvyn-btn-sm",
|
|
40
|
+
md: "galvyn-btn-md",
|
|
41
|
+
lg: "galvyn-btn-lg"
|
|
42
|
+
};
|
|
43
|
+
var Button = react.forwardRef(
|
|
44
|
+
({ variant = "default", size = "md", loading, icon, children, className, disabled, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
45
|
+
"button",
|
|
46
|
+
{
|
|
47
|
+
ref,
|
|
48
|
+
className: cn(
|
|
49
|
+
"galvyn-btn",
|
|
50
|
+
BUTTON_VARIANT_CLASSES[variant],
|
|
51
|
+
BUTTON_SIZE_CLASSES[size],
|
|
52
|
+
"galvyn-focus-ring galvyn-transition",
|
|
53
|
+
className
|
|
54
|
+
),
|
|
55
|
+
disabled: loading || disabled,
|
|
56
|
+
...props,
|
|
57
|
+
children: [
|
|
58
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}),
|
|
59
|
+
icon && !loading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "galvyn-btn-icon", children: icon }),
|
|
60
|
+
children
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
Button.displayName = "Button";
|
|
66
|
+
var Input = react.forwardRef(
|
|
67
|
+
({ label, hint, error, icon, mono, className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "galvyn-input-wrapper", children: [
|
|
68
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "galvyn-input-label", children: label }),
|
|
69
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("galvyn-input-container", error && "galvyn-input-error"), children: [
|
|
70
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "galvyn-input-icon", children: icon }),
|
|
71
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
72
|
+
"input",
|
|
73
|
+
{
|
|
74
|
+
ref,
|
|
75
|
+
className: cn(
|
|
76
|
+
"galvyn-input galvyn-focus-ring",
|
|
77
|
+
mono && "galvyn-input-mono",
|
|
78
|
+
className
|
|
79
|
+
),
|
|
80
|
+
"aria-invalid": !!error,
|
|
81
|
+
...props
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
] }),
|
|
85
|
+
(hint || error) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("galvyn-input-hint", error && "galvyn-input-hint-error"), children: error || hint })
|
|
86
|
+
] })
|
|
87
|
+
);
|
|
88
|
+
Input.displayName = "Input";
|
|
89
|
+
var Badge = ({
|
|
90
|
+
variant = "default",
|
|
91
|
+
size = "sm",
|
|
92
|
+
dot = false,
|
|
93
|
+
children,
|
|
94
|
+
className,
|
|
95
|
+
...props
|
|
96
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(`galvyn-badge galvyn-badge-${variant} galvyn-badge-${size}`, className), ...props, children: [
|
|
97
|
+
dot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "galvyn-badge-dot" }),
|
|
98
|
+
children
|
|
99
|
+
] });
|
|
100
|
+
var Card = react.forwardRef(
|
|
101
|
+
({ border = "subtle", padding = "md", hover = false, className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
"div",
|
|
103
|
+
{
|
|
104
|
+
ref,
|
|
105
|
+
className: cn(
|
|
106
|
+
"galvyn-card",
|
|
107
|
+
`galvyn-card-pad-${padding}`,
|
|
108
|
+
hover && "galvyn-card-hover",
|
|
109
|
+
galvynBorderClass(border),
|
|
110
|
+
className
|
|
111
|
+
),
|
|
112
|
+
...props,
|
|
113
|
+
children
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
Card.displayName = "Card";
|
|
118
|
+
var Kbd = ({ children, className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: cn("galvyn-kbd", className), ...props, children });
|
|
119
|
+
var StatusDot = ({ status, label, className }) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("galvyn-status", className), children: [
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `galvyn-status-dot galvyn-status-dot-${status}` }),
|
|
121
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "galvyn-status-label", children: label })
|
|
122
|
+
] });
|
|
123
|
+
var Spinner = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "galvyn-spinner", width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [
|
|
124
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "5.5", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "2" }),
|
|
125
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12.5 7a5.5 5.5 0 00-5.5-5.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
126
|
+
] });
|
|
127
|
+
|
|
128
|
+
exports.Badge = Badge;
|
|
129
|
+
exports.Button = Button;
|
|
130
|
+
exports.Card = Card;
|
|
131
|
+
exports.GradientBorder = GradientBorder;
|
|
132
|
+
exports.Input = Input;
|
|
133
|
+
exports.Kbd = Kbd;
|
|
134
|
+
exports.StatusDot = StatusDot;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type GalvynVariant = 'default' | 'secondary' | 'ghost' | 'accent' | 'danger';
|
|
4
|
+
type GalvynSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
type GalvynBorderGradient = 'none' | 'subtle' | 'medium' | 'strong' | 'accent' | 'shimmer';
|
|
6
|
+
|
|
7
|
+
interface GradientBorderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
variant?: GalvynBorderGradient;
|
|
9
|
+
as?: keyof JSX.IntrinsicElements;
|
|
10
|
+
}
|
|
11
|
+
declare const GradientBorder: React.ForwardRefExoticComponent<GradientBorderProps & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
13
|
+
variant?: GalvynVariant;
|
|
14
|
+
size?: GalvynSize;
|
|
15
|
+
loading?: boolean;
|
|
16
|
+
icon?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
19
|
+
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
20
|
+
label?: string;
|
|
21
|
+
hint?: string;
|
|
22
|
+
error?: string;
|
|
23
|
+
icon?: React.ReactNode;
|
|
24
|
+
mono?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
27
|
+
interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
28
|
+
variant?: 'default' | 'accent' | 'success' | 'warning' | 'error';
|
|
29
|
+
size?: 'sm' | 'md';
|
|
30
|
+
dot?: boolean;
|
|
31
|
+
}
|
|
32
|
+
declare const Badge: React.FC<BadgeProps>;
|
|
33
|
+
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
34
|
+
border?: GalvynBorderGradient;
|
|
35
|
+
padding?: GalvynSize;
|
|
36
|
+
hover?: boolean;
|
|
37
|
+
}
|
|
38
|
+
declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
|
|
39
|
+
declare const Kbd: React.FC<React.HTMLAttributes<HTMLElement>>;
|
|
40
|
+
interface StatusDotProps {
|
|
41
|
+
status: 'online' | 'offline' | 'warning' | 'error';
|
|
42
|
+
label?: string;
|
|
43
|
+
className?: string;
|
|
44
|
+
}
|
|
45
|
+
declare const StatusDot: React.FC<StatusDotProps>;
|
|
46
|
+
|
|
47
|
+
export { Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, GradientBorder, type GradientBorderProps, Input, type InputProps, Kbd, StatusDot, type StatusDotProps };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type GalvynVariant = 'default' | 'secondary' | 'ghost' | 'accent' | 'danger';
|
|
4
|
+
type GalvynSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
type GalvynBorderGradient = 'none' | 'subtle' | 'medium' | 'strong' | 'accent' | 'shimmer';
|
|
6
|
+
|
|
7
|
+
interface GradientBorderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
variant?: GalvynBorderGradient;
|
|
9
|
+
as?: keyof JSX.IntrinsicElements;
|
|
10
|
+
}
|
|
11
|
+
declare const GradientBorder: React.ForwardRefExoticComponent<GradientBorderProps & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
13
|
+
variant?: GalvynVariant;
|
|
14
|
+
size?: GalvynSize;
|
|
15
|
+
loading?: boolean;
|
|
16
|
+
icon?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
19
|
+
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
20
|
+
label?: string;
|
|
21
|
+
hint?: string;
|
|
22
|
+
error?: string;
|
|
23
|
+
icon?: React.ReactNode;
|
|
24
|
+
mono?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
27
|
+
interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
28
|
+
variant?: 'default' | 'accent' | 'success' | 'warning' | 'error';
|
|
29
|
+
size?: 'sm' | 'md';
|
|
30
|
+
dot?: boolean;
|
|
31
|
+
}
|
|
32
|
+
declare const Badge: React.FC<BadgeProps>;
|
|
33
|
+
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
34
|
+
border?: GalvynBorderGradient;
|
|
35
|
+
padding?: GalvynSize;
|
|
36
|
+
hover?: boolean;
|
|
37
|
+
}
|
|
38
|
+
declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
|
|
39
|
+
declare const Kbd: React.FC<React.HTMLAttributes<HTMLElement>>;
|
|
40
|
+
interface StatusDotProps {
|
|
41
|
+
status: 'online' | 'offline' | 'warning' | 'error';
|
|
42
|
+
label?: string;
|
|
43
|
+
className?: string;
|
|
44
|
+
}
|
|
45
|
+
declare const StatusDot: React.FC<StatusDotProps>;
|
|
46
|
+
|
|
47
|
+
export { Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, GradientBorder, type GradientBorderProps, Input, type InputProps, Kbd, StatusDot, type StatusDotProps };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/components/index.tsx
|
|
5
|
+
|
|
6
|
+
// src/tokens/index.ts
|
|
7
|
+
function galvynBorderClass(variant = "subtle") {
|
|
8
|
+
if (variant === "none") return "";
|
|
9
|
+
const base = "galvyn-border-gradient";
|
|
10
|
+
if (variant === "subtle") return base;
|
|
11
|
+
if (variant === "shimmer") return `${base} galvyn-border-shimmer`;
|
|
12
|
+
return `${base} galvyn-border-gradient-${variant}`;
|
|
13
|
+
}
|
|
14
|
+
function cn(...classes) {
|
|
15
|
+
return classes.filter(Boolean).join(" ");
|
|
16
|
+
}
|
|
17
|
+
var GradientBorder = forwardRef(
|
|
18
|
+
({ variant = "subtle", className, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
19
|
+
"div",
|
|
20
|
+
{
|
|
21
|
+
ref,
|
|
22
|
+
className: cn(galvynBorderClass(variant), className),
|
|
23
|
+
...props,
|
|
24
|
+
children
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
);
|
|
28
|
+
GradientBorder.displayName = "GradientBorder";
|
|
29
|
+
var BUTTON_VARIANT_CLASSES = {
|
|
30
|
+
default: "galvyn-btn-default",
|
|
31
|
+
secondary: "galvyn-btn-secondary",
|
|
32
|
+
ghost: "galvyn-btn-ghost",
|
|
33
|
+
accent: "galvyn-btn-accent",
|
|
34
|
+
danger: "galvyn-btn-danger"
|
|
35
|
+
};
|
|
36
|
+
var BUTTON_SIZE_CLASSES = {
|
|
37
|
+
sm: "galvyn-btn-sm",
|
|
38
|
+
md: "galvyn-btn-md",
|
|
39
|
+
lg: "galvyn-btn-lg"
|
|
40
|
+
};
|
|
41
|
+
var Button = forwardRef(
|
|
42
|
+
({ variant = "default", size = "md", loading, icon, children, className, disabled, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
43
|
+
"button",
|
|
44
|
+
{
|
|
45
|
+
ref,
|
|
46
|
+
className: cn(
|
|
47
|
+
"galvyn-btn",
|
|
48
|
+
BUTTON_VARIANT_CLASSES[variant],
|
|
49
|
+
BUTTON_SIZE_CLASSES[size],
|
|
50
|
+
"galvyn-focus-ring galvyn-transition",
|
|
51
|
+
className
|
|
52
|
+
),
|
|
53
|
+
disabled: loading || disabled,
|
|
54
|
+
...props,
|
|
55
|
+
children: [
|
|
56
|
+
loading && /* @__PURE__ */ jsx(Spinner, {}),
|
|
57
|
+
icon && !loading && /* @__PURE__ */ jsx("span", { className: "galvyn-btn-icon", children: icon }),
|
|
58
|
+
children
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
);
|
|
63
|
+
Button.displayName = "Button";
|
|
64
|
+
var Input = forwardRef(
|
|
65
|
+
({ label, hint, error, icon, mono, className, ...props }, ref) => /* @__PURE__ */ jsxs("div", { className: "galvyn-input-wrapper", children: [
|
|
66
|
+
label && /* @__PURE__ */ jsx("label", { className: "galvyn-input-label", children: label }),
|
|
67
|
+
/* @__PURE__ */ jsxs("div", { className: cn("galvyn-input-container", error && "galvyn-input-error"), children: [
|
|
68
|
+
icon && /* @__PURE__ */ jsx("span", { className: "galvyn-input-icon", children: icon }),
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
"input",
|
|
71
|
+
{
|
|
72
|
+
ref,
|
|
73
|
+
className: cn(
|
|
74
|
+
"galvyn-input galvyn-focus-ring",
|
|
75
|
+
mono && "galvyn-input-mono",
|
|
76
|
+
className
|
|
77
|
+
),
|
|
78
|
+
"aria-invalid": !!error,
|
|
79
|
+
...props
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
] }),
|
|
83
|
+
(hint || error) && /* @__PURE__ */ jsx("span", { className: cn("galvyn-input-hint", error && "galvyn-input-hint-error"), children: error || hint })
|
|
84
|
+
] })
|
|
85
|
+
);
|
|
86
|
+
Input.displayName = "Input";
|
|
87
|
+
var Badge = ({
|
|
88
|
+
variant = "default",
|
|
89
|
+
size = "sm",
|
|
90
|
+
dot = false,
|
|
91
|
+
children,
|
|
92
|
+
className,
|
|
93
|
+
...props
|
|
94
|
+
}) => /* @__PURE__ */ jsxs("span", { className: cn(`galvyn-badge galvyn-badge-${variant} galvyn-badge-${size}`, className), ...props, children: [
|
|
95
|
+
dot && /* @__PURE__ */ jsx("span", { className: "galvyn-badge-dot" }),
|
|
96
|
+
children
|
|
97
|
+
] });
|
|
98
|
+
var Card = forwardRef(
|
|
99
|
+
({ border = "subtle", padding = "md", hover = false, className, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
100
|
+
"div",
|
|
101
|
+
{
|
|
102
|
+
ref,
|
|
103
|
+
className: cn(
|
|
104
|
+
"galvyn-card",
|
|
105
|
+
`galvyn-card-pad-${padding}`,
|
|
106
|
+
hover && "galvyn-card-hover",
|
|
107
|
+
galvynBorderClass(border),
|
|
108
|
+
className
|
|
109
|
+
),
|
|
110
|
+
...props,
|
|
111
|
+
children
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
);
|
|
115
|
+
Card.displayName = "Card";
|
|
116
|
+
var Kbd = ({ children, className, ...props }) => /* @__PURE__ */ jsx("kbd", { className: cn("galvyn-kbd", className), ...props, children });
|
|
117
|
+
var StatusDot = ({ status, label, className }) => /* @__PURE__ */ jsxs("span", { className: cn("galvyn-status", className), children: [
|
|
118
|
+
/* @__PURE__ */ jsx("span", { className: `galvyn-status-dot galvyn-status-dot-${status}` }),
|
|
119
|
+
label && /* @__PURE__ */ jsx("span", { className: "galvyn-status-label", children: label })
|
|
120
|
+
] });
|
|
121
|
+
var Spinner = () => /* @__PURE__ */ jsxs("svg", { className: "galvyn-spinner", width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [
|
|
122
|
+
/* @__PURE__ */ jsx("circle", { cx: "7", cy: "7", r: "5.5", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "2" }),
|
|
123
|
+
/* @__PURE__ */ jsx("path", { d: "M12.5 7a5.5 5.5 0 00-5.5-5.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
124
|
+
] });
|
|
125
|
+
|
|
126
|
+
export { Badge, Button, Card, GradientBorder, Input, Kbd, StatusDot };
|