@geajs/ui 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 ADDED
@@ -0,0 +1,535 @@
1
+ # @geajs/ui
2
+
3
+ Accessible UI components for [Gea](https://github.com/dashersw/gea), powered by [Zag.js](https://zagjs.com/) state machines and styled with [Tailwind CSS](https://tailwindcss.com/).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @geajs/ui
9
+ ```
10
+
11
+ Peer dependency:
12
+ ```bash
13
+ npm install @geajs/core
14
+ ```
15
+
16
+ ## Tailwind CSS Setup
17
+
18
+ ### 1. Add @geajs/ui to your Tailwind content paths
19
+
20
+ ```js
21
+ // tailwind.config.js
22
+ import geaPreset from '@geajs/ui/tailwind-preset'
23
+
24
+ export default {
25
+ presets: [geaPreset],
26
+ content: [
27
+ './src/**/*.{tsx,ts,jsx,js}',
28
+ './node_modules/@geajs/ui/dist/**/*.js',
29
+ ],
30
+ }
31
+ ```
32
+
33
+ ### 2. Import the theme CSS
34
+
35
+ In your main CSS file:
36
+
37
+ ```css
38
+ @import '@geajs/ui/style.css';
39
+ ```
40
+
41
+ Or in your entry point:
42
+
43
+ ```ts
44
+ import '@geajs/ui/style.css'
45
+ ```
46
+
47
+ ## Components
48
+
49
+ ### Simple Styled Components
50
+
51
+ These components are thin wrappers with Tailwind styling and variant support.
52
+
53
+ #### Button
54
+
55
+ ```tsx
56
+ import { Button } from '@geajs/ui'
57
+
58
+ class MyApp extends Component {
59
+ template() {
60
+ return (
61
+ <div>
62
+ <Button>Default</Button>
63
+ <Button variant="destructive">Delete</Button>
64
+ <Button variant="outline">Outline</Button>
65
+ <Button variant="secondary">Secondary</Button>
66
+ <Button variant="ghost">Ghost</Button>
67
+ <Button variant="link">Link</Button>
68
+ <Button size="sm">Small</Button>
69
+ <Button size="lg">Large</Button>
70
+ <Button size="icon">🔍</Button>
71
+ </div>
72
+ )
73
+ }
74
+ }
75
+ ```
76
+
77
+ #### Card
78
+
79
+ ```tsx
80
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@geajs/ui'
81
+
82
+ <Card>
83
+ <CardHeader>
84
+ <CardTitle>Card Title</CardTitle>
85
+ <CardDescription>Card description text.</CardDescription>
86
+ </CardHeader>
87
+ <CardContent>
88
+ <p>Card content goes here.</p>
89
+ </CardContent>
90
+ <CardFooter>
91
+ <Button>Action</Button>
92
+ </CardFooter>
93
+ </Card>
94
+ ```
95
+
96
+ #### Input
97
+
98
+ ```tsx
99
+ import { Input } from '@geajs/ui'
100
+
101
+ <Input type="email" placeholder="Email" />
102
+ <Input disabled placeholder="Disabled" />
103
+ ```
104
+
105
+ #### Textarea
106
+
107
+ ```tsx
108
+ import { Textarea } from '@geajs/ui'
109
+
110
+ <Textarea placeholder="Type your message..." rows={4} />
111
+ ```
112
+
113
+ #### Label
114
+
115
+ ```tsx
116
+ import { Label } from '@geajs/ui'
117
+
118
+ <Label htmlFor="email">Email</Label>
119
+ ```
120
+
121
+ #### Badge
122
+
123
+ ```tsx
124
+ import { Badge } from '@geajs/ui'
125
+
126
+ <Badge>Default</Badge>
127
+ <Badge variant="secondary">Secondary</Badge>
128
+ <Badge variant="destructive">Destructive</Badge>
129
+ <Badge variant="outline">Outline</Badge>
130
+ ```
131
+
132
+ #### Alert
133
+
134
+ ```tsx
135
+ import { Alert, AlertTitle, AlertDescription } from '@geajs/ui'
136
+
137
+ <Alert>
138
+ <AlertTitle>Heads up!</AlertTitle>
139
+ <AlertDescription>This is an alert description.</AlertDescription>
140
+ </Alert>
141
+ <Alert variant="destructive">
142
+ <AlertTitle>Error</AlertTitle>
143
+ <AlertDescription>Something went wrong.</AlertDescription>
144
+ </Alert>
145
+ ```
146
+
147
+ #### Separator
148
+
149
+ ```tsx
150
+ import { Separator } from '@geajs/ui'
151
+
152
+ <Separator />
153
+ <Separator orientation="vertical" />
154
+ ```
155
+
156
+ #### Skeleton
157
+
158
+ ```tsx
159
+ import { Skeleton } from '@geajs/ui'
160
+
161
+ <Skeleton class="h-4 w-[250px]" />
162
+ <Skeleton class="h-12 w-12 rounded-full" />
163
+ ```
164
+
165
+ ### Zag-Powered Components
166
+
167
+ These components are backed by Zag.js state machines, providing full keyboard navigation, ARIA attributes, and focus management out of the box.
168
+
169
+ #### Dialog
170
+
171
+ ```tsx
172
+ import { Dialog } from '@geajs/ui'
173
+
174
+ <Dialog
175
+ title="Confirm Action"
176
+ description="Are you sure you want to proceed?"
177
+ triggerLabel="Open Dialog"
178
+ onOpenChange={(details) => console.log(details.open)}
179
+ >
180
+ <p>Dialog body content here.</p>
181
+ </Dialog>
182
+ ```
183
+
184
+ #### Tabs
185
+
186
+ ```tsx
187
+ import { Tabs } from '@geajs/ui'
188
+
189
+ <Tabs
190
+ defaultValue="tab1"
191
+ items={[
192
+ { value: 'tab1', label: 'Account', content: 'Account settings...' },
193
+ { value: 'tab2', label: 'Password', content: 'Password settings...' },
194
+ { value: 'tab3', label: 'Notifications', content: 'Notification preferences...' },
195
+ ]}
196
+ />
197
+ ```
198
+
199
+ #### Accordion
200
+
201
+ ```tsx
202
+ import { Accordion } from '@geajs/ui'
203
+
204
+ <Accordion
205
+ collapsible
206
+ items={[
207
+ { value: 'item1', label: 'What is @geajs/ui?', content: 'A component library for Gea.' },
208
+ { value: 'item2', label: 'Is it accessible?', content: 'Yes, powered by Zag.js.' },
209
+ ]}
210
+ />
211
+ ```
212
+
213
+ #### Tooltip
214
+
215
+ ```tsx
216
+ import { Tooltip } from '@geajs/ui'
217
+
218
+ <Tooltip content="This is a tooltip">
219
+ Hover me
220
+ </Tooltip>
221
+ ```
222
+
223
+ #### Popover
224
+
225
+ ```tsx
226
+ import { Popover } from '@geajs/ui'
227
+
228
+ <Popover title="Settings" description="Configure your preferences.">
229
+ <p>Popover content...</p>
230
+ </Popover>
231
+ ```
232
+
233
+ #### Menu
234
+
235
+ ```tsx
236
+ import { Menu } from '@geajs/ui'
237
+
238
+ <Menu
239
+ triggerLabel="Actions"
240
+ items={[
241
+ { value: 'edit', label: 'Edit' },
242
+ { value: 'duplicate', label: 'Duplicate' },
243
+ { type: 'separator' },
244
+ { value: 'delete', label: 'Delete' },
245
+ ]}
246
+ onSelect={(details) => console.log(details.value)}
247
+ />
248
+ ```
249
+
250
+ #### Select
251
+
252
+ ```tsx
253
+ import { Select } from '@geajs/ui'
254
+
255
+ <Select
256
+ label="Framework"
257
+ placeholder="Select a framework..."
258
+ items={[
259
+ { value: 'gea', label: 'Gea' },
260
+ { value: 'react', label: 'React' },
261
+ { value: 'vue', label: 'Vue' },
262
+ { value: 'solid', label: 'Solid' },
263
+ ]}
264
+ onValueChange={(details) => console.log(details.value)}
265
+ />
266
+ ```
267
+
268
+ **Note:** For Select and Combobox, pass a Zag `collection` prop for advanced usage with `ListCollection`.
269
+
270
+ #### Switch
271
+
272
+ ```tsx
273
+ import { Switch } from '@geajs/ui'
274
+
275
+ <Switch label="Airplane Mode" onCheckedChange={(d) => console.log(d.checked)} />
276
+ ```
277
+
278
+ #### Checkbox
279
+
280
+ ```tsx
281
+ import { Checkbox } from '@geajs/ui'
282
+
283
+ <Checkbox label="Accept terms" onCheckedChange={(d) => console.log(d.checked)} />
284
+ ```
285
+
286
+ #### Radio Group
287
+
288
+ ```tsx
289
+ import { RadioGroup } from '@geajs/ui'
290
+
291
+ <RadioGroup
292
+ label="Plan"
293
+ defaultValue="pro"
294
+ items={[
295
+ { value: 'free', label: 'Free' },
296
+ { value: 'pro', label: 'Pro' },
297
+ { value: 'enterprise', label: 'Enterprise' },
298
+ ]}
299
+ onValueChange={(d) => console.log(d.value)}
300
+ />
301
+ ```
302
+
303
+ #### Slider
304
+
305
+ ```tsx
306
+ import { Slider } from '@geajs/ui'
307
+
308
+ <Slider
309
+ label="Volume"
310
+ defaultValue={[50]}
311
+ min={0}
312
+ max={100}
313
+ step={1}
314
+ />
315
+ ```
316
+
317
+ #### Number Input
318
+
319
+ ```tsx
320
+ import { NumberInput } from '@geajs/ui'
321
+
322
+ <NumberInput label="Quantity" min={0} max={99} step={1} />
323
+ ```
324
+
325
+ #### Pin Input
326
+
327
+ ```tsx
328
+ import { PinInput } from '@geajs/ui'
329
+
330
+ <PinInput
331
+ label="Verification Code"
332
+ count={6}
333
+ type="numeric"
334
+ onValueComplete={(d) => console.log(d.valueAsString)}
335
+ />
336
+ ```
337
+
338
+ #### Tags Input
339
+
340
+ ```tsx
341
+ import { TagsInput } from '@geajs/ui'
342
+
343
+ <TagsInput
344
+ label="Tags"
345
+ placeholder="Add tag..."
346
+ defaultValue={['gea', 'ui']}
347
+ onValueChange={(d) => console.log(d.value)}
348
+ />
349
+ ```
350
+
351
+ #### Progress
352
+
353
+ ```tsx
354
+ import { Progress } from '@geajs/ui'
355
+
356
+ <Progress label="Upload" value={65} />
357
+ ```
358
+
359
+ #### Rating Group
360
+
361
+ ```tsx
362
+ import { RatingGroup } from '@geajs/ui'
363
+
364
+ <RatingGroup label="Rating" count={5} defaultValue={3} />
365
+ ```
366
+
367
+ #### Clipboard
368
+
369
+ ```tsx
370
+ import { Clipboard } from '@geajs/ui'
371
+
372
+ <Clipboard label="API Key" value="sk-abc123..." />
373
+ ```
374
+
375
+ #### Avatar
376
+
377
+ ```tsx
378
+ import { Avatar } from '@geajs/ui'
379
+
380
+ <Avatar src="/avatar.jpg" name="John Doe" />
381
+ <Avatar name="JD" />
382
+ ```
383
+
384
+ #### Toggle Group
385
+
386
+ ```tsx
387
+ import { ToggleGroup } from '@geajs/ui'
388
+
389
+ <ToggleGroup
390
+ items={[
391
+ { value: 'bold', label: 'B' },
392
+ { value: 'italic', label: 'I' },
393
+ { value: 'underline', label: 'U' },
394
+ ]}
395
+ multiple
396
+ />
397
+ ```
398
+
399
+ #### Combobox
400
+
401
+ ```tsx
402
+ import { Combobox } from '@geajs/ui'
403
+
404
+ <Combobox
405
+ label="Country"
406
+ items={[
407
+ { value: 'us', label: 'United States' },
408
+ { value: 'uk', label: 'United Kingdom' },
409
+ { value: 'de', label: 'Germany' },
410
+ ]}
411
+ />
412
+ ```
413
+
414
+ #### Collapsible
415
+
416
+ ```tsx
417
+ import { Collapsible } from '@geajs/ui'
418
+
419
+ <Collapsible label="Show more">
420
+ <p>Hidden content revealed on toggle.</p>
421
+ </Collapsible>
422
+ ```
423
+
424
+ #### Hover Card
425
+
426
+ ```tsx
427
+ import { HoverCard } from '@geajs/ui'
428
+
429
+ <HoverCard triggerLabel="@dashersw">
430
+ <p>Profile information...</p>
431
+ </HoverCard>
432
+ ```
433
+
434
+ #### Pagination
435
+
436
+ ```tsx
437
+ import { Pagination } from '@geajs/ui'
438
+
439
+ <Pagination
440
+ count={100}
441
+ defaultPageSize={10}
442
+ onPageChange={(d) => console.log(d.page)}
443
+ />
444
+ ```
445
+
446
+ #### File Upload
447
+
448
+ ```tsx
449
+ import { FileUpload } from '@geajs/ui'
450
+
451
+ <FileUpload
452
+ label="Upload Documents"
453
+ accept={{ 'application/pdf': ['.pdf'] }}
454
+ maxFiles={5}
455
+ onFileChange={(d) => console.log(d.acceptedFiles)}
456
+ />
457
+ ```
458
+
459
+ #### Toast
460
+
461
+ ```tsx
462
+ import { Toaster, ToastStore } from '@geajs/ui'
463
+
464
+ // Add the Toaster to your app root
465
+ class App extends Component {
466
+ template() {
467
+ return (
468
+ <div>
469
+ <Button onClick={() => ToastStore.success({ title: 'Saved!', description: 'Your changes have been saved.' })}>
470
+ Show Toast
471
+ </Button>
472
+ <Toaster />
473
+ </div>
474
+ )
475
+ }
476
+ }
477
+
478
+ // ToastStore methods: create, success, error, info, loading, dismiss
479
+ ```
480
+
481
+ #### Tree View
482
+
483
+ ```tsx
484
+ import { TreeView } from '@geajs/ui'
485
+
486
+ <TreeView collection={treeCollection}>
487
+ {/* Render tree nodes as children */}
488
+ </TreeView>
489
+ ```
490
+
491
+ ## Custom Styling
492
+
493
+ ### CSS Variables
494
+
495
+ Override CSS variables to customize the theme:
496
+
497
+ ```css
498
+ :root {
499
+ --primary: 222 47% 11%;
500
+ --primary-foreground: 210 40% 98%;
501
+ --radius: 0.75rem;
502
+ }
503
+ ```
504
+
505
+ ### Dark Mode
506
+
507
+ Add the `dark` class to your `<html>` element to enable dark mode:
508
+
509
+ ```html
510
+ <html class="dark">
511
+ ```
512
+
513
+ ### Component Classes
514
+
515
+ All components use semantic class names (e.g., `dialog-trigger`, `tabs-content`) alongside `data-part` and `data-state` attributes, making it easy to target them with custom CSS:
516
+
517
+ ```css
518
+ [data-part="content"][data-state="open"] {
519
+ animation: custom-enter 200ms ease;
520
+ }
521
+ ```
522
+
523
+ ## Architecture
524
+
525
+ @geajs/ui uses a "shell component" pattern:
526
+
527
+ 1. **Zag.js** provides framework-agnostic state machines for complex UI behavior (keyboard navigation, focus traps, ARIA attributes)
528
+ 2. **ZagComponent** base class bridges Zag's vanilla adapter with Gea's reactive system
529
+ 3. Zag's `spreadProps` applies dynamic attributes and event listeners imperatively after Gea's DOM patches
530
+ 4. Gea's reactive properties drive visual state (open/closed, checked, value)
531
+ 5. Tailwind CSS handles all styling through utility classes and CSS custom properties
532
+
533
+ ## License
534
+
535
+ MIT