koori-ui 1.0.5 → 1.0.6
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 +163 -148
- package/dist/index.css +3 -0
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
|
|
6
|
+
Comprehensive glassmorphism component library built on <a href="https://www.radix-ui.com">Radix UI</a> for React 19
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
@@ -16,228 +16,243 @@
|
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
|
-
- 🪟 **
|
|
20
|
-
- ♿ **Accessible** — built on Radix UI primitives
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
19
|
+
- 🪟 **27+ components** — General, Layout, Form, Navigation, Data Display, Feedback
|
|
20
|
+
- ♿ **Accessible** — built on Radix UI primitives with keyboard nav and ARIA
|
|
21
|
+
- 🌗 **Dark / Light / System** — `KooriProvider` with localStorage persistence and no FOUC
|
|
22
|
+
- 🎨 **4 color presets** — Slate, Zinc, Neutral, Violet via `data-theme`
|
|
23
|
+
- 🤖 **MCP server** — search component docs from Claude Code
|
|
24
|
+
- ⚡ **React 19 ready** — RSC-safe (`"use client"` banner auto-injected)
|
|
25
|
+
- 📦 **Dual ESM + CJS** — tree-shakeable, TypeScript declarations included
|
|
25
26
|
|
|
26
27
|
---
|
|
27
28
|
|
|
28
|
-
##
|
|
29
|
+
## Quick Start
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
|
-
|
|
32
|
+
npx create-koori-app my-app
|
|
33
|
+
cd my-app && npm run dev
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
Or install manually:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install koori-ui
|
|
40
|
+
```
|
|
35
41
|
|
|
36
42
|
---
|
|
37
43
|
|
|
38
|
-
##
|
|
44
|
+
## Setup
|
|
39
45
|
|
|
40
|
-
Import
|
|
46
|
+
### 1. Import styles
|
|
41
47
|
|
|
42
48
|
```tsx
|
|
49
|
+
// app/layout.tsx (or your entry point)
|
|
43
50
|
import "koori-ui/styles.css";
|
|
44
51
|
```
|
|
45
52
|
|
|
46
|
-
|
|
53
|
+
### 2. Wrap with KooriProvider
|
|
54
|
+
|
|
55
|
+
`KooriProvider` handles dark/light mode, color scheme, localStorage persistence, and prevents flash-of-unstyled-content.
|
|
47
56
|
|
|
48
57
|
```tsx
|
|
49
|
-
import {
|
|
58
|
+
import { KooriProvider } from "koori-ui";
|
|
50
59
|
|
|
51
|
-
export default function
|
|
60
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
52
61
|
return (
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
</
|
|
59
|
-
</
|
|
62
|
+
<html lang="en" suppressHydrationWarning>
|
|
63
|
+
<body>
|
|
64
|
+
<KooriProvider defaultTheme="dark">
|
|
65
|
+
{children}
|
|
66
|
+
</KooriProvider>
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|
|
60
69
|
);
|
|
61
70
|
}
|
|
62
71
|
```
|
|
63
72
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
## Components
|
|
67
|
-
|
|
68
|
-
### GlassPanel
|
|
69
|
-
|
|
70
|
-
A container wrapper with glassmorphism styling.
|
|
73
|
+
### 3. Use the theme hook
|
|
71
74
|
|
|
72
75
|
```tsx
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
</GlassPanel>
|
|
76
|
-
```
|
|
76
|
+
"use client";
|
|
77
|
+
import { useKooriTheme, GlassButton } from "koori-ui";
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
A card with optional `Header`, `Body`, and `Footer` sub-components.
|
|
88
|
-
|
|
89
|
-
```tsx
|
|
90
|
-
import {
|
|
91
|
-
GlassCard,
|
|
92
|
-
GlassCardHeader,
|
|
93
|
-
GlassCardBody,
|
|
94
|
-
GlassCardFooter,
|
|
95
|
-
} from "koori-ui";
|
|
96
|
-
|
|
97
|
-
<GlassCard>
|
|
98
|
-
<GlassCardHeader>Title</GlassCardHeader>
|
|
99
|
-
<GlassCardBody>Content goes here.</GlassCardBody>
|
|
100
|
-
<GlassCardFooter>
|
|
101
|
-
<GlassButton>Action</GlassButton>
|
|
102
|
-
</GlassCardFooter>
|
|
103
|
-
</GlassCard>
|
|
79
|
+
export function ThemeToggle() {
|
|
80
|
+
const { theme, setTheme } = useKooriTheme();
|
|
81
|
+
return (
|
|
82
|
+
<GlassButton onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
|
|
83
|
+
Toggle Theme
|
|
84
|
+
</GlassButton>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
104
87
|
```
|
|
105
88
|
|
|
106
|
-
|
|
|
107
|
-
|
|
108
|
-
| `
|
|
89
|
+
| `KooriProvider` prop | Type | Default | Description |
|
|
90
|
+
|---|---|---|---|
|
|
91
|
+
| `defaultTheme` | `"light" \| "dark" \| "system"` | `"system"` | Initial theme |
|
|
92
|
+
| `defaultColorScheme` | `"default" \| "slate" \| "zinc" \| "neutral" \| "violet"` | `"default"` | Initial color preset |
|
|
109
93
|
|
|
110
94
|
---
|
|
111
95
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
A button with hover glow and variants.
|
|
115
|
-
|
|
116
|
-
```tsx
|
|
117
|
-
<GlassButton variant="primary" size="lg">Submit</GlassButton>
|
|
118
|
-
```
|
|
96
|
+
## Components
|
|
119
97
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
|
123
|
-
|
|
98
|
+
### General
|
|
99
|
+
|
|
100
|
+
| Component | Description |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `GlassButton` | Button with `variant` (default/primary) and `size` (sm/md/lg) |
|
|
103
|
+
| `GlassBadge` | Pill badge — variants: default, primary, success, warning, danger |
|
|
104
|
+
| `GlassH1` `GlassH2` `GlassH3` `GlassH4` | Heading elements |
|
|
105
|
+
| `GlassText` | Paragraph — `size` (sm/md/lg), `muted` prop |
|
|
106
|
+
| `GlassCode` | Inline code snippet with glass background |
|
|
107
|
+
| `GlassLink` | Anchor with primary color and hover underline |
|
|
108
|
+
| `GlassBlockquote` | Blockquote with primary left border |
|
|
109
|
+
|
|
110
|
+
### Layout
|
|
111
|
+
|
|
112
|
+
| Component | Description |
|
|
113
|
+
|---|---|
|
|
114
|
+
| `GlassPanel` | Foundational container — variants: default, subtle, elevated |
|
|
115
|
+
| `GlassCard` + `GlassCardHeader` / `GlassCardBody` / `GlassCardFooter` | Structured card |
|
|
116
|
+
| `GlassSeparator` | Horizontal or vertical divider (`orientation` prop) |
|
|
117
|
+
|
|
118
|
+
### Form
|
|
119
|
+
|
|
120
|
+
| Component | Description |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `GlassInput` | Text input, all native types supported |
|
|
123
|
+
| `GlassTextarea` | Multi-line input (`rows` prop) |
|
|
124
|
+
| `GlassCheckbox` | Accessible checkbox with optional `label` |
|
|
125
|
+
| `GlassSwitch` | Toggle switch with optional `label` |
|
|
126
|
+
| `GlassRadioGroup` + `GlassRadioItem` | Radio group powered by Radix UI |
|
|
127
|
+
| `GlassSelect` + sub-components | Dropdown select powered by Radix UI |
|
|
128
|
+
| `GlassSlider` | Range slider powered by Radix UI |
|
|
129
|
+
|
|
130
|
+
### Navigation
|
|
131
|
+
|
|
132
|
+
| Component | Description |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `GlassTabs` + `GlassTabsList` / `GlassTabsTrigger` / `GlassTabsContent` | Tabbed interface |
|
|
135
|
+
| `GlassBreadcrumb` + `GlassBreadcrumbItem` / `GlassBreadcrumbSeparator` | Navigation breadcrumb |
|
|
136
|
+
| `GlassDropdownMenu` + sub-components | Context menu powered by Radix UI |
|
|
137
|
+
|
|
138
|
+
### Data Display
|
|
139
|
+
|
|
140
|
+
| Component | Description |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `GlassAvatar` + `GlassAvatarImage` / `GlassAvatarFallback` | Avatar with image fallback |
|
|
143
|
+
| `GlassTable` + `GlassThead` / `GlassTbody` / `GlassTr` / `GlassTh` / `GlassTd` | Data table |
|
|
144
|
+
| `GlassStatCard` | KPI card with `value`, `label`, `trend`, `icon` props |
|
|
145
|
+
| `GlassAreaChart` / `GlassBarChart` | Recharts wrappers with glass tooltips |
|
|
146
|
+
|
|
147
|
+
### Feedback
|
|
148
|
+
|
|
149
|
+
| Component | Description |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `GlassAlert` | Alert with variants: info, success, warning, error |
|
|
152
|
+
| `GlassDialog` + sub-components | Modal dialog powered by Radix UI |
|
|
153
|
+
| `GlassPopover` + sub-components | Floating panel powered by Radix UI |
|
|
154
|
+
| `GlassTooltip` + sub-components | Tooltip powered by Radix UI |
|
|
155
|
+
| `GlassToast` + `GlassToaster` | Toast notifications powered by Radix UI |
|
|
156
|
+
| `GlassProgress` | Progress bar — variants: default, success, warning, error |
|
|
157
|
+
| `GlassSkeleton` | Animated loading placeholder |
|
|
124
158
|
|
|
125
159
|
---
|
|
126
160
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
A styled text input with subtle focus ring.
|
|
130
|
-
|
|
131
|
-
```tsx
|
|
132
|
-
<GlassInput placeholder="Search..." type="email" />
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Supports all native `<input>` props. Works controlled and uncontrolled.
|
|
136
|
-
|
|
137
|
-
---
|
|
161
|
+
## Theming
|
|
138
162
|
|
|
139
|
-
###
|
|
163
|
+
### Color presets
|
|
140
164
|
|
|
141
|
-
|
|
165
|
+
Apply a preset via `KooriProvider` or directly on `<html>`:
|
|
142
166
|
|
|
143
167
|
```tsx
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
GlassDialogContent,
|
|
148
|
-
GlassDialogTitle,
|
|
149
|
-
GlassDialogDescription,
|
|
150
|
-
GlassDialogClose,
|
|
151
|
-
} from "koori-ui";
|
|
152
|
-
|
|
153
|
-
<GlassDialog>
|
|
154
|
-
<GlassDialogTrigger asChild>
|
|
155
|
-
<GlassButton>Open</GlassButton>
|
|
156
|
-
</GlassDialogTrigger>
|
|
157
|
-
<GlassDialogContent>
|
|
158
|
-
<GlassDialogTitle>Confirm</GlassDialogTitle>
|
|
159
|
-
<GlassDialogDescription>Are you sure?</GlassDialogDescription>
|
|
160
|
-
<GlassDialogClose asChild>
|
|
161
|
-
<GlassButton>Close</GlassButton>
|
|
162
|
-
</GlassDialogClose>
|
|
163
|
-
</GlassDialogContent>
|
|
164
|
-
</GlassDialog>
|
|
168
|
+
<KooriProvider defaultColorScheme="violet">...</KooriProvider>
|
|
169
|
+
// or
|
|
170
|
+
<html data-theme="slate">
|
|
165
171
|
```
|
|
166
172
|
|
|
167
|
-
|
|
173
|
+
Available presets: `slate`, `zinc`, `neutral`, `violet`
|
|
168
174
|
|
|
169
|
-
###
|
|
175
|
+
### CSS custom properties
|
|
170
176
|
|
|
171
|
-
|
|
177
|
+
Override any token to match your brand:
|
|
172
178
|
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
{ name: "Feb", revenue: 3000, users: 1398 },
|
|
179
|
-
];
|
|
180
|
-
|
|
181
|
-
<GlassAreaChart
|
|
182
|
-
data={chartData}
|
|
183
|
-
index="name"
|
|
184
|
-
categories={[{ key: "revenue", color: "var(--koori-primary)", name: "Revenue" }]}
|
|
185
|
-
/>
|
|
179
|
+
```css
|
|
180
|
+
:root {
|
|
181
|
+
--koori-primary: #8b5cf6;
|
|
182
|
+
--koori-accent: #a78bfa;
|
|
183
|
+
}
|
|
186
184
|
```
|
|
187
185
|
|
|
188
|
-
|
|
186
|
+
| Token | Description |
|
|
187
|
+
|---|---|
|
|
188
|
+
| `--koori-bg` | Page background |
|
|
189
|
+
| `--koori-text` | Primary text |
|
|
190
|
+
| `--koori-muted` | Secondary/muted text |
|
|
191
|
+
| `--koori-primary` | Brand primary |
|
|
192
|
+
| `--koori-accent` | Brand accent |
|
|
193
|
+
| `--koori-success` / `--koori-warning` / `--koori-error` / `--koori-info` | Status colors |
|
|
194
|
+
| `--koori-radius-sm/md/lg/xl/full` | Border radius scale |
|
|
189
195
|
|
|
190
|
-
|
|
196
|
+
### Glass CSS classes
|
|
191
197
|
|
|
192
|
-
|
|
198
|
+
Use directly when building custom components:
|
|
193
199
|
|
|
194
|
-
|
|
200
|
+
| Class | Description |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `.glass` | Standard frosted glass |
|
|
203
|
+
| `.glass-subtle` | Lighter, more transparent |
|
|
204
|
+
| `.glass-elevated` | Strongest blur and drop shadow |
|
|
195
205
|
|
|
196
206
|
---
|
|
197
207
|
|
|
198
|
-
##
|
|
208
|
+
## MCP Server (Claude Code)
|
|
199
209
|
|
|
200
|
-
|
|
210
|
+
Search Koori UI component docs from within Claude Code:
|
|
201
211
|
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
--koori-bg: #0b0f19;
|
|
205
|
-
--koori-text: #e6eaf2;
|
|
206
|
-
--koori-muted: #a1a7b3;
|
|
207
|
-
--koori-primary: #6c8cff;
|
|
208
|
-
}
|
|
212
|
+
```bash
|
|
213
|
+
cd packages/mcp && npm run build
|
|
209
214
|
```
|
|
210
215
|
|
|
211
|
-
|
|
216
|
+
Add to `.claude/settings.json`:
|
|
212
217
|
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"mcpServers": {
|
|
221
|
+
"koori-ui": {
|
|
222
|
+
"command": "node",
|
|
223
|
+
"args": ["./packages/mcp/dist/index.js"]
|
|
224
|
+
}
|
|
225
|
+
}
|
|
216
226
|
}
|
|
217
227
|
```
|
|
218
228
|
|
|
229
|
+
Available tools: `list_components`, `get_component_docs`, `search_components`, `get_component_example`
|
|
230
|
+
|
|
219
231
|
---
|
|
220
232
|
|
|
221
|
-
##
|
|
233
|
+
## create-koori-app
|
|
222
234
|
|
|
223
|
-
|
|
235
|
+
Scaffold a new project interactively:
|
|
224
236
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
237
|
+
```bash
|
|
238
|
+
npx create-koori-app my-app
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Prompts for project name, default theme, and package manager. Outputs a Next.js app with `KooriProvider` pre-configured.
|
|
230
242
|
|
|
231
243
|
---
|
|
232
244
|
|
|
233
245
|
## Build
|
|
234
246
|
|
|
235
247
|
```bash
|
|
236
|
-
npm run build # CJS + ESM + DTS → dist/
|
|
248
|
+
npm run build # CJS + ESM + DTS + CSS → dist/
|
|
237
249
|
npm run typecheck # tsc --noEmit
|
|
238
250
|
npm run dev # watch mode
|
|
251
|
+
npm run release:patch # bump version, build, pack tarball
|
|
239
252
|
```
|
|
240
253
|
|
|
254
|
+
---
|
|
255
|
+
|
|
241
256
|
## License
|
|
242
257
|
|
|
243
258
|
MIT
|
package/dist/index.css
CHANGED
package/dist/index.js
CHANGED
|
@@ -262,11 +262,14 @@ function GlassAreaChart({
|
|
|
262
262
|
index
|
|
263
263
|
}) {
|
|
264
264
|
const [mounted, setMounted] = (0, import_react2.useState)(false);
|
|
265
|
-
(0, import_react2.useEffect)(() =>
|
|
265
|
+
(0, import_react2.useEffect)(() => {
|
|
266
|
+
const raf = requestAnimationFrame(() => setMounted(true));
|
|
267
|
+
return () => cancelAnimationFrame(raf);
|
|
268
|
+
}, []);
|
|
266
269
|
if (!mounted) {
|
|
267
270
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("w-full", className), style: { height, minHeight: height } });
|
|
268
271
|
}
|
|
269
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("w-full", className), style: { height, minHeight: height, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.AreaChart, { data, margin: { top: 10, right: 10, left: 0, bottom: 0 }, children: [
|
|
272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("w-full", className), style: { height, minHeight: height, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", minWidth: 200, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.AreaChart, { data, margin: { top: 10, right: 10, left: 0, bottom: 0 }, children: [
|
|
270
273
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: categories.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("linearGradient", { id: `grad-${cat.key}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
271
274
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "5%", stopColor: cat.color, stopOpacity: 0.3 }),
|
|
272
275
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "95%", stopColor: cat.color, stopOpacity: 0 })
|
|
@@ -318,11 +321,14 @@ function GlassBarChart({
|
|
|
318
321
|
index
|
|
319
322
|
}) {
|
|
320
323
|
const [mounted, setMounted] = (0, import_react2.useState)(false);
|
|
321
|
-
(0, import_react2.useEffect)(() =>
|
|
324
|
+
(0, import_react2.useEffect)(() => {
|
|
325
|
+
const raf = requestAnimationFrame(() => setMounted(true));
|
|
326
|
+
return () => cancelAnimationFrame(raf);
|
|
327
|
+
}, []);
|
|
322
328
|
if (!mounted) {
|
|
323
329
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("w-full", className), style: { height, minHeight: height } });
|
|
324
330
|
}
|
|
325
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("w-full", className), style: { height, minHeight: height, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.BarChart, { data, margin: { top: 10, right: 10, left: 0, bottom: 0 }, barSize: 32, children: [
|
|
331
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("w-full", className), style: { height, minHeight: height, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", minWidth: 200, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.BarChart, { data, margin: { top: 10, right: 10, left: 0, bottom: 0 }, barSize: 32, children: [
|
|
326
332
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "rgba(255,255,255,0.06)" }),
|
|
327
333
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
328
334
|
import_recharts.XAxis,
|