@justin_evo/evo-ui 1.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.
Files changed (110) hide show
  1. package/dist/Alert/Alert.d.ts +11 -0
  2. package/dist/AutoComplete/AutoComplete.d.ts +95 -0
  3. package/dist/Badge/Badge.d.ts +23 -0
  4. package/dist/Breadcrumb/Breadcrumb.d.ts +16 -0
  5. package/dist/Button/Button.d.ts +54 -0
  6. package/dist/Card/Card.d.ts +60 -0
  7. package/dist/Checkbox/Checkbox.d.ts +16 -0
  8. package/dist/CommandPalette/CommandPalette.d.ts +17 -0
  9. package/dist/Container/Container.d.ts +10 -0
  10. package/dist/Divider/Divider.d.ts +7 -0
  11. package/dist/Form/Form.d.ts +61 -0
  12. package/dist/Grid/Grid.d.ts +23 -0
  13. package/dist/ImageCropper/ImageCropper.d.ts +111 -0
  14. package/dist/Input/Input.d.ts +12 -0
  15. package/dist/Modal/Modal.d.ts +26 -0
  16. package/dist/Nav/Nav.d.ts +63 -0
  17. package/dist/Notification/Notification.d.ts +186 -0
  18. package/dist/Pagination/Pagination.d.ts +10 -0
  19. package/dist/Radio/Radio.d.ts +20 -0
  20. package/dist/RichTextArea/RichTextArea.d.ts +70 -0
  21. package/dist/Select/Select.d.ts +44 -0
  22. package/dist/Skeleton/Skeleton.d.ts +23 -0
  23. package/dist/Stack/Stack.d.ts +16 -0
  24. package/dist/Table/Table.d.ts +77 -0
  25. package/dist/Tabs/Tabs.d.ts +28 -0
  26. package/dist/Theme/ThemeProvider.d.ts +96 -0
  27. package/dist/Theme/ThemeToggle.d.ts +22 -0
  28. package/dist/Toggle/Toggle.d.ts +11 -0
  29. package/dist/Tooltip/Tooltip.d.ts +10 -0
  30. package/dist/TopNav/TopNav.d.ts +76 -0
  31. package/dist/TreeSelect/TreeSelect.d.ts +50 -0
  32. package/dist/declarations.d.ts +6 -0
  33. package/dist/evo-ui.css +1 -0
  34. package/dist/index.cjs.js +1 -0
  35. package/dist/index.d.ts +31 -0
  36. package/dist/index.es.js +5688 -0
  37. package/package.json +52 -0
  38. package/src/Alert/Alert.tsx +49 -0
  39. package/src/AutoComplete/AutoComplete.tsx +810 -0
  40. package/src/Badge/Badge.tsx +53 -0
  41. package/src/Breadcrumb/Breadcrumb.tsx +53 -0
  42. package/src/Button/Button.tsx +125 -0
  43. package/src/Card/Card.tsx +257 -0
  44. package/src/Checkbox/Checkbox.tsx +59 -0
  45. package/src/CommandPalette/CommandPalette.tsx +185 -0
  46. package/src/Container/Container.tsx +31 -0
  47. package/src/Divider/Divider.tsx +31 -0
  48. package/src/Form/Form.tsx +185 -0
  49. package/src/Grid/Grid.tsx +66 -0
  50. package/src/ImageCropper/ImageCropper.tsx +911 -0
  51. package/src/Input/Input.tsx +74 -0
  52. package/src/Modal/Modal.tsx +77 -0
  53. package/src/Nav/Nav.tsx +626 -0
  54. package/src/Notification/Notification.tsx +1503 -0
  55. package/src/Pagination/Pagination.tsx +76 -0
  56. package/src/Radio/Radio.tsx +69 -0
  57. package/src/RichTextArea/RichTextArea.tsx +869 -0
  58. package/src/Select/Select.tsx +515 -0
  59. package/src/Skeleton/Skeleton.tsx +70 -0
  60. package/src/Stack/Stack.tsx +52 -0
  61. package/src/Table/Table.tsx +335 -0
  62. package/src/Tabs/Tabs.tsx +90 -0
  63. package/src/Theme/ThemeProvider.tsx +253 -0
  64. package/src/Theme/ThemeToggle.tsx +79 -0
  65. package/src/Toggle/Toggle.tsx +48 -0
  66. package/src/Tooltip/Tooltip.tsx +38 -0
  67. package/src/TopNav/TopNav.tsx +994 -0
  68. package/src/TreeSelect/TreeSelect.tsx +825 -0
  69. package/src/css/alert.module.scss +93 -0
  70. package/src/css/autocomplete.module.scss +416 -0
  71. package/src/css/badge.module.scss +82 -0
  72. package/src/css/base/_color.scss +159 -0
  73. package/src/css/base/_theme.scss +237 -0
  74. package/src/css/base/_variables.scss +161 -0
  75. package/src/css/breadcrumb.module.scss +50 -0
  76. package/src/css/button.module.scss +385 -0
  77. package/src/css/card.module.scss +217 -0
  78. package/src/css/checkbox.module.scss +120 -0
  79. package/src/css/commandpalette.module.scss +211 -0
  80. package/src/css/container.module.scss +18 -0
  81. package/src/css/divider.module.scss +41 -0
  82. package/src/css/form.module.scss +245 -0
  83. package/src/css/imagecropper.module.scss +397 -0
  84. package/src/css/input.module.scss +89 -0
  85. package/src/css/modal.module.scss +105 -0
  86. package/src/css/nav.module.scss +339 -0
  87. package/src/css/notification.module.scss +691 -0
  88. package/src/css/pagination.module.scss +63 -0
  89. package/src/css/radio.module.scss +89 -0
  90. package/src/css/richtextarea.module.scss +307 -0
  91. package/src/css/select.module.scss +525 -0
  92. package/src/css/skeleton.module.scss +30 -0
  93. package/src/css/table.module.scss +386 -0
  94. package/src/css/tabs.module.scss +63 -0
  95. package/src/css/theme-toggle.module.scss +83 -0
  96. package/src/css/toggle.module.scss +54 -0
  97. package/src/css/tooltip.module.scss +97 -0
  98. package/src/css/topnav.module.scss +396 -0
  99. package/src/css/treeselect.module.scss +558 -0
  100. package/src/css/utilities/_borders.scss +111 -0
  101. package/src/css/utilities/_colors.scss +66 -0
  102. package/src/css/utilities/_effects.scss +216 -0
  103. package/src/css/utilities/_layout.scss +181 -0
  104. package/src/css/utilities/_position.scss +75 -0
  105. package/src/css/utilities/_sizing.scss +138 -0
  106. package/src/css/utilities/_spacing.scss +99 -0
  107. package/src/css/utilities/_typography.scss +121 -0
  108. package/src/css/utilities/index.scss +24 -0
  109. package/src/declarations.d.ts +6 -0
  110. package/src/index.ts +60 -0
@@ -0,0 +1,525 @@
1
+ @use 'base/variables' as *;
2
+ @use 'base/color' as *;
3
+
4
+ /* =====================================================================
5
+ * EvoSelect — Custom dropdown built for dark, modern interfaces.
6
+ * Combines design ideas from shadcn/Radix, Linear, Vercel, Apple HIG,
7
+ * Material 3, GitHub, Stripe, Notion, Tailwind UI, and Untitled UI.
8
+ * ===================================================================== */
9
+
10
+ .field {
11
+ display: inline-flex;
12
+ flex-direction: column;
13
+ gap: 0.4rem;
14
+ font-family: $font-sans;
15
+ min-width: 220px;
16
+ }
17
+
18
+ .fullWidth { width: 100%; }
19
+
20
+ .disabled .trigger {
21
+ opacity: 0.5;
22
+ cursor: not-allowed;
23
+ pointer-events: none;
24
+ }
25
+
26
+ .label {
27
+ font-size: $text-sm;
28
+ font-weight: 500;
29
+ color: $color-text-primary;
30
+ letter-spacing: -0.005em;
31
+ }
32
+
33
+ /* ---------------- Wrapper (positioning context for menu) ---------------- */
34
+ .selectWrapper {
35
+ position: relative;
36
+ width: 100%;
37
+ }
38
+
39
+ /* ---------------- Trigger button ---------------- */
40
+ .trigger {
41
+ display: inline-flex;
42
+ align-items: center;
43
+ justify-content: space-between;
44
+ gap: 0.5rem;
45
+ width: 100%;
46
+
47
+ background: $color-surface;
48
+ border: 1px solid $color-border;
49
+ border-radius: $radius-sm;
50
+ color: $color-text-primary;
51
+ font-family: $font-sans;
52
+ font-size: $text-sm;
53
+ line-height: 1.4;
54
+ cursor: pointer;
55
+ user-select: none;
56
+ text-align: left;
57
+ outline: none;
58
+
59
+ transition:
60
+ background-color $transition-fast,
61
+ border-color $transition-fast,
62
+ box-shadow $transition-fast,
63
+ transform $transition-fast;
64
+
65
+ &:hover:not(:disabled) {
66
+ background: $color-surface-hover;
67
+ border-color: $color-border-strong;
68
+ }
69
+
70
+ &:focus-visible {
71
+ border-color: $evo-primary-color;
72
+ box-shadow:
73
+ 0 0 0 3px color-mix(in srgb, $evo-primary-color 18%, transparent),
74
+ 0 1px 2px rgb(0 0 0 / 0.15);
75
+ }
76
+
77
+ &.open {
78
+ border-color: $evo-primary-color;
79
+ box-shadow:
80
+ 0 0 0 3px color-mix(in srgb, $evo-primary-color 18%, transparent),
81
+ 0 1px 2px rgb(0 0 0 / 0.15);
82
+ }
83
+
84
+ &.hasError {
85
+ border-color: $evo-danger-color;
86
+
87
+ &.open,
88
+ &:focus-visible {
89
+ box-shadow:
90
+ 0 0 0 3px color-mix(in srgb, $evo-danger-color 18%, transparent),
91
+ 0 1px 2px rgb(0 0 0 / 0.15);
92
+ }
93
+ }
94
+
95
+ &:disabled {
96
+ opacity: 0.5;
97
+ cursor: not-allowed;
98
+ }
99
+ }
100
+
101
+ /* ---------------- Sizes ---------------- */
102
+ .sm {
103
+ padding: 0.375rem 0.625rem;
104
+ min-height: 32px;
105
+ font-size: $text-xs;
106
+ border-radius: $radius-sm;
107
+ }
108
+
109
+ .md {
110
+ padding: 0.5rem 0.75rem;
111
+ min-height: 38px;
112
+ font-size: $text-sm;
113
+ }
114
+
115
+ .lg {
116
+ padding: 0.625rem 0.875rem;
117
+ min-height: 44px;
118
+ font-size: $text-base;
119
+ }
120
+
121
+ /* ---------------- Trigger content ---------------- */
122
+ .triggerValue,
123
+ .triggerPlaceholder {
124
+ display: inline-flex;
125
+ align-items: center;
126
+ gap: 0.5rem;
127
+ min-width: 0;
128
+ flex: 1;
129
+ }
130
+
131
+ /* When the trigger is rendering chips it needs vertical padding to breathe,
132
+ * and the row must wrap when many chips are selected. */
133
+ .triggerChips {
134
+ padding-top: 0.3rem;
135
+ padding-bottom: 0.3rem;
136
+ height: auto;
137
+ align-items: flex-start;
138
+ }
139
+
140
+ .chipRow {
141
+ display: flex;
142
+ flex-wrap: wrap;
143
+ gap: 0.3rem;
144
+ min-width: 0;
145
+ flex: 1;
146
+ align-items: center;
147
+ }
148
+
149
+ .chip {
150
+ display: inline-flex;
151
+ align-items: center;
152
+ gap: 0.3rem;
153
+ padding: 0.15rem 0.35rem 0.15rem 0.5rem;
154
+ background: color-mix(in srgb, $evo-primary-color 14%, transparent);
155
+ color: $color-text-primary;
156
+ border-radius: 999px;
157
+ font-size: $text-xs;
158
+ font-weight: 500;
159
+ line-height: 1.2;
160
+ max-width: 100%;
161
+ }
162
+
163
+ .chipIcon {
164
+ display: inline-flex;
165
+ align-items: center;
166
+ flex-shrink: 0;
167
+ font-size: 1em;
168
+ color: $color-text-secondary;
169
+ }
170
+
171
+ .chipLabel {
172
+ overflow: hidden;
173
+ text-overflow: ellipsis;
174
+ white-space: nowrap;
175
+ max-width: 12rem;
176
+ }
177
+
178
+ .chipRemove {
179
+ display: inline-flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ width: 18px;
183
+ height: 18px;
184
+ border-radius: 50%;
185
+ color: $color-text-muted;
186
+ cursor: pointer;
187
+ flex-shrink: 0;
188
+ transition: color $transition-fast, background-color $transition-fast;
189
+
190
+ &:hover {
191
+ color: $color-text-primary;
192
+ background: color-mix(in srgb, $evo-primary-color 22%, transparent);
193
+ }
194
+ }
195
+
196
+ .countMore {
197
+ color: $color-text-muted;
198
+ font-weight: 400;
199
+ margin-left: 0.15rem;
200
+ }
201
+
202
+ .triggerPlaceholder {
203
+ color: $color-text-muted;
204
+ }
205
+
206
+ .triggerText {
207
+ overflow: hidden;
208
+ text-overflow: ellipsis;
209
+ white-space: nowrap;
210
+ min-width: 0;
211
+ }
212
+
213
+ .triggerIcon {
214
+ display: inline-flex;
215
+ align-items: center;
216
+ flex-shrink: 0;
217
+ color: $color-text-secondary;
218
+ font-size: 1em;
219
+ }
220
+
221
+ .triggerActions {
222
+ display: inline-flex;
223
+ align-items: center;
224
+ gap: 0.25rem;
225
+ flex-shrink: 0;
226
+ }
227
+
228
+ /* ---------------- Clear button ---------------- */
229
+ .clearBtn {
230
+ display: inline-flex;
231
+ align-items: center;
232
+ justify-content: center;
233
+ width: 18px;
234
+ height: 18px;
235
+ border-radius: 50%;
236
+ color: $color-text-muted;
237
+ cursor: pointer;
238
+ transition: color $transition-fast, background-color $transition-fast;
239
+
240
+ &:hover {
241
+ color: $color-text-primary;
242
+ background: $color-surface-hover;
243
+ }
244
+ }
245
+
246
+ /* ---------------- Chevron ---------------- */
247
+ .chevron {
248
+ display: inline-flex;
249
+ align-items: center;
250
+ justify-content: center;
251
+ color: $color-text-muted;
252
+ transition: transform 180ms cubic-bezier(0.4, 0, 0.2, 1), color $transition-fast;
253
+ }
254
+
255
+ .chevronOpen {
256
+ transform: rotate(180deg);
257
+ color: $evo-primary-color;
258
+ }
259
+
260
+ .trigger:hover:not(:disabled) .chevron {
261
+ color: $color-text-secondary;
262
+ }
263
+
264
+ /* ===================================================================
265
+ * Dropdown menu
266
+ * =================================================================== */
267
+ .menu {
268
+ position: absolute;
269
+ top: calc(100% + 6px);
270
+ left: 0;
271
+ right: 0;
272
+ z-index: 100;
273
+
274
+ background: $color-surface-elevated;
275
+ border: 1px solid $color-border;
276
+ border-radius: $radius-md;
277
+ overflow: hidden;
278
+
279
+ box-shadow:
280
+ 0 16px 32px -12px rgb(0 0 0 / 0.35),
281
+ 0 6px 12px -4px rgb(0 0 0 / 0.18);
282
+
283
+ transform-origin: top center;
284
+ animation: menuOpen 160ms cubic-bezier(0.16, 1, 0.3, 1);
285
+ }
286
+
287
+ @keyframes menuOpen {
288
+ from {
289
+ opacity: 0;
290
+ transform: translateY(-6px) scale(0.97);
291
+ }
292
+ to {
293
+ opacity: 1;
294
+ transform: translateY(0) scale(1);
295
+ }
296
+ }
297
+
298
+ /* ---------------- In-menu search row ---------------- */
299
+ .searchRow {
300
+ display: flex;
301
+ align-items: center;
302
+ gap: 0.5rem;
303
+ padding: 0.5rem 0.75rem;
304
+ border-bottom: 1px solid $color-border-subtle;
305
+ background: $color-surface-sunken;
306
+ }
307
+
308
+ .searchIconWrap {
309
+ display: inline-flex;
310
+ color: $color-text-muted;
311
+ flex-shrink: 0;
312
+ }
313
+
314
+ .searchInput {
315
+ flex: 1;
316
+ background: none;
317
+ border: none;
318
+ outline: none;
319
+ font-family: $font-sans;
320
+ font-size: $text-sm;
321
+ color: $color-text-primary;
322
+ caret-color: $evo-primary-color;
323
+ padding: 0;
324
+
325
+ &::placeholder { color: $color-text-muted; }
326
+ }
327
+
328
+ /* ---------------- Multi-select bulk actions row ---------------- */
329
+ .bulkRow {
330
+ display: flex;
331
+ align-items: center;
332
+ gap: 0.4rem;
333
+ padding: 0.35rem 0.6rem;
334
+ border-bottom: 1px solid $color-border-subtle;
335
+ background: $color-surface-sunken;
336
+ }
337
+
338
+ .bulkBtn {
339
+ padding: 0.2rem 0.5rem;
340
+ background: transparent;
341
+ border: 1px solid $color-border;
342
+ border-radius: $radius-sm;
343
+ color: $color-text-secondary;
344
+ font-family: $font-sans;
345
+ font-size: $text-xs;
346
+ font-weight: 500;
347
+ cursor: pointer;
348
+ transition: background-color $transition-fast, color $transition-fast, border-color $transition-fast;
349
+
350
+ &:hover:not(:disabled) {
351
+ background: color-mix(in srgb, $evo-primary-color 10%, transparent);
352
+ color: $evo-primary-color;
353
+ border-color: $evo-primary-color;
354
+ }
355
+
356
+ &:disabled {
357
+ opacity: 0.4;
358
+ cursor: not-allowed;
359
+ }
360
+ }
361
+
362
+ .bulkCount {
363
+ margin-left: auto;
364
+ font-size: $text-xs;
365
+ color: $color-text-muted;
366
+ font-variant-numeric: tabular-nums;
367
+ }
368
+
369
+ /* ---------------- Options list ---------------- */
370
+ .list {
371
+ max-height: 280px;
372
+ overflow-y: auto;
373
+ padding: 0.3rem;
374
+
375
+ /* Theme-aware scrollbar (slim) */
376
+ scrollbar-width: thin;
377
+ scrollbar-color: $color-border-strong transparent;
378
+
379
+ &::-webkit-scrollbar {
380
+ width: 8px;
381
+ }
382
+ &::-webkit-scrollbar-track {
383
+ background: transparent;
384
+ }
385
+ &::-webkit-scrollbar-thumb {
386
+ background: $color-border-strong;
387
+ border-radius: 4px;
388
+ background-clip: padding-box;
389
+ border: 2px solid transparent;
390
+ }
391
+ &::-webkit-scrollbar-thumb:hover {
392
+ background: $color-text-muted;
393
+ background-clip: padding-box;
394
+ border: 2px solid transparent;
395
+ }
396
+ }
397
+
398
+ .empty {
399
+ padding: 1.5rem 0.75rem;
400
+ text-align: center;
401
+ color: $color-text-muted;
402
+ font-size: $text-sm;
403
+ }
404
+
405
+ /* ---------------- Option ---------------- */
406
+ .option {
407
+ position: relative;
408
+ display: flex;
409
+ align-items: center;
410
+ gap: 0.625rem;
411
+ width: 100%;
412
+ padding: 0.5rem 0.625rem;
413
+ background: transparent;
414
+ border: none;
415
+ border-radius: 6px;
416
+ color: $color-text-primary;
417
+ font-family: $font-sans;
418
+ font-size: $text-sm;
419
+ text-align: left;
420
+ cursor: pointer;
421
+ transition: background-color 120ms ease, color 120ms ease;
422
+
423
+ & + & { margin-top: 1px; }
424
+ }
425
+
426
+ .optionActive:not(.optionDisabled) {
427
+ background: color-mix(in srgb, $evo-primary-color 12%, transparent);
428
+ color: $color-text-primary;
429
+ }
430
+
431
+ .optionSelected {
432
+ color: $evo-primary-color;
433
+
434
+ .optionTitle { font-weight: 600; }
435
+ }
436
+
437
+ .optionDisabled {
438
+ opacity: 0.4;
439
+ cursor: not-allowed;
440
+ }
441
+
442
+ .optionIcon {
443
+ display: inline-flex;
444
+ align-items: center;
445
+ justify-content: center;
446
+ flex-shrink: 0;
447
+ color: $color-text-secondary;
448
+ font-size: 1em;
449
+ width: 1.1rem;
450
+ height: 1.1rem;
451
+ }
452
+
453
+ .optionLabel {
454
+ display: flex;
455
+ flex-direction: column;
456
+ flex: 1;
457
+ min-width: 0;
458
+ gap: 1px;
459
+ }
460
+
461
+ .optionTitle {
462
+ overflow: hidden;
463
+ text-overflow: ellipsis;
464
+ white-space: nowrap;
465
+ font-weight: 500;
466
+ }
467
+
468
+ .optionDesc {
469
+ font-size: $text-xs;
470
+ color: $color-text-muted;
471
+ font-weight: 400;
472
+ overflow: hidden;
473
+ text-overflow: ellipsis;
474
+ white-space: nowrap;
475
+ }
476
+
477
+ .check {
478
+ display: inline-flex;
479
+ align-items: center;
480
+ justify-content: center;
481
+ width: 16px;
482
+ height: 16px;
483
+ color: $evo-primary-color;
484
+ flex-shrink: 0;
485
+ }
486
+
487
+ /* ---------------- Multi-select inline checkbox ---------------- */
488
+ .checkbox {
489
+ display: inline-flex;
490
+ align-items: center;
491
+ justify-content: center;
492
+ width: 16px;
493
+ height: 16px;
494
+ border: 1.5px solid $color-border-strong;
495
+ border-radius: 4px;
496
+ color: transparent;
497
+ background: $color-surface;
498
+ flex-shrink: 0;
499
+ transition: background-color $transition-fast, border-color $transition-fast, color $transition-fast;
500
+ }
501
+
502
+ .checkboxChecked {
503
+ background: $evo-primary-color;
504
+ border-color: $evo-primary-color;
505
+ color: $evo-primary-fg;
506
+ }
507
+
508
+ .option:hover:not(.optionDisabled) .checkbox:not(.checkboxChecked) {
509
+ border-color: $evo-primary-color;
510
+ }
511
+
512
+ /* ---------------- Footer texts ---------------- */
513
+ .errorText {
514
+ font-size: $text-xs;
515
+ color: $evo-danger-color;
516
+ margin: 0;
517
+ line-height: 1.4;
518
+ }
519
+
520
+ .helperText {
521
+ font-size: $text-xs;
522
+ color: $color-text-muted;
523
+ margin: 0;
524
+ line-height: 1.4;
525
+ }
@@ -0,0 +1,30 @@
1
+ @use 'base/variables' as *;
2
+ @use 'base/color' as *;
3
+
4
+ @keyframes skeletonShimmer {
5
+ 0% { background-position: -200% 0; }
6
+ 100% { background-position: 200% 0; }
7
+ }
8
+
9
+ .skeleton {
10
+ display: block;
11
+ background-color: $color-skeleton-base;
12
+ }
13
+
14
+ .animated {
15
+ background: linear-gradient(
16
+ 90deg,
17
+ $color-skeleton-base 25%,
18
+ $color-skeleton-highlight 50%,
19
+ $color-skeleton-base 75%
20
+ );
21
+ background-size: 200% 100%;
22
+ animation: skeletonShimmer 1.6s ease-in-out infinite;
23
+ }
24
+
25
+ .textGroup {
26
+ display: flex;
27
+ flex-direction: column;
28
+ gap: 0.5rem;
29
+ width: 100%;
30
+ }