cronixui 1.0.0 → 1.0.2

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.
Files changed (75) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +582 -0
  3. package/package.json +10 -7
  4. package/packages/react/src/components/Accordion.jsx +50 -0
  5. package/packages/react/src/components/Alert.jsx +62 -0
  6. package/packages/react/src/components/Avatar.jsx +34 -0
  7. package/packages/react/src/components/Badge.jsx +15 -0
  8. package/packages/react/src/components/Breadcrumb.jsx +27 -0
  9. package/packages/react/src/components/Button.jsx +21 -0
  10. package/packages/react/src/components/Card.jsx +23 -0
  11. package/packages/react/src/components/Checkbox.jsx +27 -0
  12. package/packages/react/src/components/CommandPalette.jsx +93 -0
  13. package/packages/react/src/components/Dropdown.jsx +48 -0
  14. package/packages/react/src/components/FileInput.jsx +44 -0
  15. package/packages/react/src/components/Input.jsx +22 -0
  16. package/packages/react/src/components/List.jsx +29 -0
  17. package/packages/react/src/components/Modal.jsx +65 -0
  18. package/packages/react/src/components/Nav.jsx +50 -0
  19. package/packages/react/src/components/Pagination.jsx +81 -0
  20. package/packages/react/src/components/Progress.jsx +23 -0
  21. package/packages/react/src/components/Radio.jsx +50 -0
  22. package/packages/react/src/components/Search.jsx +70 -0
  23. package/packages/react/src/components/Select.jsx +33 -0
  24. package/packages/react/src/components/Skeleton.jsx +15 -0
  25. package/packages/react/src/components/Slider.jsx +29 -0
  26. package/packages/react/src/components/Spinner.jsx +5 -0
  27. package/packages/react/src/components/Stat.jsx +19 -0
  28. package/packages/react/src/components/Table.jsx +48 -0
  29. package/packages/react/src/components/Tabs.jsx +65 -0
  30. package/packages/react/src/components/Tag.jsx +19 -0
  31. package/packages/react/src/components/Textarea.jsx +17 -0
  32. package/packages/react/src/components/Toast.jsx +78 -0
  33. package/packages/react/src/components/Toggle.jsx +34 -0
  34. package/packages/react/src/components/Tooltip.jsx +12 -0
  35. package/packages/react/src/index.js +33 -0
  36. package/packages/win/CronixUI.WinUI/Controls/FlAvatar.cs +39 -0
  37. package/packages/win/CronixUI.WinUI/Controls/FlBadge.cs +21 -0
  38. package/packages/win/CronixUI.WinUI/Controls/FlButton.cs +30 -0
  39. package/packages/win/CronixUI.WinUI/Controls/FlCard.cs +21 -0
  40. package/packages/win/CronixUI.WinUI/Controls/FlCheckBox.cs +12 -0
  41. package/packages/win/CronixUI.WinUI/Controls/FlComboBox.cs +12 -0
  42. package/packages/win/CronixUI.WinUI/Controls/FlModal.cs +34 -0
  43. package/packages/win/CronixUI.WinUI/Controls/FlNavigation.cs +12 -0
  44. package/packages/win/CronixUI.WinUI/Controls/FlProgressBar.cs +21 -0
  45. package/packages/win/CronixUI.WinUI/Controls/FlRadioButton.cs +12 -0
  46. package/packages/win/CronixUI.WinUI/Controls/FlSlider.cs +12 -0
  47. package/packages/win/CronixUI.WinUI/Controls/FlSpinner.cs +21 -0
  48. package/packages/win/CronixUI.WinUI/Controls/FlTabs.cs +12 -0
  49. package/packages/win/CronixUI.WinUI/Controls/FlTextBox.cs +21 -0
  50. package/packages/win/CronixUI.WinUI/Controls/FlToggle.cs +12 -0
  51. package/packages/win/CronixUI.WinUI/Controls/FlTooltip.cs +21 -0
  52. package/packages/win/CronixUI.WinUI/CronixUI.WinUI.csproj +21 -0
  53. package/packages/win/CronixUI.WinUI/CronixUI.WinUI.sln +33 -0
  54. package/packages/win/CronixUI.WinUI/Themes/FlAvatar.xaml +39 -0
  55. package/packages/win/CronixUI.WinUI/Themes/FlBadge.xaml +30 -0
  56. package/packages/win/CronixUI.WinUI/Themes/FlButton.xaml +36 -0
  57. package/packages/win/CronixUI.WinUI/Themes/FlCard.xaml +28 -0
  58. package/packages/win/CronixUI.WinUI/Themes/FlCheckBox.xaml +45 -0
  59. package/packages/win/CronixUI.WinUI/Themes/FlComboBox.xaml +70 -0
  60. package/packages/win/CronixUI.WinUI/Themes/FlModal.xaml +47 -0
  61. package/packages/win/CronixUI.WinUI/Themes/FlProgressBar.xaml +27 -0
  62. package/packages/win/CronixUI.WinUI/Themes/FlRadioButton.xaml +42 -0
  63. package/packages/win/CronixUI.WinUI/Themes/FlSlider.xaml +38 -0
  64. package/packages/win/CronixUI.WinUI/Themes/FlSpinner.xaml +13 -0
  65. package/packages/win/CronixUI.WinUI/Themes/FlTextBox.xaml +39 -0
  66. package/packages/win/CronixUI.WinUI/Themes/FlToggle.xaml +45 -0
  67. package/packages/win/CronixUI.WinUI/Themes/FlTooltip.xaml +31 -0
  68. package/packages/win/CronixUI.WinUI/Themes/Generic.xaml +163 -0
  69. /package/{dist → packages/web/dist}/cronixui.css +0 -0
  70. /package/{dist → packages/web/dist}/cronixui.js +0 -0
  71. /package/{dist → packages/web/dist}/cronixui.min.css +0 -0
  72. /package/{dist → packages/web/dist}/cronixui.min.js +0 -0
  73. /package/{src → packages/web/src}/cronixui.css +0 -0
  74. /package/{src → packages/web/src}/cronixui.js +0 -0
  75. /package/{src → packages/web/src}/variables.css +0 -0
package/README.md ADDED
@@ -0,0 +1,582 @@
1
+ # CronixUI
2
+
3
+ A multi-platform UI toolkit with a dark theme, crimson accents, and Outfit typography. Available for Web, React, and Windows (WinUI 3).
4
+
5
+ ## Packages
6
+
7
+ | Package | Description |
8
+ |---------|-------------|
9
+ | `cronixui` | Core CSS/JS for web |
10
+ | `cronixui-react` | React components |
11
+ | `cronixui-win` | WinUI 3 controls |
12
+
13
+ ## Installation
14
+
15
+ ### Web
16
+
17
+ ```bash
18
+ npm install cronixui
19
+ ```
20
+
21
+ ### CDN
22
+
23
+ ```html
24
+ <link rel="stylesheet" href="https://unpkg.com/cronixui@1.0.1/packages/web/dist/cronixui.css">
25
+ <script src="https://unpkg.com/cronixui@1.0.1/packages/web/dist/cronixui.js"></script>
26
+ ```
27
+
28
+ ### React
29
+
30
+ ```bash
31
+ npm install cronixui-react
32
+ ```
33
+
34
+ ### WinUI 3
35
+
36
+ Coming soon to NuGet.
37
+
38
+ ## Quick Start (Web)
39
+
40
+ ```html
41
+ <!DOCTYPE html>
42
+ <html lang="en">
43
+ <head>
44
+ <meta charset="UTF-8">
45
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
46
+ <title>My App</title>
47
+ <link rel="stylesheet" href="https://unpkg.com/cronixui@1.0.1/packages/web/dist/cronixui.css">
48
+ </head>
49
+ <body>
50
+ <div class="cn-container">
51
+ <h1 class="cn-h1">Hello, CronixUI!</h1>
52
+ <button class="cn-btn cn-btn-primary">Get Started</button>
53
+ </div>
54
+ <script src="https://unpkg.com/cronixui@1.0.1/packages/web/dist/cronixui.js"></script>
55
+ </body>
56
+ </html>
57
+ ```
58
+
59
+ ## Design Tokens
60
+
61
+ CronixUI uses CSS custom properties for consistent theming:
62
+
63
+ | Token | Value | Description |
64
+ |-------|-------|-------------|
65
+ | `--cn-bg` | `#0a0a0a` | Background |
66
+ | `--cn-surface` | `#111111` | Surface |
67
+ | `--cn-accent` | `#6b2323` | Crimson accent |
68
+ | `--cn-text` | `#f0ede8` | Primary text |
69
+ | `--cn-border` | `rgba(255,255,255,0.08)` | Border color |
70
+
71
+ ## Components
72
+
73
+ ### Typography
74
+
75
+ ```html
76
+ <h1 class="cn-h1">Heading 1</h1>
77
+ <h2 class="cn-h2">Heading 2</h2>
78
+ <h3 class="cn-h3">Heading 3</h3>
79
+ <p class="cn-text-muted">Muted text</p>
80
+ <p class="cn-text-dim">Dim text</p>
81
+ <code class="cn-text-mono">code</code>
82
+ ```
83
+
84
+ ### Buttons
85
+
86
+ ```html
87
+ <button class="cn-btn cn-btn-primary">Primary</button>
88
+ <button class="cn-btn">Default</button>
89
+ <button class="cn-btn cn-btn-ghost">Ghost</button>
90
+ <button class="cn-btn cn-btn-outline">Outline</button>
91
+ <button class="cn-btn cn-btn-success">Success</button>
92
+ <button class="cn-btn cn-btn-danger">Danger</button>
93
+
94
+ <!-- Sizes -->
95
+ <button class="cn-btn cn-btn-sm">Small</button>
96
+ <button class="cn-btn cn-btn-lg">Large</button>
97
+
98
+ <!-- Button Group -->
99
+ <div class="cn-btn-group">
100
+ <button class="cn-btn">Left</button>
101
+ <button class="cn-btn">Center</button>
102
+ <button class="cn-btn">Right</button>
103
+ </div>
104
+ ```
105
+
106
+ ### Inputs
107
+
108
+ ```html
109
+ <!-- Basic input -->
110
+ <input class="cn-input" placeholder="Enter text...">
111
+
112
+ <!-- With label -->
113
+ <div class="cn-form-group">
114
+ <label class="cn-form-label">Email</label>
115
+ <input class="cn-input" type="email" placeholder="you@example.com">
116
+ </div>
117
+
118
+ <!-- With error -->
119
+ <div class="cn-form-group">
120
+ <label class="cn-form-label">Password</label>
121
+ <input class="cn-input cn-input-error" type="password">
122
+ <span class="cn-form-error">Password is required</span>
123
+ </div>
124
+
125
+ <!-- Sizes -->
126
+ <input class="cn-input cn-input-sm" placeholder="Small">
127
+ <input class="cn-input cn-input-lg" placeholder="Large">
128
+
129
+ <!-- Select -->
130
+ <div class="cn-select-wrapper">
131
+ <select class="cn-select">
132
+ <option>Option 1</option>
133
+ <option>Option 2</option>
134
+ </select>
135
+ </div>
136
+
137
+ <!-- Textarea -->
138
+ <textarea class="cn-input cn-textarea" placeholder="Long text..."></textarea>
139
+ ```
140
+
141
+ ### Checkbox & Radio
142
+
143
+ ```html
144
+ <label class="cn-checkbox">
145
+ <input type="checkbox" checked>
146
+ <span class="cn-checkbox-box"></span>
147
+ <span class="cn-checkbox-label">Checked</span>
148
+ </label>
149
+
150
+ <label class="cn-radio">
151
+ <input type="radio" name="group" checked>
152
+ <span class="cn-radio-box"></span>
153
+ <span class="cn-radio-label">Option A</span>
154
+ </label>
155
+ ```
156
+
157
+ ### Toggle
158
+
159
+ ```html
160
+ <div class="cn-toggle on"></div>
161
+ <span class="cn-toggle-label">Enabled</span>
162
+ ```
163
+
164
+ ```javascript
165
+ // Toggle state
166
+ document.querySelector('.cn-toggle').classList.toggle('on');
167
+ ```
168
+
169
+ ### Slider
170
+
171
+ ```html
172
+ <input type="range" class="cn-slider" min="0" max="100" value="50">
173
+ ```
174
+
175
+ ### Badges
176
+
177
+ ```html
178
+ <span class="cn-badge cn-badge-default">Default</span>
179
+ <span class="cn-badge cn-badge-accent">Accent</span>
180
+ <span class="cn-badge cn-badge-success">Success</span>
181
+ <span class="cn-badge cn-badge-warning">Warning</span>
182
+ <span class="cn-badge cn-badge-error">Error</span>
183
+ <span class="cn-badge cn-badge-info">Info</span>
184
+
185
+ <!-- Solid variants -->
186
+ <span class="cn-badge cn-badge-solid cn-badge-accent">Solid</span>
187
+ ```
188
+
189
+ ### Tags
190
+
191
+ ```html
192
+ <span class="cn-tag">
193
+ Tag Name
194
+ <span class="cn-tag-remove">
195
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
196
+ <line x1="18" y1="6" x2="6" y2="18"/>
197
+ <line x1="6" y1="6" x2="18" y2="18"/>
198
+ </svg>
199
+ </span>
200
+ </span>
201
+ ```
202
+
203
+ ### Stats
204
+
205
+ ```html
206
+ <div class="cn-stat">
207
+ <div class="cn-stat-value">2,847</div>
208
+ <div class="cn-stat-label">Total runs</div>
209
+ <div class="cn-stat-delta cn-stat-delta-up">+12%</div>
210
+ </div>
211
+ ```
212
+
213
+ ### Progress
214
+
215
+ ```html
216
+ <div class="cn-progress-label"><span>Loading</span><span>68%</span></div>
217
+ <div class="cn-progress">
218
+ <div class="cn-progress-bar" style="width: 68%;"></div>
219
+ </div>
220
+
221
+ <!-- Variants -->
222
+ <div class="cn-progress cn-progress-success">...</div>
223
+ <div class="cn-progress cn-progress-warning">...</div>
224
+ <div class="cn-progress cn-progress-error">...</div>
225
+ <div class="cn-progress cn-progress-lg">...</div>
226
+ ```
227
+
228
+ ### Cards
229
+
230
+ ```html
231
+ <div class="cn-card">
232
+ <h3 class="cn-card-title">Card Title</h3>
233
+ <p class="cn-card-body">Card content.</p>
234
+ </div>
235
+
236
+ <!-- Clickable -->
237
+ <div class="cn-card cn-card-clickable">...</div>
238
+
239
+ <!-- With header/footer -->
240
+ <div class="cn-card">
241
+ <div class="cn-card-header">
242
+ <span class="cn-card-title">Title</span>
243
+ <button class="cn-btn cn-btn-sm">Action</button>
244
+ </div>
245
+ <p class="cn-card-body">Content</p>
246
+ <div class="cn-card-footer">Footer</div>
247
+ </div>
248
+ ```
249
+
250
+ ### Navigation
251
+
252
+ ```html
253
+ <div class="cn-nav">
254
+ <button class="cn-nav-item cn-nav-active">Home</button>
255
+ <button class="cn-nav-item">Projects</button>
256
+ <button class="cn-nav-item">Settings</button>
257
+ </div>
258
+ ```
259
+
260
+ ```javascript
261
+ CronixUI.Nav.init();
262
+ ```
263
+
264
+ ### Tabs
265
+
266
+ ```html
267
+ <div class="cn-tabs">
268
+ <div class="cn-tabs-list">
269
+ <button class="cn-tab cn-tab-active">Tab 1</button>
270
+ <button class="cn-tab">Tab 2</button>
271
+ <button class="cn-tab">Tab 3</button>
272
+ </div>
273
+ </div>
274
+ <div class="cn-tab-content">
275
+ <div class="cn-tab-panel cn-tab-panel-active">Content 1</div>
276
+ <div class="cn-tab-panel">Content 2</div>
277
+ <div class="cn-tab-panel">Content 3</div>
278
+ </div>
279
+ ```
280
+
281
+ ### Breadcrumb
282
+
283
+ ```html
284
+ <div class="cn-breadcrumb">
285
+ <a href="#" class="cn-breadcrumb-item">Home</a>
286
+ <span class="cn-breadcrumb-separator">/</span>
287
+ <a href="#" class="cn-breadcrumb-item">Projects</a>
288
+ <span class="cn-breadcrumb-separator">/</span>
289
+ <span class="cn-breadcrumb-current">Current</span>
290
+ </div>
291
+ ```
292
+
293
+ ### Alerts
294
+
295
+ ```html
296
+ <div class="cn-alert cn-alert-info">
297
+ <div class="cn-alert-icon">...</div>
298
+ <div class="cn-alert-content">
299
+ <div class="cn-alert-title">Title</div>
300
+ <div class="cn-alert-message">Message</div>
301
+ </div>
302
+ <button class="cn-alert-close">×</button>
303
+ </div>
304
+ ```
305
+
306
+ Variants: `cn-alert-info`, `cn-alert-success`, `cn-alert-warning`, `cn-alert-error`
307
+
308
+ ### Toast
309
+
310
+ ```javascript
311
+ // Show toast
312
+ CronixUI.Toast.success('Operation completed!');
313
+ CronixUI.Toast.error('Something went wrong');
314
+ CronixUI.Toast.warning('Please review');
315
+ CronixUI.Toast.info('New updates');
316
+
317
+ // With title
318
+ CronixUI.Toast.show({
319
+ title: 'Success',
320
+ message: 'Your changes have been saved.',
321
+ type: 'success',
322
+ duration: 5000
323
+ });
324
+ ```
325
+
326
+ ### Modal
327
+
328
+ ```html
329
+ <div class="cn-modal-backdrop" id="myModal">
330
+ <div class="cn-modal">
331
+ <div class="cn-modal-header">
332
+ <h3 class="cn-modal-title">Modal Title</h3>
333
+ <button class="cn-modal-close">×</button>
334
+ </div>
335
+ <div class="cn-modal-body">Content</div>
336
+ <div class="cn-modal-footer">
337
+ <button class="cn-btn cn-btn-ghost">Cancel</button>
338
+ <button class="cn-btn cn-btn-primary">Confirm</button>
339
+ </div>
340
+ </div>
341
+ </div>
342
+ ```
343
+
344
+ ```javascript
345
+ const modal = document.getElementById('myModal');
346
+ modal._cnModal.open();
347
+ modal._cnModal.close();
348
+ ```
349
+
350
+ ### Dropdown
351
+
352
+ ```html
353
+ <div class="cn-dropdown">
354
+ <button class="cn-btn cn-dropdown-trigger">
355
+ Menu <svg>...</svg>
356
+ </button>
357
+ <div class="cn-dropdown-menu">
358
+ <div class="cn-dropdown-item">Profile</div>
359
+ <div class="cn-dropdown-item">Settings</div>
360
+ <div class="cn-dropdown-divider"></div>
361
+ <div class="cn-dropdown-item">Logout</div>
362
+ </div>
363
+ </div>
364
+ ```
365
+
366
+ ### Tooltip
367
+
368
+ ```html
369
+ <div class="cn-tooltip">
370
+ <button class="cn-btn">Hover me</button>
371
+ <div class="cn-tooltip-content">Tooltip text</div>
372
+ </div>
373
+ ```
374
+
375
+ ### Table
376
+
377
+ ```html
378
+ <div class="cn-table-wrapper cn-table-sortable">
379
+ <table class="cn-table">
380
+ <thead>
381
+ <tr>
382
+ <th data-sort="name">Name</th>
383
+ <th data-sort="value">Value</th>
384
+ </tr>
385
+ </thead>
386
+ <tbody>
387
+ <tr>
388
+ <td>Item 1</td>
389
+ <td>100</td>
390
+ </tr>
391
+ </tbody>
392
+ </table>
393
+ </div>
394
+ ```
395
+
396
+ ### List
397
+
398
+ ```html
399
+ <div class="cn-list">
400
+ <div class="cn-list-item cn-list-item-clickable">
401
+ <div class="cn-list-item-content">
402
+ <div class="cn-list-item-title">Title</div>
403
+ <div class="cn-list-item-subtitle">Subtitle</div>
404
+ </div>
405
+ </div>
406
+ </div>
407
+ ```
408
+
409
+ ### Accordion
410
+
411
+ ```html
412
+ <div class="cn-accordion">
413
+ <div class="cn-accordion-item cn-accordion-open">
414
+ <div class="cn-accordion-header">
415
+ <span class="cn-accordion-title">Section 1</span>
416
+ <svg class="cn-accordion-icon">...</svg>
417
+ </div>
418
+ <div class="cn-accordion-content">Content</div>
419
+ </div>
420
+ </div>
421
+ ```
422
+
423
+ ### Avatar
424
+
425
+ ```html
426
+ <div class="cn-avatar">JD</div>
427
+ <div class="cn-avatar cn-avatar-sm">AB</div>
428
+ <div class="cn-avatar cn-avatar-lg">XY</div>
429
+ <div class="cn-avatar cn-avatar-xl">ZZ</div>
430
+
431
+ <!-- Group -->
432
+ <div class="cn-avatar-group">
433
+ <div class="cn-avatar">A</div>
434
+ <div class="cn-avatar">B</div>
435
+ <div class="cn-avatar">+5</div>
436
+ </div>
437
+ ```
438
+
439
+ ### Pagination
440
+
441
+ ```html
442
+ <div class="cn-pagination" id="pagination"></div>
443
+ ```
444
+
445
+ ```javascript
446
+ new CronixUI.Pagination(document.getElementById('pagination'), {
447
+ total: 10,
448
+ current: 1,
449
+ onChange: (page) => console.log('Page:', page)
450
+ });
451
+ ```
452
+
453
+ ### File Input
454
+
455
+ ```html
456
+ <div class="cn-file-input">
457
+ <input type="file">
458
+ <div class="cn-file-input-label">
459
+ <svg class="cn-file-input-icon">...</svg>
460
+ <div class="cn-file-input-text">
461
+ <span>Click to upload</span> or drag and drop
462
+ </div>
463
+ </div>
464
+ </div>
465
+ ```
466
+
467
+ ### Search
468
+
469
+ ```html
470
+ <div class="cn-search">
471
+ <svg class="cn-search-icon">...</svg>
472
+ <input class="cn-input cn-search-input" placeholder="Search...">
473
+ <div class="cn-search-results"></div>
474
+ </div>
475
+ ```
476
+
477
+ ```javascript
478
+ const search = document.querySelector('.cn-search');
479
+ search._cnSearch.setItems([
480
+ { title: 'Result 1', subtitle: 'Description', action: () => {} },
481
+ { title: 'Result 2', action: () => {} }
482
+ ]);
483
+ ```
484
+
485
+ ### Command Palette
486
+
487
+ ```html
488
+ <div class="cn-command-palette" id="cmd">
489
+ <div class="cn-command-palette-inner">
490
+ <input class="cn-command-palette-input" placeholder="Type a command...">
491
+ <div class="cn-command-palette-results"></div>
492
+ </div>
493
+ </div>
494
+ ```
495
+
496
+ ```javascript
497
+ const cmd = document.getElementById('cmd');
498
+ new CronixUI.CommandPalette(cmd);
499
+ cmd._cnCommandPalette.setItems([
500
+ { title: 'New File', kbd: 'Ctrl+N', action: () => {} },
501
+ { title: 'Save', kbd: 'Ctrl+S', action: () => {} }
502
+ ]);
503
+
504
+ // Open
505
+ cmd._cnCommandPalette.open();
506
+ ```
507
+
508
+ ### Loading States
509
+
510
+ ```html
511
+ <!-- Spinner -->
512
+ <div class="cn-spinner"></div>
513
+ <div class="cn-spinner cn-spinner-sm"></div>
514
+ <div class="cn-spinner cn-spinner-lg"></div>
515
+
516
+ <!-- Skeleton -->
517
+ <div class="cn-skeleton cn-skeleton-title"></div>
518
+ <div class="cn-skeleton cn-skeleton-text"></div>
519
+ <div class="cn-skeleton cn-skeleton-avatar"></div>
520
+ ```
521
+
522
+ ### Layout
523
+
524
+ ```html
525
+ <!-- Container -->
526
+ <div class="cn-container">...</div>
527
+ <div class="cn-container-sm">...</div>
528
+ <div class="cn-container-lg">...</div>
529
+
530
+ <!-- Flex -->
531
+ <div class="cn-flex cn-items-center cn-gap-4">...</div>
532
+
533
+ <!-- Grid -->
534
+ <div class="cn-grid cn-grid-3">...</div>
535
+
536
+ <!-- Stack -->
537
+ <div class="cn-stack">...</div>
538
+ <div class="cn-hstack">...</div>
539
+
540
+ <!-- Sections -->
541
+ <div class="cn-section">...</div>
542
+ <div class="cn-divider"></div>
543
+ ```
544
+
545
+ ## JavaScript API
546
+
547
+ ### Global Object
548
+
549
+ ```javascript
550
+ // Initialize all components
551
+ CronixUI.init();
552
+
553
+ // Utilities
554
+ CronixUI.$(selector);
555
+ CronixUI.$$(selector);
556
+ CronixUI.createEl(tag, className, attrs);
557
+ ```
558
+
559
+ ### Classes
560
+
561
+ | Class | Methods |
562
+ |-------|---------|
563
+ | `CronixUI.Toggle` | `toggle()`, `isOn()`, `setOn(bool)` |
564
+ | `CronixUI.Modal` | `open()`, `close()` |
565
+ | `CronixUI.Dropdown` | `open()`, `close()`, `toggle()` |
566
+ | `CronixUI.Toast` | `show(opts)`, `success()`, `error()`, `warning()`, `info()` |
567
+ | `CronixUI.Tabs` | `setActive(index)` |
568
+ | `CronixUI.Accordion` | `toggle(item)`, `openAll()`, `closeAll()` |
569
+ | `CronixUI.Pagination` | `goTo(page)`, `render()` |
570
+ | `CronixUI.CommandPalette` | `open()`, `close()`, `setItems([])` |
571
+ | `CronixUI.Search` | `setItems([])`, `filter()`, `open()`, `close()` |
572
+
573
+ ## Browser Support
574
+
575
+ - Chrome 80+
576
+ - Firefox 75+
577
+ - Safari 13+
578
+ - Edge 80+
579
+
580
+ ## License
581
+
582
+ GPL 3.0, see LICENSE for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cronixui",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography",
5
5
  "keywords": [
6
6
  "ui",
@@ -12,14 +12,17 @@
12
12
  "license": "GPL-3.0",
13
13
  "author": "CazyUndee",
14
14
  "type": "commonjs",
15
- "main": "dist/cronixui.js",
16
- "style": "dist/cronixui.css",
15
+ "main": "packages/web/dist/cronixui.js",
16
+ "style": "packages/web/dist/cronixui.css",
17
17
  "files": [
18
- "dist/",
19
- "src/"
18
+ "packages/web/dist/",
19
+ "packages/web/src/",
20
+ "packages/react/src/",
21
+ "packages/win/CronixUI.WinUI/",
22
+ "README.md"
20
23
  ],
21
24
  "scripts": {
22
- "build": "node scripts/build.js",
23
- "dev": "npx live-server demo"
25
+ "build": "node packages/web/scripts/build.js",
26
+ "dev": "npx live-server packages/web/demo"
24
27
  }
25
28
  }
@@ -0,0 +1,50 @@
1
+ import { useState } from 'react';
2
+
3
+ export default function Accordion({
4
+ allowMultiple = false,
5
+ defaultOpen = [],
6
+ children,
7
+ className = ''
8
+ }) {
9
+ const [openItems, setOpenItems] = useState(new Set(defaultOpen));
10
+
11
+ const toggleItem = (index) => {
12
+ setOpenItems((prev) => {
13
+ const next = new Set(prev);
14
+ if (next.has(index)) {
15
+ next.delete(index);
16
+ } else {
17
+ if (!allowMultiple) {
18
+ next.clear();
19
+ }
20
+ next.add(index);
21
+ }
22
+ return next;
23
+ });
24
+ };
25
+
26
+ const items = Array.isArray(children) ? children : [children];
27
+
28
+ return (
29
+ <div className={`cn-accordion ${className}`}>
30
+ {items.map((child, idx) => (
31
+ <div key={idx} className={`cn-accordion-item ${openItems.has(idx) ? 'cn-accordion-open' : ''}`}>
32
+ <div className="cn-accordion-header" onClick={() => toggleItem(idx)}>
33
+ <span>{child.props.title}</span>
34
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" width="20" height="20">
35
+ <polyline points="6 9 12 15 18 9"></polyline>
36
+ </svg>
37
+ </div>
38
+ <div className="cn-accordion-content">
39
+ {child.props.children}
40
+ </div>
41
+ </div>
42
+ ))}
43
+ </div>
44
+ );
45
+ }
46
+
47
+ export function AccordionItem({ children }) {
48
+ return children;
49
+ }
50
+ AccordionItem.displayName = 'AccordionItem';