nexa-ui-kit 0.11.4 → 0.11.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.
Files changed (68) hide show
  1. package/dist/components/NAlert.js +20 -5
  2. package/dist/components/NAlert.nexa +20 -5
  3. package/dist/components/NAvatar.js +2 -0
  4. package/dist/components/NAvatar.nexa +2 -0
  5. package/dist/components/NBadge.js +5 -4
  6. package/dist/components/NBadge.nexa +5 -4
  7. package/dist/components/NBottomSheet.js +24 -22
  8. package/dist/components/NBottomSheet.nexa +9 -7
  9. package/dist/components/NButton.js +63 -18
  10. package/dist/components/NButton.nexa +63 -18
  11. package/dist/components/NCard.js +6 -5
  12. package/dist/components/NCard.nexa +6 -5
  13. package/dist/components/NCheckbox.js +62 -47
  14. package/dist/components/NCheckbox.nexa +46 -33
  15. package/dist/components/NDataTable.js +124 -100
  16. package/dist/components/NDataTable.nexa +39 -15
  17. package/dist/components/NInput.js +27 -6
  18. package/dist/components/NInput.nexa +27 -6
  19. package/dist/components/NModal.js +22 -9
  20. package/dist/components/NModal.nexa +22 -9
  21. package/dist/components/NMultiSelect.js +1 -1
  22. package/dist/components/NMultiSelect.nexa +1 -1
  23. package/dist/components/NPaginator.js +83 -1
  24. package/dist/components/NPaginator.nexa +83 -1
  25. package/dist/components/NProgressBar.js +11 -9
  26. package/dist/components/NProgressBar.nexa +11 -9
  27. package/dist/components/NRadio.js +24 -24
  28. package/dist/components/NRadio.nexa +11 -10
  29. package/dist/components/NSelect.js +38 -12
  30. package/dist/components/NSelect.nexa +38 -12
  31. package/dist/components/NSwitch.js +5 -3
  32. package/dist/components/NSwitch.nexa +5 -3
  33. package/dist/components/NTabs.js +14 -6
  34. package/dist/components/NTabs.nexa +14 -6
  35. package/dist/components/NTag.js +14 -5
  36. package/dist/components/NTag.nexa +14 -5
  37. package/dist/components/NToastContainer.js +11 -4
  38. package/dist/components/NToastContainer.nexa +11 -4
  39. package/dist/components/NTooltip.js +5 -4
  40. package/dist/components/NTooltip.nexa +5 -4
  41. package/dist/components/NTreeMenu.js +77 -34
  42. package/dist/components/NTreeMenu.nexa +55 -12
  43. package/dist/styles/theme.js +69 -55
  44. package/dist/styles/tokens.css +90 -74
  45. package/package.json +4 -4
  46. package/src/components/NAlert.nexa +20 -5
  47. package/src/components/NAvatar.nexa +2 -0
  48. package/src/components/NBadge.nexa +5 -4
  49. package/src/components/NBottomSheet.nexa +9 -7
  50. package/src/components/NButton.nexa +63 -18
  51. package/src/components/NCard.nexa +6 -5
  52. package/src/components/NCheckbox.nexa +46 -33
  53. package/src/components/NDataTable.nexa +39 -15
  54. package/src/components/NInput.nexa +27 -6
  55. package/src/components/NModal.nexa +22 -9
  56. package/src/components/NMultiSelect.nexa +1 -1
  57. package/src/components/NPaginator.nexa +83 -1
  58. package/src/components/NProgressBar.nexa +11 -9
  59. package/src/components/NRadio.nexa +11 -10
  60. package/src/components/NSelect.nexa +38 -12
  61. package/src/components/NSwitch.nexa +5 -3
  62. package/src/components/NTabs.nexa +14 -6
  63. package/src/components/NTag.nexa +14 -5
  64. package/src/components/NToastContainer.nexa +11 -4
  65. package/src/components/NTooltip.nexa +5 -4
  66. package/src/components/NTreeMenu.nexa +55 -12
  67. package/src/styles/theme.ts +69 -55
  68. package/src/styles/tokens.css +90 -74
@@ -73,5 +73,87 @@ const end = computed(() => Math.min((safeFirst.value || 0) + (safeRows.value ||
73
73
  </template>
74
74
 
75
75
  <style scoped>
76
- .n-paginator{display:flex;align-items:center;justify-content:space-between;gap:var(--n-space-3);padding:var(--n-space-3) var(--n-space-4);border-top:1px solid var(--n-color-border);background:var(--n-color-surface);font-family:var(--n-font-sans)}.n-paginator-report{color:var(--n-color-text-muted);font-size:var(--n-text-xs)}.n-paginator-center{display:flex;align-items:center;gap:0.35rem}.n-pg-btn{background:transparent;border:1px solid var(--n-color-border);color:var(--n-color-text);border-radius:var(--n-radius-sm);padding:0.25rem 0.5rem;cursor:pointer;transition:all var(--n-transition-fast)}.n-pg-btn:hover:not(:disabled){background:var(--n-color-glass)}.n-pg-btn:disabled{opacity:0.5;cursor:not-allowed}.n-pg-page{min-width:5rem;text-align:center;color:var(--n-color-text-secondary);font-size:var(--n-text-xs)}.n-pg-select{background:var(--n-color-bg);border:1px solid var(--n-color-border);color:var(--n-color-text);border-radius:var(--n-radius-sm);padding:0.25rem 0.5rem;font-size:var(--n-text-xs);outline:none}
76
+ .n-paginator {
77
+ display: flex;
78
+ align-items: center;
79
+ justify-content: space-between;
80
+ gap: var(--n-space-3);
81
+ padding: var(--n-space-3) var(--n-space-4);
82
+ border-top: 1px solid var(--n-color-border);
83
+ background: var(--n-color-surface);
84
+ font-family: var(--n-font-sans);
85
+ }
86
+
87
+ .n-paginator-report {
88
+ color: var(--n-color-text-muted);
89
+ font-size: var(--n-text-xs);
90
+ }
91
+
92
+ .n-paginator-center {
93
+ display: flex;
94
+ align-items: center;
95
+ gap: var(--n-space-2);
96
+ }
97
+
98
+ .n-pg-btn {
99
+ background: transparent;
100
+ border: 1px solid var(--n-color-border);
101
+ color: var(--n-color-text);
102
+ border-radius: var(--n-radius-md);
103
+ padding: 0.3rem 0.55rem;
104
+ cursor: pointer;
105
+ transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
106
+ display: inline-flex;
107
+ align-items: center;
108
+ justify-content: center;
109
+ }
110
+
111
+ .n-pg-btn:hover:not(:disabled) {
112
+ background: var(--n-color-glass);
113
+ transform: scale(1.05);
114
+ }
115
+
116
+ .n-pg-btn:active:not(:disabled) {
117
+ transform: scale(0.97);
118
+ }
119
+
120
+ .n-pg-btn:focus-visible {
121
+ outline: 2px solid var(--n-color-primary);
122
+ outline-offset: 2px;
123
+ }
124
+
125
+ .n-pg-btn:disabled {
126
+ opacity: 0.5;
127
+ cursor: not-allowed;
128
+ }
129
+
130
+ .n-pg-page {
131
+ min-width: 2.5rem;
132
+ text-align: center;
133
+ font-size: var(--n-text-xs);
134
+ font-weight: var(--n-weight-semibold);
135
+ padding: 0.25rem 0.5rem;
136
+ background: var(--n-color-primary);
137
+ color: white;
138
+ border-radius: var(--n-radius-md);
139
+ line-height: 1.4;
140
+ }
141
+
142
+ .n-pg-select {
143
+ background: var(--n-color-bg);
144
+ border: 1px solid var(--n-color-border);
145
+ color: var(--n-color-text);
146
+ border-radius: var(--n-radius-md);
147
+ padding: 0.3rem 0.55rem;
148
+ font-size: var(--n-text-xs);
149
+ outline: none;
150
+ cursor: pointer;
151
+ transition: border-color 0.2s cubic-bezier(0.16, 1, 0.3, 1);
152
+ }
153
+
154
+ .n-pg-select:focus-visible {
155
+ border-color: var(--n-color-primary);
156
+ outline: 2px solid var(--n-color-primary);
157
+ outline-offset: 2px;
158
+ }
77
159
  </style>
@@ -42,28 +42,30 @@ const percentage = computed(() => Math.min(100, Math.max(0, (props.value / props
42
42
  background: var(--n-color-surface-alt);
43
43
  border-radius: var(--n-radius-full);
44
44
  overflow: hidden;
45
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);
45
46
  }
46
47
 
47
- .is-sm .n-progress-track { height: 6px; }
48
- .is-md .n-progress-track { height: 10px; }
49
- .is-lg .n-progress-track { height: 14px; }
48
+ .is-sm .n-progress-track { height: 8px; }
49
+ .is-md .n-progress-track { height: 12px; }
50
+ .is-lg .n-progress-track { height: 16px; }
50
51
 
51
52
  .n-progress-bar {
52
53
  height: 100%;
53
54
  border-radius: var(--n-radius-full);
54
- transition: width var(--n-transition-slow);
55
+ transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1);
55
56
  display: flex;
56
57
  align-items: center;
57
58
  justify-content: flex-end;
58
59
  padding-right: 0.35rem;
59
60
  min-width: 0;
61
+ box-shadow: 0 0 8px rgba(99, 102, 241, 0.3);
60
62
  }
61
63
 
62
- .is-primary { background: var(--n-color-primary); }
63
- .is-success { background: var(--n-color-success); }
64
- .is-danger { background: var(--n-color-danger); }
65
- .is-warning { background: var(--n-color-warning); }
66
- .is-info { background: var(--n-color-info); }
64
+ .is-primary { background: var(--n-color-primary); box-shadow: 0 0 8px rgba(99, 102, 241, 0.3); }
65
+ .is-success { background: var(--n-color-success); box-shadow: 0 0 8px rgba(34, 197, 94, 0.3); }
66
+ .is-danger { background: var(--n-color-danger); box-shadow: 0 0 8px rgba(239, 68, 68, 0.3); }
67
+ .is-warning { background: var(--n-color-warning); box-shadow: 0 0 8px rgba(234, 179, 8, 0.3); }
68
+ .is-info { background: var(--n-color-info); box-shadow: 0 0 8px rgba(59, 130, 246, 0.3); }
67
69
 
68
70
  .n-progress-label {
69
71
  color: white;
@@ -20,7 +20,7 @@ const select = () => {
20
20
  <template>
21
21
  <label class="n-radio" :class="{ 'is-checked': isChecked(), 'is-disabled': disabled }">
22
22
  <div class="n-radio-circle" @click="select">
23
- <div class="n-radio-dot"></div>
23
+ <div v-if="isChecked()" class="n-radio-dot"></div>
24
24
  </div>
25
25
  <span v-if="label" class="n-radio-label">{{ label }}</span>
26
26
  </label>
@@ -36,32 +36,33 @@ const select = () => {
36
36
  }
37
37
 
38
38
  .n-radio-circle {
39
- width: 20px;
40
- height: 20px;
39
+ width: 22px;
40
+ height: 22px;
41
41
  border: 2px solid var(--n-color-border);
42
42
  border-radius: var(--n-radius-full);
43
43
  display: flex;
44
44
  align-items: center;
45
45
  justify-content: center;
46
- transition: all var(--n-transition-fast);
46
+ transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
47
47
  flex-shrink: 0;
48
48
  }
49
49
 
50
50
  .is-checked .n-radio-circle {
51
51
  border-color: var(--n-color-primary);
52
+ box-shadow: 0 0 0 3px var(--n-color-primary-light), 0 0 12px rgba(99, 102, 241, 0.25);
52
53
  }
53
54
 
54
55
  .n-radio-dot {
55
- width: 10px;
56
- height: 10px;
56
+ width: 11px;
57
+ height: 11px;
57
58
  border-radius: var(--n-radius-full);
58
59
  background: var(--n-color-primary);
59
- transform: scale(0);
60
- transition: all var(--n-transition-spring);
60
+ animation: n-radio-dot-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
61
61
  }
62
62
 
63
- .is-checked .n-radio-dot {
64
- transform: scale(1);
63
+ @keyframes n-radio-dot-in {
64
+ from { transform: scale(0); }
65
+ to { transform: scale(1); }
65
66
  }
66
67
 
67
68
  .n-radio-label {
@@ -302,7 +302,8 @@ onBeforeUnmount(() => {
302
302
 
303
303
  .n-select-trigger:focus-visible {
304
304
  border-color: var(--n-color-primary);
305
- box-shadow: 0 0 0 3px var(--n-color-primary-light);
305
+ box-shadow: 0 0 0 3px var(--n-color-primary-light), 0 0 20px rgba(var(--n-color-primary-rgb, 99, 102, 241), 0.12);
306
+ outline: none;
306
307
  }
307
308
 
308
309
  .n-select:hover .n-select-trigger:not(.is-disabled) {
@@ -311,7 +312,7 @@ onBeforeUnmount(() => {
311
312
 
312
313
  .n-select.is-open .n-select-trigger {
313
314
  border-color: var(--n-color-primary);
314
- box-shadow: 0 0 0 3px var(--n-color-primary-light);
315
+ box-shadow: 0 0 0 3px var(--n-color-primary-light), 0 0 20px rgba(var(--n-color-primary-rgb, 99, 102, 241), 0.12);
315
316
  }
316
317
 
317
318
  .n-select-placeholder {
@@ -342,7 +343,7 @@ onBeforeUnmount(() => {
342
343
 
343
344
  .n-select-arrow {
344
345
  color: var(--n-color-text-muted);
345
- transition: transform var(--n-transition-fast);
346
+ transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
346
347
  font-size: var(--n-text-xs);
347
348
  }
348
349
 
@@ -355,27 +356,30 @@ onBeforeUnmount(() => {
355
356
  top: calc(100% + 0.5rem);
356
357
  left: 0;
357
358
  width: 100%;
358
- background: var(--n-color-surface);
359
+ background: color-mix(in srgb, var(--n-color-surface) 90%, transparent);
360
+ backdrop-filter: blur(16px) saturate(1.15);
361
+ -webkit-backdrop-filter: blur(16px) saturate(1.15);
359
362
  border: 1px solid var(--n-color-border);
360
363
  border-radius: var(--n-radius-md);
361
- box-shadow: var(--n-shadow-lg);
364
+ box-shadow: var(--n-shadow-lg), 0 8px 32px rgba(0,0,0,0.08);
362
365
  z-index: var(--n-z-dropdown);
363
366
  overflow: hidden;
364
- animation: n-dropdown-in 0.2s ease-out;
367
+ animation: n-dropdown-in 0.3s cubic-bezier(0.16, 1, 0.3, 1);
368
+ transform-origin: top center;
365
369
  }
366
370
 
367
371
  @keyframes n-dropdown-in {
368
- from { opacity: 0; transform: translateY(-8px); }
369
- to { opacity: 1; transform: translateY(0); }
372
+ from { opacity: 0; transform: translateY(-6px) scale(0.98); }
373
+ to { opacity: 1; transform: translateY(0) scale(1); }
370
374
  }
371
375
 
372
376
  .n-select-dropdown.is-top {
373
- animation: n-dropdown-in-top 0.2s ease-out;
377
+ animation: n-dropdown-in-top 0.3s cubic-bezier(0.16, 1, 0.3, 1);
374
378
  }
375
379
 
376
380
  @keyframes n-dropdown-in-top {
377
- from { opacity: 0; transform: translateY(8px); }
378
- to { opacity: 1; transform: translateY(0); }
381
+ from { opacity: 0; transform: translateY(6px) scale(0.98); }
382
+ to { opacity: 1; transform: translateY(0) scale(1); }
379
383
  }
380
384
 
381
385
  .n-select-search {
@@ -416,15 +420,37 @@ onBeforeUnmount(() => {
416
420
 
417
421
  .n-select-option {
418
422
  padding: 0.7rem 1rem;
423
+ padding-left: 1rem;
419
424
  color: var(--n-color-text-secondary);
420
425
  cursor: pointer;
421
- transition: all var(--n-transition-fast);
426
+ transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
427
+ letter-spacing: 0.01em;
428
+ position: relative;
429
+ }
430
+
431
+ .n-select-option::before {
432
+ content: '';
433
+ position: absolute;
434
+ left: 0;
435
+ top: 50%;
436
+ transform: translateY(-50%) scaleY(0);
437
+ width: 3px;
438
+ height: 50%;
439
+ background: var(--n-color-primary);
440
+ border-radius: 0 3px 3px 0;
441
+ transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
442
+ }
443
+
444
+ .n-select-option:hover::before,
445
+ .n-select-option.is-focused::before {
446
+ transform: translateY(-50%) scaleY(1);
422
447
  }
423
448
 
424
449
  .n-select-option:hover,
425
450
  .n-select-option.is-focused {
426
451
  background: var(--n-color-glass);
427
452
  color: var(--n-color-text);
453
+ padding-left: 1.25rem;
428
454
  }
429
455
 
430
456
  .n-select-option.is-selected {
@@ -37,12 +37,13 @@ const toggle = () => {
37
37
  background: var(--n-color-surface-hover);
38
38
  border-radius: var(--n-radius-full);
39
39
  position: relative;
40
- transition: all var(--n-transition-fast);
40
+ transition: all var(--n-transition-normal);
41
41
  flex-shrink: 0;
42
42
  }
43
43
 
44
44
  .is-checked .n-switch-track {
45
45
  background: var(--n-color-primary);
46
+ box-shadow: var(--n-shadow-glow-primary);
46
47
  }
47
48
 
48
49
  .n-switch-thumb {
@@ -53,14 +54,15 @@ const toggle = () => {
53
54
  position: absolute;
54
55
  top: 3px;
55
56
  left: 3px;
56
- transition: transform var(--n-transition-spring), background var(--n-transition-normal);
57
- box-shadow: var(--n-shadow-sm);
57
+ transition: transform var(--n-transition-normal), background var(--n-transition-normal);
58
+ box-shadow: var(--n-shadow-md);
58
59
  will-change: transform;
59
60
  }
60
61
 
61
62
  .is-checked .n-switch-thumb {
62
63
  transform: translateX(20px);
63
64
  background: white;
65
+ box-shadow: var(--n-shadow-md);
64
66
  }
65
67
 
66
68
  .n-switch-label {
@@ -72,10 +72,17 @@ const activeIndex = computed(() =>
72
72
  position: relative;
73
73
  user-select: none;
74
74
  white-space: nowrap;
75
+ border-radius: var(--n-radius-sm) var(--n-radius-sm) 0 0;
75
76
  }
76
77
 
77
- .n-tab:hover {
78
- color: var(--n-color-text-secondary);
78
+ .n-tab:hover:not(.is-active):not(.is-disabled) {
79
+ color: var(--n-color-text);
80
+ background: var(--n-color-glass);
81
+ }
82
+
83
+ .n-tab:focus-visible {
84
+ outline: none;
85
+ box-shadow: inset 0 0 0 2px var(--n-color-primary);
79
86
  }
80
87
 
81
88
  .n-tab.is-active {
@@ -104,10 +111,11 @@ const activeIndex = computed(() =>
104
111
 
105
112
  .n-tabs-indicator {
106
113
  position: absolute;
107
- bottom: 0;
108
- height: 2px;
114
+ bottom: -1px;
115
+ height: 2.5px;
109
116
  background: var(--n-color-primary);
110
- transition: all var(--n-transition-normal);
111
- border-radius: var(--n-radius-full) var(--n-radius-full) 0 0;
117
+ transition: all 0.35s cubic-bezier(0.16, 1, 0.3, 1);
118
+ border-radius: var(--n-radius-full);
119
+ box-shadow: 0 1px 6px rgba(99, 102, 241, 0.35);
112
120
  }
113
121
  </style>
@@ -21,7 +21,7 @@ const emit = defineEmits(['close'])
21
21
  display: inline-flex;
22
22
  align-items: center;
23
23
  gap: var(--n-space-1);
24
- padding: 0.2rem 0.6rem;
24
+ padding: 0.25rem 0.7rem;
25
25
  font-size: var(--n-text-xs);
26
26
  font-weight: var(--n-weight-semibold);
27
27
  border-radius: var(--n-radius-sm);
@@ -29,14 +29,15 @@ const emit = defineEmits(['close'])
29
29
  font-family: var(--n-font-sans);
30
30
  white-space: nowrap;
31
31
  border: 1px solid transparent;
32
+ letter-spacing: 0.02em;
32
33
  }
33
34
 
34
35
  .n-tag.is-rounded {
35
36
  border-radius: var(--n-radius-full);
36
37
  }
37
38
 
38
- .n-tag-sm { padding: 0.1rem 0.4rem; font-size: 0.65rem; }
39
- .n-tag-lg { padding: 0.35rem 0.8rem; font-size: var(--n-text-sm); }
39
+ .n-tag-sm { padding: 0.15rem 0.5rem; font-size: 0.65rem; }
40
+ .n-tag-lg { padding: 0.4rem 0.9rem; font-size: var(--n-text-sm); }
40
41
 
41
42
  .n-tag-primary {
42
43
  background: var(--n-color-primary-light);
@@ -83,11 +84,19 @@ const emit = defineEmits(['close'])
83
84
  padding: 0;
84
85
  margin-left: var(--n-space-1);
85
86
  color: inherit;
86
- opacity: 0.6;
87
- transition: opacity var(--n-transition-fast);
87
+ opacity: 0.5;
88
+ transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
89
+ border-radius: var(--n-radius-sm);
90
+ display: flex;
91
+ align-items: center;
92
+ justify-content: center;
93
+ width: 18px;
94
+ height: 18px;
88
95
  }
89
96
 
90
97
  .n-tag-close:hover {
91
98
  opacity: 1;
99
+ background: rgba(0,0,0,0.08);
100
+ transform: scale(1.15);
92
101
  }
93
102
  </style>
@@ -84,16 +84,23 @@ const positionClass = `is-${props.position.replace('-', '-')}`
84
84
  pointer-events: auto;
85
85
  min-width: 300px;
86
86
  max-width: 420px;
87
- background: var(--n-color-surface);
87
+ background: var(--n-color-glass);
88
88
  border: 1px solid var(--n-color-border);
89
89
  border-radius: var(--n-radius-md);
90
90
  overflow: hidden;
91
- box-shadow: var(--n-shadow-lg);
91
+ box-shadow: var(--n-shadow-lg), 0 8px 32px rgba(0, 0, 0, 0.08);
92
92
  cursor: pointer;
93
- animation: n-toast-in var(--n-transition-spring);
94
- transition: all var(--n-transition-fast);
93
+ animation: n-toast-in 0.35s cubic-bezier(0.16, 1, 0.3, 1);
94
+ transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
95
+ backdrop-filter: blur(16px);
96
+ border-left: 3px solid var(--n-color-border);
95
97
  }
96
98
 
99
+ .is-success { border-left-color: var(--n-color-success); }
100
+ .is-error { border-left-color: var(--n-color-danger); }
101
+ .is-info { border-left-color: var(--n-color-primary); }
102
+ .is-warning { border-left-color: var(--n-color-warning); }
103
+
97
104
  .n-toast:hover {
98
105
  transform: scale(1.02);
99
106
  background: var(--n-color-surface-alt);
@@ -95,18 +95,19 @@ const hide = () => {
95
95
  }
96
96
 
97
97
  .n-tooltip {
98
- background: var(--n-color-bg);
98
+ background: var(--n-color-glass);
99
99
  color: var(--n-color-text);
100
100
  padding: var(--n-space-2) var(--n-space-3);
101
101
  border-radius: var(--n-radius-sm);
102
102
  font-size: var(--n-text-xs);
103
- font-weight: var(--n-weight-medium);
103
+ font-weight: var(--n-weight-semibold);
104
104
  white-space: nowrap;
105
105
  z-index: var(--n-z-tooltip);
106
- box-shadow: var(--n-shadow-lg);
106
+ box-shadow: var(--n-shadow-lg), 0 4px 16px rgba(0, 0, 0, 0.1);
107
107
  border: 1px solid var(--n-color-border);
108
108
  pointer-events: none;
109
- animation: n-tooltip-in 0.2s ease-out;
109
+ animation: n-tooltip-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
110
+ backdrop-filter: blur(12px);
110
111
  }
111
112
 
112
113
  @keyframes n-tooltip-in {
@@ -48,13 +48,13 @@ const toggle = (id, e) => {
48
48
  </script>
49
49
 
50
50
  <template>
51
- <div class="n-tree-menu">
51
+ <div class="n-tree-menu" role="tree">
52
52
  <div v-for="item in flatTree.value" :key="item.id"
53
53
  class="n-tree-item"
54
54
  :class="{ 'is-selected': isSelected(item.id) }"
55
55
  :style="{ '--n-tree-depth': String(item._depth) }"
56
56
  >
57
- <div class="n-tree-row" @click="selectItem(item)">
57
+ <div class="n-tree-row" tabindex="0" role="treeitem" :aria-selected="isSelected(item.id)" @click="selectItem(item)">
58
58
  <button v-if="hasChildren(item)"
59
59
  class="n-tree-toggle"
60
60
  :class="{ 'is-expanded': isExpanded(item.id) }"
@@ -78,6 +78,11 @@ const toggle = (id, e) => {
78
78
  .n-tree-item {
79
79
  --n-tree-depth: 0;
80
80
  position: relative;
81
+ margin-bottom: 1px;
82
+ }
83
+
84
+ .n-tree-item:last-child {
85
+ margin-bottom: 0;
81
86
  }
82
87
 
83
88
  /* Líneas conectoras verticales */
@@ -89,18 +94,18 @@ const toggle = (id, e) => {
89
94
  bottom: 0;
90
95
  width: 1px;
91
96
  background: var(--n-color-border);
92
- opacity: 0.5;
97
+ opacity: 0.35;
93
98
  }
94
99
 
95
100
  .n-tree-row {
96
101
  display: flex;
97
102
  align-items: center;
98
103
  gap: 0.5rem;
99
- padding: 0.5rem 0.75rem;
104
+ padding: 0.55rem 0.75rem;
100
105
  padding-left: calc(0.75rem + var(--n-tree-depth, 0) * 1.25rem);
101
106
  border-radius: var(--n-radius-sm);
102
107
  cursor: pointer;
103
- transition: all var(--n-transition-fast);
108
+ transition: background 0.25s cubic-bezier(0.16, 1, 0.3, 1), color 0.25s cubic-bezier(0.16, 1, 0.3, 1);
104
109
  color: var(--n-color-text);
105
110
  position: relative;
106
111
  }
@@ -114,11 +119,15 @@ const toggle = (id, e) => {
114
119
  width: 0.75rem;
115
120
  height: 1px;
116
121
  background: var(--n-color-border);
117
- opacity: 0.5;
122
+ opacity: 0.35;
118
123
  }
119
124
 
120
125
  .n-tree-row:hover {
121
- background: var(--n-color-surface-hover);
126
+ background: linear-gradient(135deg, var(--n-color-surface-hover), color-mix(in srgb, var(--n-color-surface-hover) 85%, var(--n-color-primary) 5%));
127
+ }
128
+
129
+ .n-tree-row:active {
130
+ background: color-mix(in srgb, var(--n-color-surface-hover) 80%, var(--n-color-text) 5%);
122
131
  }
123
132
 
124
133
  .n-tree-item.is-selected > .n-tree-row {
@@ -127,26 +136,54 @@ const toggle = (id, e) => {
127
136
  font-weight: var(--n-weight-semibold);
128
137
  }
129
138
 
139
+ .n-tree-item.is-selected > .n-tree-row::after {
140
+ content: '';
141
+ position: absolute;
142
+ left: 0;
143
+ top: 0;
144
+ bottom: 0;
145
+ width: 3px;
146
+ background: var(--n-color-primary);
147
+ border-radius: 0 var(--n-radius-sm) var(--n-radius-sm) 0;
148
+ }
149
+
130
150
  .n-tree-toggle {
131
151
  background: var(--n-color-glass);
132
152
  border: 1px solid var(--n-color-border);
133
- border-radius: var(--n-radius-sm);
153
+ border-radius: var(--n-radius-md);
134
154
  color: var(--n-color-text-secondary);
135
155
  cursor: pointer;
136
- width: 20px;
137
- height: 20px;
156
+ width: 22px;
157
+ height: 22px;
138
158
  display: flex;
139
159
  align-items: center;
140
160
  justify-content: center;
141
161
  padding: 0;
142
- transition: all var(--n-transition-fast);
162
+ transition: background 0.25s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.25s cubic-bezier(0.16, 1, 0.3, 1), color 0.25s cubic-bezier(0.16, 1, 0.3, 1), transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
143
163
  flex-shrink: 0;
144
164
  }
145
165
 
146
166
  .n-tree-toggle:hover {
147
- background: var(--n-color-primary-light);
167
+ background: color-mix(in srgb, var(--n-color-primary-light) 80%, var(--n-color-primary) 10%);
148
168
  border-color: var(--n-color-primary);
149
169
  color: var(--n-color-primary);
170
+ transform: scale(1.05);
171
+ }
172
+
173
+ .n-tree-toggle:active {
174
+ transform: scale(0.95);
175
+ }
176
+
177
+ .n-tree-toggle:focus-visible {
178
+ outline: none;
179
+ box-shadow: 0 0 0 2px var(--n-color-background), 0 0 0 4px var(--n-color-primary);
180
+ z-index: 1;
181
+ }
182
+
183
+ .n-tree-row:focus-visible {
184
+ outline: none;
185
+ box-shadow: inset 0 0 0 2px var(--n-color-primary);
186
+ border-radius: var(--n-radius-md);
150
187
  }
151
188
 
152
189
  .n-tree-toggle-icon {
@@ -173,5 +210,11 @@ const toggle = (id, e) => {
173
210
  text-overflow: ellipsis;
174
211
  white-space: nowrap;
175
212
  font-weight: var(--n-weight-medium);
213
+ letter-spacing: 0.01em;
214
+ }
215
+
216
+ .n-tree-item.is-selected .n-tree-label {
217
+ font-weight: var(--n-weight-bold);
218
+ letter-spacing: 0;
176
219
  }
177
220
  </style>