@cruxkit/core 0.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/LICENSE +21 -0
- package/README.md +964 -0
- package/dist/index.cjs +211 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +828 -0
- package/dist/index.d.ts +828 -0
- package/dist/index.js +211 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,964 @@
|
|
|
1
|
+
<!-- ╔══════════════════════════════ BEG ══════════════════════════════╗ -->
|
|
2
|
+
|
|
3
|
+
<br>
|
|
4
|
+
<div align="center">
|
|
5
|
+
<p>
|
|
6
|
+
<img src="./assets/img/logo.png" alt="logo" style="" height="60" />
|
|
7
|
+
</p>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
<img src="https://img.shields.io/badge/v-0.0.1-black"/>
|
|
12
|
+
<a href="https://github.com/cruxkit-org"><img src="https://img.shields.io/badge/🔥-@cruxkit-black"/></a>
|
|
13
|
+
<br>
|
|
14
|
+
<img src="https://img.shields.io/github/issues/cruxkit-orgz/core?style=flat" alt="Github Repo Issues" />
|
|
15
|
+
<img src="https://img.shields.io/github/stars/cruxkit-orgz/core?style=social" alt="GitHub Repo stars" />
|
|
16
|
+
</div>
|
|
17
|
+
<br>
|
|
18
|
+
|
|
19
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
<!-- ╔══════════════════════════════ DOC ══════════════════════════════╗ -->
|
|
24
|
+
|
|
25
|
+
- ## Overview 👀
|
|
26
|
+
|
|
27
|
+
- #### Why?
|
|
28
|
+
> **@cruxkit/core** is a complete component library built with **pure [@minejs/jsx](https://github.com/minejs-org/jsx)** and styled with **[@mineui](https://github.com/mineui-org)** semantic tokens.
|
|
29
|
+
>
|
|
30
|
+
> It eliminates framework lock-in while providing production-ready, accessible, and fully-typed UI components.
|
|
31
|
+
>
|
|
32
|
+
> No React. No overhead. Pure logic. Every UI pattern you've built 1000 times—this is the last time.
|
|
33
|
+
|
|
34
|
+
- #### When?
|
|
35
|
+
> Use **@cruxkit/core** when you need:
|
|
36
|
+
>
|
|
37
|
+
> • **Modular components** without framework dependencies
|
|
38
|
+
>
|
|
39
|
+
> • **Full TypeScript support** with IntelliSense
|
|
40
|
+
>
|
|
41
|
+
> • **Accessible UI** with ARIA attributes and keyboard navigation
|
|
42
|
+
>
|
|
43
|
+
> • **Theme flexibility** with [@mineui](https://github.com/mineui-org) semantic CSS variables
|
|
44
|
+
>
|
|
45
|
+
> • **Reactive state** powered by [@minejs/signals](https://github.com/minejs-org/signals)
|
|
46
|
+
>
|
|
47
|
+
> • **Fast performance** with zero overhead abstractions
|
|
48
|
+
>
|
|
49
|
+
> and when using [@cruxjs/app](https://github.com/cruxjs-org/app).
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
<br>
|
|
53
|
+
<br>
|
|
54
|
+
|
|
55
|
+
- ## Quick Start 🔥
|
|
56
|
+
|
|
57
|
+
> install [`hmm`](https://github.com/minejs-org/hmm) first.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# in your terminal
|
|
61
|
+
hmm i @cruxkit/core @minejs/jsx @minejs/signals
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// In your (.tsx) files
|
|
66
|
+
import { ... } from '@cruxkit/core';
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
70
|
+
<br>
|
|
71
|
+
|
|
72
|
+
- ### Example
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { Stack, Group, Grid, Container } from '@cruxkit/core';
|
|
76
|
+
|
|
77
|
+
// Vertical layout
|
|
78
|
+
<Stack gap={4}>
|
|
79
|
+
<div>Item 1</div>
|
|
80
|
+
<div>Item 2</div>
|
|
81
|
+
</Stack>
|
|
82
|
+
|
|
83
|
+
// Horizontal layout
|
|
84
|
+
<Group gap={4} justify="between">
|
|
85
|
+
<div>Left</div>
|
|
86
|
+
<div>Right</div>
|
|
87
|
+
</Group>
|
|
88
|
+
|
|
89
|
+
// Responsive grid
|
|
90
|
+
<Grid cols={1} colsMd={2} colsLg={3} gap={6}>
|
|
91
|
+
{items.map(item => <Card key={item.id}>{item.name}</Card>)}
|
|
92
|
+
</Grid>
|
|
93
|
+
|
|
94
|
+
// Max-width container
|
|
95
|
+
<Container maxWidth="lg" class="mx-auto">
|
|
96
|
+
<h1>Centered content</h1>
|
|
97
|
+
</Container>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
<br>
|
|
101
|
+
<br>
|
|
102
|
+
|
|
103
|
+
- ## Documentation 📑
|
|
104
|
+
|
|
105
|
+
- ### API ⛓️
|
|
106
|
+
|
|
107
|
+
| Components | Phase | Section |
|
|
108
|
+
| ----------------------------------------------------------- | ----- | ----------------------------- |
|
|
109
|
+
| Button, Input, Text, Badge, Avatar, Spinner, Skeleton | 1 | [Primitives](#primitives) |
|
|
110
|
+
| Stack, Group, Grid, Container, Spacer, Divider, Center, Box | 2 | [Layout](#layout) |
|
|
111
|
+
| Alert, Toast, Progress, Notification | 3 | [Feedback](#feedback) |
|
|
112
|
+
| Modal, Drawer, Popover, Tooltip, DropdownMenu | 4 | [Overlays](#overlays) |
|
|
113
|
+
| Form, Checkbox, Radio, Switch, Select, Slider, Textarea | 5 | [Forms](#forms) |
|
|
114
|
+
| Nav, Tabs, Breadcrumb, Pagination | 6 | [Navigation](#navigation) |
|
|
115
|
+
| Card, Table, List, Tag, Stat | 7 | [Data Display](#data-display) |
|
|
116
|
+
|
|
117
|
+
- #### Primitives
|
|
118
|
+
|
|
119
|
+
**Button Component**
|
|
120
|
+
```typescript
|
|
121
|
+
import { Button } from '@cruxkit/core';
|
|
122
|
+
|
|
123
|
+
interface ButtonProps {
|
|
124
|
+
variant? : 'solid' | 'outline' | 'ghost' | 'link';
|
|
125
|
+
color? : 'brand' | 'success' | 'warning' | 'error' | 'neutral';
|
|
126
|
+
size? : 'sm' | 'md' | 'lg';
|
|
127
|
+
disabled? : boolean;
|
|
128
|
+
loading? : boolean;
|
|
129
|
+
active? : boolean;
|
|
130
|
+
fullWidth? : boolean;
|
|
131
|
+
leftIcon? : JSXElement;
|
|
132
|
+
rightIcon? : JSXElement;
|
|
133
|
+
onClick? : (e: MouseEvent) => void;
|
|
134
|
+
type? : 'button' | 'submit' | 'reset';
|
|
135
|
+
children? : JSXElement | string;
|
|
136
|
+
class? : string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
<Button variant="solid" color="brand">Click me</Button>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Text Component**
|
|
143
|
+
```typescript
|
|
144
|
+
import { Text } from '@cruxkit/core';
|
|
145
|
+
|
|
146
|
+
interface TextProps {
|
|
147
|
+
as? : 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'label' | 'small';
|
|
148
|
+
size? : 'xs' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';
|
|
149
|
+
weight? : 'light' | 'normal' | 'medium' | 'semibold' | 'bold';
|
|
150
|
+
color? : '1' | '2' | '3' | '4' | 'inverse' | 'brand' | 'success' | 'warning' | 'error';
|
|
151
|
+
italic? : boolean;
|
|
152
|
+
underline? : boolean;
|
|
153
|
+
truncate? : boolean;
|
|
154
|
+
align? : 'start' | 'center' | 'end' | 'justify';
|
|
155
|
+
children? : JSXElement | string;
|
|
156
|
+
class? : string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
<Text as="h1" size="4xl" weight="bold">Heading</Text>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Badge Component**
|
|
163
|
+
```typescript
|
|
164
|
+
import { Badge } from '@cruxkit/core';
|
|
165
|
+
|
|
166
|
+
interface BadgeProps {
|
|
167
|
+
variant? : 'solid' | 'outline' | 'subtle';
|
|
168
|
+
color? : 'brand' | 'success' | 'warning' | 'error' | 'neutral';
|
|
169
|
+
size? : 'sm' | 'md' | 'lg';
|
|
170
|
+
rounded? : 'base' | 'full';
|
|
171
|
+
dot? : boolean;
|
|
172
|
+
leftIcon? : JSXElement;
|
|
173
|
+
rightIcon? : JSXElement;
|
|
174
|
+
children? : JSXElement | string | number;
|
|
175
|
+
class? : string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
<Badge variant="solid" color="success">Active</Badge>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Avatar Component**
|
|
182
|
+
```typescript
|
|
183
|
+
import { Avatar, AvatarGroup } from '@cruxkit/core';
|
|
184
|
+
|
|
185
|
+
interface AvatarProps {
|
|
186
|
+
src? : string;
|
|
187
|
+
alt? : string;
|
|
188
|
+
name? : string;
|
|
189
|
+
size? : 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
190
|
+
rounded? : 'base' | 'full';
|
|
191
|
+
badge? : JSXElement;
|
|
192
|
+
badgePosition? : 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
|
|
193
|
+
onClick? : (e: MouseEvent) => void;
|
|
194
|
+
class? : string;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
<Avatar src="/user.jpg" name="John Doe" size="md" />
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Spinner Component**
|
|
201
|
+
```typescript
|
|
202
|
+
import { Spinner } from '@cruxkit/core';
|
|
203
|
+
|
|
204
|
+
interface SpinnerProps {
|
|
205
|
+
size? : 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
206
|
+
color? : 'current' | 'brand' | 'success' | 'warning' | 'error';
|
|
207
|
+
thickness? : 'thin' | 'normal' | 'thick';
|
|
208
|
+
speed? : 'slow' | 'normal' | 'fast';
|
|
209
|
+
class? : string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
<Spinner size="md" color="brand" />
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Skeleton Component**
|
|
216
|
+
```typescript
|
|
217
|
+
import { Skeleton } from '@cruxkit/core';
|
|
218
|
+
|
|
219
|
+
interface SkeletonProps {
|
|
220
|
+
width? : string;
|
|
221
|
+
height? : string;
|
|
222
|
+
variant? : 'text' | 'circular' | 'rectangular';
|
|
223
|
+
animate? : boolean;
|
|
224
|
+
class? : string;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
<Skeleton variant="text" width="100%" height="20px" />
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Input Component**
|
|
231
|
+
```typescript
|
|
232
|
+
import { Input } from '@cruxkit/core';
|
|
233
|
+
|
|
234
|
+
interface InputProps {
|
|
235
|
+
variant? : 'outline' | 'filled' | 'flushed';
|
|
236
|
+
size? : 'sm' | 'md' | 'lg';
|
|
237
|
+
disabled? : boolean;
|
|
238
|
+
required? : boolean;
|
|
239
|
+
invalid? : boolean;
|
|
240
|
+
fullWidth? : boolean;
|
|
241
|
+
leftIcon? : JSXElement;
|
|
242
|
+
rightIcon? : JSXElement;
|
|
243
|
+
leftAddon? : JSXElement | string;
|
|
244
|
+
rightAddon? : JSXElement | string;
|
|
245
|
+
type? : 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';
|
|
246
|
+
placeholder? : string;
|
|
247
|
+
value? : string | number;
|
|
248
|
+
onChange? : (e: Event) => void;
|
|
249
|
+
onFocus? : (e: FocusEvent) => void;
|
|
250
|
+
onBlur? : (e: FocusEvent) => void;
|
|
251
|
+
class? : string;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
<Input type="email" placeholder="your@email.com" required />
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
- #### Layout
|
|
258
|
+
|
|
259
|
+
**Stack Component (Vertical Layout)**
|
|
260
|
+
```typescript
|
|
261
|
+
import { Stack } from '@cruxkit/core';
|
|
262
|
+
|
|
263
|
+
interface StackProps {
|
|
264
|
+
gap? : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | 20 | 24;
|
|
265
|
+
align? : 'start' | 'center' | 'end' | 'stretch' | 'baseline';
|
|
266
|
+
justify? : 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
|
|
267
|
+
reverse? : boolean;
|
|
268
|
+
wrap? : boolean;
|
|
269
|
+
as? : 'div' | 'section' | 'article' | 'header' | 'footer' | 'nav';
|
|
270
|
+
children? : JSXElement | JSXElement[];
|
|
271
|
+
class? : string;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
<Stack gap={4} align="center">
|
|
275
|
+
<div>Item 1</div>
|
|
276
|
+
<div>Item 2</div>
|
|
277
|
+
</Stack>
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Group Component (Horizontal Layout)**
|
|
281
|
+
```typescript
|
|
282
|
+
import { Group } from '@cruxkit/core';
|
|
283
|
+
|
|
284
|
+
interface GroupProps {
|
|
285
|
+
gap? : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | 20 | 24;
|
|
286
|
+
align? : 'start' | 'center' | 'end' | 'stretch' | 'baseline';
|
|
287
|
+
justify? : 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
|
|
288
|
+
reverse? : boolean;
|
|
289
|
+
wrap? : boolean;
|
|
290
|
+
children? : JSXElement | JSXElement[];
|
|
291
|
+
class? : string;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
<Group gap={4} justify="between">
|
|
295
|
+
<div>Left</div>
|
|
296
|
+
<div>Right</div>
|
|
297
|
+
</Group>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Grid Component**
|
|
301
|
+
```typescript
|
|
302
|
+
import { Grid } from '@cruxkit/core';
|
|
303
|
+
|
|
304
|
+
interface GridProps {
|
|
305
|
+
cols? : 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
306
|
+
colsSm? : GridProps['cols'];
|
|
307
|
+
colsMd? : GridProps['cols'];
|
|
308
|
+
colsLg? : GridProps['cols'];
|
|
309
|
+
colsXl? : GridProps['cols'];
|
|
310
|
+
gap? : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | 20 | 24;
|
|
311
|
+
gapX? : GridProps['gap'];
|
|
312
|
+
gapY? : GridProps['gap'];
|
|
313
|
+
align? : 'start' | 'center' | 'end' | 'stretch';
|
|
314
|
+
justify? : 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
|
|
315
|
+
children? : JSXElement | JSXElement[];
|
|
316
|
+
class? : string;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
<Grid cols={1} colsMd={2} colsLg={3} gap={6}>
|
|
320
|
+
{items.map(item => <Card key={item.id}>{item.name}</Card>)}
|
|
321
|
+
</Grid>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Container Component**
|
|
325
|
+
```typescript
|
|
326
|
+
import { Container } from '@cruxkit/core';
|
|
327
|
+
|
|
328
|
+
interface ContainerProps {
|
|
329
|
+
maxWidth? : 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
|
|
330
|
+
px? : 0 | 1 | 2 | 3 | 4 | 6 | 8 | 12;
|
|
331
|
+
py? : 0 | 1 | 2 | 3 | 4 | 6 | 8 | 12;
|
|
332
|
+
centerContent? : boolean;
|
|
333
|
+
as? : 'div' | 'main' | 'section' | 'article';
|
|
334
|
+
children? : JSXElement | JSXElement[];
|
|
335
|
+
class? : string;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
<Container maxWidth="lg">
|
|
339
|
+
<h1>Centered content</h1>
|
|
340
|
+
</Container>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Divider Component**
|
|
344
|
+
```typescript
|
|
345
|
+
import { Divider } from '@cruxkit/core';
|
|
346
|
+
|
|
347
|
+
interface DividerProps {
|
|
348
|
+
orientation? : 'horizontal' | 'vertical';
|
|
349
|
+
variant? : 'solid' | 'dashed' | 'dotted';
|
|
350
|
+
thickness? : 'thin' | 'medium' | 'thick';
|
|
351
|
+
color? : '1' | '2' | '3' | 'brand' | 'current';
|
|
352
|
+
label? : string | JSXElement;
|
|
353
|
+
labelPosition? : 'start' | 'center' | 'end';
|
|
354
|
+
spacing? : 0 | 1 | 2 | 3 | 4 | 6 | 8 | 12;
|
|
355
|
+
class? : string;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
<Divider label="OR" labelPosition="center" />
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Center Component**
|
|
362
|
+
```typescript
|
|
363
|
+
import { Center } from '@cruxkit/core';
|
|
364
|
+
|
|
365
|
+
interface CenterProps {
|
|
366
|
+
inline? : boolean;
|
|
367
|
+
children? : JSXElement | JSXElement[];
|
|
368
|
+
class? : string;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
<Center class="h-screen">
|
|
372
|
+
<Spinner />
|
|
373
|
+
</Center>
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Box Component**
|
|
377
|
+
```typescript
|
|
378
|
+
import { Box } from '@cruxkit/core';
|
|
379
|
+
|
|
380
|
+
interface BoxProps {
|
|
381
|
+
as? : 'div' | 'section' | 'article' | 'aside';
|
|
382
|
+
children? : JSXElement | JSXElement[];
|
|
383
|
+
class? : string;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
<Box as="section" class="p-4 bg-surface rounded-lg">
|
|
387
|
+
Content here
|
|
388
|
+
</Box>
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
- #### Feedback
|
|
392
|
+
|
|
393
|
+
**Alert Component**
|
|
394
|
+
```typescript
|
|
395
|
+
import { Alert } from '@cruxkit/core';
|
|
396
|
+
|
|
397
|
+
interface AlertProps {
|
|
398
|
+
status? : 'info' | 'success' | 'warning' | 'error';
|
|
399
|
+
variant? : 'solid' | 'subtle' | 'left-accent' | 'top-accent';
|
|
400
|
+
title? : string | JSXElement;
|
|
401
|
+
description? : string | JSXElement;
|
|
402
|
+
icon? : JSXElement;
|
|
403
|
+
showIcon? : boolean;
|
|
404
|
+
closable? : boolean;
|
|
405
|
+
onClose? : () => void;
|
|
406
|
+
actions? : JSXElement;
|
|
407
|
+
children? : JSXElement | string;
|
|
408
|
+
class? : string;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
<Alert status="success" variant="solid" title="Success!">
|
|
412
|
+
Your changes have been saved.
|
|
413
|
+
</Alert>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Toast Component**
|
|
417
|
+
```typescript
|
|
418
|
+
import { Toast } from '@cruxkit/core';
|
|
419
|
+
|
|
420
|
+
interface ToastProps {
|
|
421
|
+
status? : 'info' | 'success' | 'warning' | 'error';
|
|
422
|
+
title? : string | JSXElement;
|
|
423
|
+
description? : string | JSXElement;
|
|
424
|
+
duration? : number;
|
|
425
|
+
closable? : boolean;
|
|
426
|
+
icon? : JSXElement;
|
|
427
|
+
action? : JSXElement;
|
|
428
|
+
onClose? : () => void;
|
|
429
|
+
class? : string;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
<Toast status="success" title="Saved!" duration={5000} />
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Progress Component**
|
|
436
|
+
```typescript
|
|
437
|
+
import { Progress } from '@cruxkit/core';
|
|
438
|
+
|
|
439
|
+
interface ProgressProps {
|
|
440
|
+
value? : number;
|
|
441
|
+
max? : number;
|
|
442
|
+
size? : 'xs' | 'sm' | 'md' | 'lg';
|
|
443
|
+
color? : 'brand' | 'success' | 'warning' | 'error';
|
|
444
|
+
variant? : 'linear' | 'circular';
|
|
445
|
+
label? : string | JSXElement;
|
|
446
|
+
showValue? : boolean;
|
|
447
|
+
indeterminate? : boolean;
|
|
448
|
+
striped? : boolean;
|
|
449
|
+
animated? : boolean;
|
|
450
|
+
class? : string;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
<Progress value={75} showValue />
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**Notification Component**
|
|
457
|
+
```typescript
|
|
458
|
+
import { Notification } from '@cruxkit/core';
|
|
459
|
+
|
|
460
|
+
interface NotificationProps {
|
|
461
|
+
status? : 'info' | 'success' | 'warning' | 'error';
|
|
462
|
+
title? : string | JSXElement;
|
|
463
|
+
description? : string | JSXElement;
|
|
464
|
+
duration? : number;
|
|
465
|
+
position? : 'top' | 'bottom' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
|
|
466
|
+
closable? : boolean;
|
|
467
|
+
onClose? : () => void;
|
|
468
|
+
class? : string;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
<Notification status="info" title="New message" position="top-end" />
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
- #### Overlays
|
|
475
|
+
|
|
476
|
+
**Modal Component**
|
|
477
|
+
```typescript
|
|
478
|
+
import { Modal } from '@cruxkit/core';
|
|
479
|
+
|
|
480
|
+
interface ModalProps {
|
|
481
|
+
isOpen? : boolean;
|
|
482
|
+
onClose? : () => void;
|
|
483
|
+
title? : string | JSXElement;
|
|
484
|
+
description? : string | JSXElement;
|
|
485
|
+
size? : 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
486
|
+
backdrop? : boolean;
|
|
487
|
+
closeOnBackdrop? : boolean;
|
|
488
|
+
actions? : JSXElement;
|
|
489
|
+
children? : JSXElement | string;
|
|
490
|
+
class? : string;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
<Modal isOpen={isOpen()} onClose={() => setIsOpen(false)} title="Confirm">
|
|
494
|
+
Are you sure?
|
|
495
|
+
</Modal>
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Drawer Component**
|
|
499
|
+
```typescript
|
|
500
|
+
import { Drawer } from '@cruxkit/core';
|
|
501
|
+
|
|
502
|
+
interface DrawerProps {
|
|
503
|
+
isOpen? : boolean;
|
|
504
|
+
onClose? : () => void;
|
|
505
|
+
title? : string | JSXElement;
|
|
506
|
+
position? : 'left' | 'right' | 'top' | 'bottom';
|
|
507
|
+
size? : 'sm' | 'md' | 'lg' | 'xl';
|
|
508
|
+
backdrop? : boolean;
|
|
509
|
+
closeOnBackdrop? : boolean;
|
|
510
|
+
children? : JSXElement | string;
|
|
511
|
+
class? : string;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
<Drawer isOpen={isOpen()} position="left" title="Menu">
|
|
515
|
+
Drawer content
|
|
516
|
+
</Drawer>
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
**Popover Component**
|
|
520
|
+
```typescript
|
|
521
|
+
import { Popover } from '@cruxkit/core';
|
|
522
|
+
|
|
523
|
+
interface PopoverProps {
|
|
524
|
+
trigger? : JSXElement;
|
|
525
|
+
position? : 'top' | 'bottom' | 'left' | 'right';
|
|
526
|
+
isOpen? : boolean;
|
|
527
|
+
onOpenChange? : (open: boolean) => void;
|
|
528
|
+
closeOnClickOutside?: boolean;
|
|
529
|
+
closeOnEscape? : boolean;
|
|
530
|
+
children? : JSXElement | string;
|
|
531
|
+
class? : string;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
<Popover trigger={<Button>Open</Button>}>
|
|
535
|
+
Popover content
|
|
536
|
+
</Popover>
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**Tooltip Component**
|
|
540
|
+
```typescript
|
|
541
|
+
import { Tooltip } from '@cruxkit/core';
|
|
542
|
+
|
|
543
|
+
interface TooltipProps {
|
|
544
|
+
content? : string | JSXElement;
|
|
545
|
+
position? : 'top' | 'bottom' | 'left' | 'right';
|
|
546
|
+
delayShow? : number;
|
|
547
|
+
delayHide? : number;
|
|
548
|
+
children? : JSXElement;
|
|
549
|
+
class? : string;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
<Tooltip content="Help text" position="top">
|
|
553
|
+
<Button>Hover me</Button>
|
|
554
|
+
</Tooltip>
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
**DropdownMenu Component**
|
|
558
|
+
```typescript
|
|
559
|
+
import { DropdownMenu } from '@cruxkit/core';
|
|
560
|
+
|
|
561
|
+
interface DropdownMenuProps {
|
|
562
|
+
trigger? : JSXElement;
|
|
563
|
+
items? : any[];
|
|
564
|
+
onItemClick? : (item: any) => void;
|
|
565
|
+
position? : 'top' | 'bottom';
|
|
566
|
+
closeOnClick? : boolean;
|
|
567
|
+
class? : string;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
<DropdownMenu trigger={<Button>Menu</Button>} items={menuItems} />
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
- #### Forms
|
|
574
|
+
|
|
575
|
+
**Form Component**
|
|
576
|
+
```typescript
|
|
577
|
+
import { Form, FormField, FormLabel, FormError, FormHint } from '@cruxkit/core';
|
|
578
|
+
|
|
579
|
+
interface FormProps {
|
|
580
|
+
children? : JSXElement | JSXElement[];
|
|
581
|
+
onSubmit? : (e: SubmitEvent) => void;
|
|
582
|
+
onChange? : (e: Event) => void;
|
|
583
|
+
method? : 'GET' | 'POST';
|
|
584
|
+
action? : string;
|
|
585
|
+
noValidate? : boolean;
|
|
586
|
+
class? : string;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
<Form onSubmit={handleSubmit}>
|
|
590
|
+
<FormField>
|
|
591
|
+
<FormLabel for="email" required>Email</FormLabel>
|
|
592
|
+
<Input id="email" type="email" required />
|
|
593
|
+
<FormHint>We'll never share your email.</FormHint>
|
|
594
|
+
<FormError>Email is invalid</FormError>
|
|
595
|
+
</FormField>
|
|
596
|
+
<Button type="submit">Submit</Button>
|
|
597
|
+
</Form>
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
**Checkbox Component**
|
|
601
|
+
```typescript
|
|
602
|
+
import { Checkbox } from '@cruxkit/core';
|
|
603
|
+
|
|
604
|
+
interface CheckboxProps {
|
|
605
|
+
checked? : boolean;
|
|
606
|
+
onChange? : (checked: boolean) => void;
|
|
607
|
+
label? : string | JSXElement;
|
|
608
|
+
disabled? : boolean;
|
|
609
|
+
name? : string;
|
|
610
|
+
value? : string;
|
|
611
|
+
class? : string;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
<Checkbox label="I agree" onChange={(checked) => console.log(checked)} />
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
**Radio Component**
|
|
618
|
+
```typescript
|
|
619
|
+
import { Radio, RadioGroup } from '@cruxkit/core';
|
|
620
|
+
|
|
621
|
+
interface RadioProps {
|
|
622
|
+
value : string;
|
|
623
|
+
checked? : boolean;
|
|
624
|
+
onChange? : (value: string) => void;
|
|
625
|
+
label? : string | JSXElement;
|
|
626
|
+
disabled? : boolean;
|
|
627
|
+
class? : string;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
interface RadioGroupProps {
|
|
631
|
+
value? : string;
|
|
632
|
+
onChange? : (value: string) => void;
|
|
633
|
+
options : { value: string; label: string }[];
|
|
634
|
+
orientation? : 'vertical' | 'horizontal';
|
|
635
|
+
class? : string;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
<RadioGroup
|
|
639
|
+
options={[
|
|
640
|
+
{ value: 'option1', label: 'Option 1' },
|
|
641
|
+
{ value: 'option2', label: 'Option 2' }
|
|
642
|
+
]}
|
|
643
|
+
onChange={(value) => console.log(value)}
|
|
644
|
+
/>
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
**Switch Component**
|
|
648
|
+
```typescript
|
|
649
|
+
import { Switch } from '@cruxkit/core';
|
|
650
|
+
|
|
651
|
+
interface SwitchProps {
|
|
652
|
+
checked? : boolean;
|
|
653
|
+
onChange? : (checked: boolean) => void;
|
|
654
|
+
label? : string | JSXElement;
|
|
655
|
+
disabled? : boolean;
|
|
656
|
+
name? : string;
|
|
657
|
+
class? : string;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
<Switch label="Enable notifications" onChange={handleToggle} />
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**Select Component**
|
|
664
|
+
```typescript
|
|
665
|
+
import { Select } from '@cruxkit/core';
|
|
666
|
+
|
|
667
|
+
interface SelectOption {
|
|
668
|
+
value : string;
|
|
669
|
+
label : string;
|
|
670
|
+
disabled? : boolean;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
interface SelectProps {
|
|
674
|
+
options : SelectOption[];
|
|
675
|
+
value? : string;
|
|
676
|
+
onChange? : (value: string) => void;
|
|
677
|
+
placeholder? : string;
|
|
678
|
+
disabled? : boolean;
|
|
679
|
+
name? : string;
|
|
680
|
+
class? : string;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
<Select
|
|
684
|
+
options={[
|
|
685
|
+
{ value: 'option1', label: 'Option 1' },
|
|
686
|
+
{ value: 'option2', label: 'Option 2' }
|
|
687
|
+
]}
|
|
688
|
+
onChange={handleChange}
|
|
689
|
+
/>
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
**Slider Component**
|
|
693
|
+
```typescript
|
|
694
|
+
import { Slider } from '@cruxkit/core';
|
|
695
|
+
|
|
696
|
+
interface SliderProps {
|
|
697
|
+
value? : number;
|
|
698
|
+
onChange? : (value: number) => void;
|
|
699
|
+
min? : number;
|
|
700
|
+
max? : number;
|
|
701
|
+
step? : number;
|
|
702
|
+
label? : string | JSXElement;
|
|
703
|
+
showValue? : boolean;
|
|
704
|
+
disabled? : boolean;
|
|
705
|
+
class? : string;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
<Slider min={0} max={100} value={50} onChange={handleChange} showValue />
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
**Textarea Component**
|
|
712
|
+
```typescript
|
|
713
|
+
import { Textarea } from '@cruxkit/core';
|
|
714
|
+
|
|
715
|
+
interface TextareaProps {
|
|
716
|
+
value? : string;
|
|
717
|
+
onChange? : (e: Event) => void;
|
|
718
|
+
placeholder? : string;
|
|
719
|
+
rows? : number;
|
|
720
|
+
cols? : number;
|
|
721
|
+
disabled? : boolean;
|
|
722
|
+
required? : boolean;
|
|
723
|
+
resize? : 'none' | 'vertical' | 'horizontal' | 'both';
|
|
724
|
+
maxLength? : number;
|
|
725
|
+
class? : string;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
<Textarea placeholder="Your message..." rows={4} />
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
- #### Navigation
|
|
732
|
+
|
|
733
|
+
**Nav Component**
|
|
734
|
+
```typescript
|
|
735
|
+
import { Nav } from '@cruxkit/core';
|
|
736
|
+
|
|
737
|
+
interface NavItem {
|
|
738
|
+
label : string | JSXElement;
|
|
739
|
+
href : string;
|
|
740
|
+
active? : boolean;
|
|
741
|
+
disabled? : boolean;
|
|
742
|
+
icon? : JSXElement;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
interface NavProps {
|
|
746
|
+
items : NavItem[];
|
|
747
|
+
orientation? : 'horizontal' | 'vertical';
|
|
748
|
+
class? : string;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
<Nav items={navItems} orientation="horizontal" />
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**Tabs Component**
|
|
755
|
+
```typescript
|
|
756
|
+
import { Tabs } from '@cruxkit/core';
|
|
757
|
+
|
|
758
|
+
interface TabItem {
|
|
759
|
+
id : string;
|
|
760
|
+
label : string | JSXElement;
|
|
761
|
+
content? : JSXElement | string;
|
|
762
|
+
disabled? : boolean;
|
|
763
|
+
icon? : JSXElement;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
interface TabsProps {
|
|
767
|
+
tabs : TabItem[];
|
|
768
|
+
defaultTab? : string;
|
|
769
|
+
activeTab? : string;
|
|
770
|
+
variant? : 'line' | 'solid' | 'outline';
|
|
771
|
+
onTabChange? : (tabId: string) => void;
|
|
772
|
+
class? : string;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
<Tabs tabs={tabs} variant="line" />
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
**Breadcrumb Component**
|
|
779
|
+
```typescript
|
|
780
|
+
import { Breadcrumb } from '@cruxkit/core';
|
|
781
|
+
|
|
782
|
+
interface BreadcrumbItem {
|
|
783
|
+
label : string | JSXElement;
|
|
784
|
+
href? : string;
|
|
785
|
+
active? : boolean;
|
|
786
|
+
icon? : JSXElement;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
interface BreadcrumbProps {
|
|
790
|
+
items : BreadcrumbItem[];
|
|
791
|
+
separator? : JSXElement | string;
|
|
792
|
+
class? : string;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
<Breadcrumb items={breadcrumbItems} />
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
**Pagination Component**
|
|
799
|
+
```typescript
|
|
800
|
+
import { Pagination } from '@cruxkit/core';
|
|
801
|
+
|
|
802
|
+
interface PaginationProps {
|
|
803
|
+
current : number;
|
|
804
|
+
total : number;
|
|
805
|
+
onChange : (page: number) => void;
|
|
806
|
+
siblingCount? : number;
|
|
807
|
+
showFirstLast? : boolean;
|
|
808
|
+
class? : string;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
<Pagination current={1} total={10} onChange={handlePageChange} />
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
- #### Data Display
|
|
815
|
+
|
|
816
|
+
**Card Component**
|
|
817
|
+
```typescript
|
|
818
|
+
import { Card, CardHeader, CardBody, CardFooter } from '@cruxkit/core';
|
|
819
|
+
|
|
820
|
+
interface CardProps {
|
|
821
|
+
variant? : 'elevated' | 'outlined' | 'filled';
|
|
822
|
+
padding? : 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'none';
|
|
823
|
+
rounded? : 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
824
|
+
hover? : boolean;
|
|
825
|
+
clickable? : boolean;
|
|
826
|
+
onClick? : () => void;
|
|
827
|
+
children : JSXElement;
|
|
828
|
+
class? : string;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
<Card variant="outlined" hover>
|
|
832
|
+
<CardHeader divider><h3>Title</h3></CardHeader>
|
|
833
|
+
<CardBody>Content</CardBody>
|
|
834
|
+
<CardFooter divider><Button>Action</Button></CardFooter>
|
|
835
|
+
</Card>
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
**Table Component**
|
|
839
|
+
```typescript
|
|
840
|
+
import { Table } from '@cruxkit/core';
|
|
841
|
+
|
|
842
|
+
interface TableColumn<T> {
|
|
843
|
+
key : keyof T;
|
|
844
|
+
label : string;
|
|
845
|
+
width? : string | number;
|
|
846
|
+
align? : 'left' | 'center' | 'right';
|
|
847
|
+
sortable? : boolean;
|
|
848
|
+
render? : (value: any, row: T, index: number) => JSXElement | string;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
interface TableProps<T> {
|
|
852
|
+
data : T[];
|
|
853
|
+
columns : TableColumn<T>[];
|
|
854
|
+
striped? : boolean;
|
|
855
|
+
hoverable? : boolean;
|
|
856
|
+
sortBy? : keyof T;
|
|
857
|
+
sortOrder? : 'asc' | 'desc';
|
|
858
|
+
onSort? : (column: keyof T, order: 'asc' | 'desc') => void;
|
|
859
|
+
class? : string;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
<Table data={users} columns={columns} striped hoverable />
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
**List Component**
|
|
866
|
+
```typescript
|
|
867
|
+
import { List } from '@cruxkit/core';
|
|
868
|
+
|
|
869
|
+
interface ListItem<T = any> {
|
|
870
|
+
id? : string | number;
|
|
871
|
+
label? : string | JSXElement;
|
|
872
|
+
description? : string | JSXElement;
|
|
873
|
+
icon? : JSXElement;
|
|
874
|
+
avatar? : JSXElement;
|
|
875
|
+
trailing? : JSXElement;
|
|
876
|
+
disabled? : boolean;
|
|
877
|
+
onClick? : () => void;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
interface ListProps<T = any> {
|
|
881
|
+
items : ListItem<T>[];
|
|
882
|
+
variant? : 'simple' | 'divider' | 'spaced';
|
|
883
|
+
size? : 'sm' | 'md' | 'lg';
|
|
884
|
+
selectable? : boolean;
|
|
885
|
+
onItemClick? : (item: ListItem<T>, index: number) => void;
|
|
886
|
+
class? : string;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
<List items={listItems} variant="divider" />
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
**Tag Component**
|
|
893
|
+
```typescript
|
|
894
|
+
import { Tag } from '@cruxkit/core';
|
|
895
|
+
|
|
896
|
+
interface TagProps {
|
|
897
|
+
variant? : 'solid' | 'outline' | 'subtle';
|
|
898
|
+
color? : 'primary' | 'success' | 'warning' | 'error';
|
|
899
|
+
size? : 'sm' | 'md' | 'lg';
|
|
900
|
+
icon? : JSXElement;
|
|
901
|
+
closeable? : boolean;
|
|
902
|
+
onClose? : () => void;
|
|
903
|
+
disabled? : boolean;
|
|
904
|
+
children : JSXElement | string;
|
|
905
|
+
class? : string;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
<Tag variant="solid" color="success" closeable>Active</Tag>
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
**Stat Component**
|
|
912
|
+
```typescript
|
|
913
|
+
import { Stat } from '@cruxkit/core';
|
|
914
|
+
|
|
915
|
+
interface StatProps {
|
|
916
|
+
value : string | number | JSXElement;
|
|
917
|
+
label : string | JSXElement;
|
|
918
|
+
description? : string | JSXElement;
|
|
919
|
+
icon? : JSXElement;
|
|
920
|
+
variant? : 'card' | 'simple' | 'bordered';
|
|
921
|
+
size? : 'sm' | 'md' | 'lg';
|
|
922
|
+
change? : number;
|
|
923
|
+
changeLabel? : string;
|
|
924
|
+
trend? : 'up' | 'down' | 'neutral';
|
|
925
|
+
color? : 'primary' | 'success' | 'warning' | 'error';
|
|
926
|
+
class? : string;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
<Stat value={1250} label="Total Users" trend="up" change={12} />
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
933
|
+
<br>
|
|
934
|
+
|
|
935
|
+
- ### Related 🔗
|
|
936
|
+
|
|
937
|
+
- ##### [@minejs/jsx](https://github.com/minejs-org/jsx)
|
|
938
|
+
> JSX runtime - No React, pure JavaScript implementation
|
|
939
|
+
|
|
940
|
+
- ##### [@minejs/signals](https://github.com/minejs-org/signals)
|
|
941
|
+
> Reactive state management with signals and effects
|
|
942
|
+
|
|
943
|
+
- ##### [@mineui](https://github.com/mineui-org)
|
|
944
|
+
> Semantic CSS variable system for theming and styling
|
|
945
|
+
|
|
946
|
+
- ##### [@cruxjs/app](https://github.com/cruxjs-org/app)
|
|
947
|
+
> Application framework built on @cruxkit components
|
|
948
|
+
|
|
949
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
<!-- ╔══════════════════════════════ END ══════════════════════════════╗ -->
|
|
954
|
+
|
|
955
|
+
<br>
|
|
956
|
+
<br>
|
|
957
|
+
|
|
958
|
+
---
|
|
959
|
+
|
|
960
|
+
<div align="center">
|
|
961
|
+
<a href="https://github.com/maysara-elshewehy"><img src="https://img.shields.io/badge/by-Maysara-black"/></a>
|
|
962
|
+
</div>
|
|
963
|
+
|
|
964
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|