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
@@ -67,9 +67,10 @@ const btnClass = computed(() => {
67
67
  gap: var(--n-space-2);
68
68
  font-family: var(--n-font-sans);
69
69
  font-weight: var(--n-weight-semibold);
70
+ letter-spacing: 0.01em;
70
71
  border-radius: var(--n-radius-md);
71
72
  cursor: pointer;
72
- transition: all var(--n-transition-normal);
73
+ transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
73
74
  border: 1px solid transparent;
74
75
  outline: none;
75
76
  white-space: nowrap;
@@ -78,16 +79,18 @@ const btnClass = computed(() => {
78
79
  text-decoration: none;
79
80
  line-height: var(--n-leading-normal, 1.5);
80
81
  min-width: fit-content;
82
+ will-change: transform;
83
+ -webkit-tap-highlight-color: transparent;
81
84
  }
82
85
 
83
86
  .n-btn:focus-visible {
84
- box-shadow: 0 0 0 3px var(--n-color-primary-light);
87
+ box-shadow: 0 0 0 3px var(--n-color-primary-light), 0 0 0 1px var(--n-color-primary);
85
88
  }
86
89
 
87
90
  /* Sizes */
88
- .n-btn-sm { padding: 0.5rem 1.25rem; font-size: var(--n-text-sm); gap: var(--n-space-1); border-radius: var(--n-radius-sm); min-height: 32px; }
89
- .n-btn-md { padding: 0.65rem 1.75rem; font-size: var(--n-text-base); min-height: 40px; }
90
- .n-btn-lg { padding: 0.85rem 2.5rem; font-size: var(--n-text-lg); border-radius: var(--n-radius-lg); min-height: 48px; }
91
+ .n-btn-sm { padding: 0.5rem 1.5rem; font-size: var(--n-text-sm); gap: var(--n-space-1); border-radius: var(--n-radius-sm); min-height: 36px; }
92
+ .n-btn-md { padding: 0.75rem 2rem; font-size: var(--n-text-base); min-height: 44px; }
93
+ .n-btn-lg { padding: 1rem 2.75rem; font-size: var(--n-text-lg); border-radius: var(--n-radius-lg); min-height: 52px; }
91
94
 
92
95
  /* Block */
93
96
  .is-block { width: 100%; }
@@ -95,18 +98,25 @@ const btnClass = computed(() => {
95
98
  /* Rounded */
96
99
  .is-rounded { border-radius: var(--n-radius-full); }
97
100
 
101
+ /* Active/Press */
102
+ .n-btn:active:not(:disabled) {
103
+ transform: scale(0.97);
104
+ }
105
+
98
106
  /* Variant: Primary */
99
107
  .n-btn-primary {
100
- background: linear-gradient(135deg, var(--n-color-primary) 0%, var(--n-color-primary-hover) 100%);
108
+ background: linear-gradient(135deg, #6366f1 0%, #4f46e5 50%, #4338ca 100%);
101
109
  color: white;
102
- box-shadow: var(--n-shadow-glow-primary);
110
+ box-shadow: 0 4px 14px rgba(99, 102, 241, 0.4), 0 0 0 1px rgba(99, 102, 241, 0.3);
111
+ text-shadow: 0 1px 2px rgba(0,0,0,0.2);
103
112
  }
104
113
  .n-btn-primary:hover:not(:disabled) {
105
- transform: translateY(-2px);
106
- box-shadow: 0 8px 20px -3px var(--n-color-primary-glow);
114
+ transform: translateY(-3px) scale(1.02);
115
+ box-shadow: 0 8px 25px rgba(99, 102, 241, 0.5), 0 0 0 1px rgba(99, 102, 241, 0.4), 0 0 40px rgba(99, 102, 241, 0.15);
107
116
  }
108
117
  .n-btn-primary:active:not(:disabled) {
109
- transform: translateY(0) scale(0.97);
118
+ transform: translateY(-1px) scale(0.98);
119
+ box-shadow: 0 2px 8px rgba(99, 102, 241, 0.4), inset 0 2px 4px rgba(0,0,0,0.15);
110
120
  }
111
121
 
112
122
  /* Variant: Secondary */
@@ -118,6 +128,10 @@ const btnClass = computed(() => {
118
128
  .n-btn-secondary:hover:not(:disabled) {
119
129
  background: var(--n-color-surface-hover);
120
130
  border-color: var(--n-color-border-hover);
131
+ transform: translateY(-1px);
132
+ }
133
+ .n-btn-secondary:active:not(:disabled) {
134
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.08);
121
135
  }
122
136
 
123
137
  /* Variant: Success */
@@ -131,7 +145,7 @@ const btnClass = computed(() => {
131
145
  box-shadow: var(--n-shadow-glow-success);
132
146
  }
133
147
  .n-btn-success:active:not(:disabled) {
134
- transform: translateY(0) scale(0.97);
148
+ box-shadow: var(--n-shadow-glow-success), inset 0 1px 3px rgba(0,0,0,0.15);
135
149
  }
136
150
 
137
151
  /* Variant: Warning */
@@ -145,7 +159,7 @@ const btnClass = computed(() => {
145
159
  box-shadow: var(--n-shadow-glow-warning);
146
160
  }
147
161
  .n-btn-warning:active:not(:disabled) {
148
- transform: translateY(0) scale(0.97);
162
+ box-shadow: var(--n-shadow-glow-warning), inset 0 1px 3px rgba(0,0,0,0.15);
149
163
  }
150
164
 
151
165
  /* Variant: Info */
@@ -159,7 +173,7 @@ const btnClass = computed(() => {
159
173
  box-shadow: var(--n-shadow-glow-info);
160
174
  }
161
175
  .n-btn-info:active:not(:disabled) {
162
- transform: translateY(0) scale(0.97);
176
+ box-shadow: var(--n-shadow-glow-info), inset 0 1px 3px rgba(0,0,0,0.15);
163
177
  }
164
178
 
165
179
  /* Variant: Danger */
@@ -173,28 +187,46 @@ const btnClass = computed(() => {
173
187
  box-shadow: var(--n-shadow-glow-danger);
174
188
  }
175
189
  .n-btn-danger:active:not(:disabled) {
176
- transform: translateY(0) scale(0.97);
190
+ box-shadow: var(--n-shadow-glow-danger), inset 0 1px 3px rgba(0,0,0,0.15);
177
191
  }
178
192
 
179
193
  /* Variant: Ghost */
180
194
  .n-btn-ghost {
181
195
  background: transparent;
196
+ backdrop-filter: blur(12px);
197
+ -webkit-backdrop-filter: blur(12px);
182
198
  color: var(--n-color-text-secondary);
199
+ border-color: transparent;
183
200
  }
184
201
  .n-btn-ghost:hover:not(:disabled) {
185
202
  background: var(--n-color-glass);
203
+ backdrop-filter: blur(12px);
204
+ -webkit-backdrop-filter: blur(12px);
186
205
  color: var(--n-color-text);
206
+ border-color: var(--n-color-glass-border);
207
+ }
208
+ .n-btn-ghost:active:not(:disabled) {
209
+ background: var(--n-color-glass-hover);
210
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.06);
187
211
  }
188
212
 
189
213
  /* Variant: Outline */
190
214
  .n-btn-outline {
191
215
  background: transparent;
192
216
  color: var(--n-color-primary);
193
- border-color: var(--n-color-primary);
217
+ border: 1.5px solid transparent;
218
+ background-image: linear-gradient(transparent, transparent), linear-gradient(135deg, var(--n-color-primary), var(--n-color-primary-hover));
219
+ background-origin: padding-box, border-box;
220
+ background-clip: padding-box, border-box;
194
221
  }
195
222
  .n-btn-outline:hover:not(:disabled) {
196
- background: var(--n-color-primary-light);
197
- border-color: var(--n-color-primary-hover);
223
+ background-image: linear-gradient(var(--n-color-primary-light), var(--n-color-primary-light)), linear-gradient(135deg, var(--n-color-primary-hover), var(--n-color-primary));
224
+ background-origin: padding-box, border-box;
225
+ background-clip: padding-box, border-box;
226
+ color: var(--n-color-primary-hover);
227
+ }
228
+ .n-btn-outline:active:not(:disabled) {
229
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.08);
198
230
  }
199
231
 
200
232
  /* Variant: Glass */
@@ -208,13 +240,26 @@ const btnClass = computed(() => {
208
240
  background: var(--n-color-glass-hover);
209
241
  border-color: var(--n-color-border-hover);
210
242
  }
243
+ .n-btn-glass:active:not(:disabled) {
244
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.08);
245
+ }
211
246
 
212
247
  /* Disabled */
213
248
  .n-btn:disabled {
214
- opacity: 0.45;
215
249
  cursor: not-allowed;
216
250
  transform: none !important;
217
251
  box-shadow: none !important;
252
+ pointer-events: none;
253
+ opacity: 0.55;
254
+ }
255
+ .n-btn:disabled::after {
256
+ content: '';
257
+ position: absolute;
258
+ inset: 0;
259
+ border-radius: inherit;
260
+ background: var(--n-color-surface, #fff);
261
+ opacity: 0.3;
262
+ pointer-events: none;
218
263
  }
219
264
 
220
265
  /* Loader */
@@ -32,16 +32,17 @@ const props = defineProps({
32
32
  .n-card {
33
33
  background: var(--n-color-surface);
34
34
  border: 1px solid var(--n-color-border);
35
- border-radius: var(--n-radius-xl);
35
+ border-radius: var(--n-radius-lg);
36
36
  overflow: hidden;
37
- transition: all var(--n-transition-normal);
37
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
38
38
  display: flex;
39
39
  flex-direction: column;
40
+ will-change: transform, box-shadow;
40
41
  }
41
42
 
42
43
  .is-elevated {
43
44
  background: var(--n-color-surface-elevated);
44
- box-shadow: var(--n-shadow-lg);
45
+ box-shadow: var(--n-shadow-md);
45
46
  }
46
47
 
47
48
  .is-outlined {
@@ -57,9 +58,9 @@ const props = defineProps({
57
58
  }
58
59
 
59
60
  .n-card.is-hoverable:hover {
60
- transform: translateY(-4px);
61
+ transform: translateY(-2px);
61
62
  border-color: var(--n-color-border-hover);
62
- box-shadow: var(--n-shadow-xl);
63
+ box-shadow: var(--n-shadow-lg);
63
64
  }
64
65
 
65
66
  .n-card-image {
@@ -17,10 +17,12 @@ const toggle = () => {
17
17
  <template>
18
18
  <label class="n-checkbox" :class="{ 'is-checked': modelValue && !indeterminate, 'is-indeterminate': indeterminate, 'is-disabled': disabled }">
19
19
  <div class="n-checkbox-box" @click="toggle">
20
- <span class="n-checkbox-icon">
21
- <svg v-if="indeterminate" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" focusable="false" aria-hidden="true"><line x1="4" y1="12" x2="20" y2="12"/></svg>
22
- <svg v-else viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
23
- </span>
20
+ <div v-if="modelValue && !indeterminate" class="n-checkbox-check">
21
+ <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" focusable="false"><path d="M5 12l5 5L20 7"/></svg>
22
+ </div>
23
+ <div v-if="indeterminate" class="n-checkbox-check">
24
+ <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" focusable="false"><line x1="5" y1="12" x2="19" y2="12"/></svg>
25
+ </div>
24
26
  </div>
25
27
  <span v-if="label" class="n-checkbox-label">{{ label }}</span>
26
28
  </label>
@@ -30,62 +32,73 @@ const toggle = () => {
30
32
  .n-checkbox {
31
33
  display: inline-flex;
32
34
  align-items: center;
33
- gap: var(--n-space-3);
35
+ gap: 0.75rem;
34
36
  cursor: pointer;
35
37
  user-select: none;
38
+ padding: 0.375rem 0.5rem;
39
+ border-radius: 6px;
40
+ transition: background 0.15s;
41
+ }
42
+
43
+ .n-checkbox:hover:not(.is-disabled) {
44
+ background: rgba(99, 102, 241, 0.08);
36
45
  }
37
46
 
38
47
  .n-checkbox-box {
39
48
  width: 20px;
40
49
  height: 20px;
41
- border: 2px solid var(--n-color-border);
42
- border-radius: var(--n-radius-sm);
50
+ border-radius: 6px;
51
+ border: 2px solid #475569;
43
52
  display: flex;
44
53
  align-items: center;
45
54
  justify-content: center;
46
- transition: all var(--n-transition-fast);
55
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
56
+ background: #0f172a;
47
57
  flex-shrink: 0;
48
- background: transparent;
49
- }
50
-
51
- .is-checked .n-checkbox-box {
52
- background: var(--n-color-primary);
53
- border-color: var(--n-color-primary);
54
58
  }
55
59
 
60
+ .is-checked .n-checkbox-box,
56
61
  .is-indeterminate .n-checkbox-box {
57
- background: var(--n-color-primary);
58
- border-color: var(--n-color-primary);
62
+ background: #6366f1;
63
+ border-color: #6366f1;
64
+ box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.2), 0 4px 12px rgba(99, 102, 241, 0.4);
59
65
  }
60
66
 
61
- .n-checkbox-icon {
62
- color: white;
63
- font-size: 12px;
64
- font-weight: var(--n-weight-bold);
65
- line-height: 1;
66
- opacity: 0;
67
- transform: scale(0);
68
- transition: all var(--n-transition-fast);
67
+ .n-checkbox-check {
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ animation: n-check 0.25s cubic-bezier(0.4, 0, 0.2, 1);
69
72
  }
70
73
 
71
- .is-checked .n-checkbox-icon,
72
- .is-indeterminate .n-checkbox-icon {
73
- opacity: 1;
74
- transform: scale(1);
74
+ @keyframes n-check {
75
+ 0% { transform: scale(0); opacity: 0; }
76
+ 50% { transform: scale(1.2); }
77
+ 100% { transform: scale(1); opacity: 1; }
75
78
  }
76
79
 
77
80
  .n-checkbox-label {
78
- font-size: var(--n-text-sm);
79
- color: var(--n-color-text);
80
- font-weight: var(--n-weight-medium);
81
+ font-size: 0.875rem;
82
+ color: #e2e8f0;
83
+ font-weight: 500;
84
+ line-height: 1.5;
81
85
  }
82
86
 
83
87
  .is-disabled {
84
- opacity: 0.5;
88
+ opacity: 0.4;
85
89
  cursor: not-allowed;
86
90
  }
87
91
 
92
+ .is-disabled .n-checkbox-box {
93
+ background: #1e293b;
94
+ border-color: #334155;
95
+ }
96
+
88
97
  .n-checkbox:hover:not(.is-disabled) .n-checkbox-box {
89
- border-color: var(--n-color-primary);
98
+ border-color: #6366f1;
99
+ }
100
+
101
+ .is-checked .n-checkbox-box:active {
102
+ transform: scale(0.9);
90
103
  }
91
104
  </style>
@@ -176,7 +176,7 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
176
176
  <tr class="n-dt-head-row">
177
177
  <th v-if="selectionMode" class="n-dt-th is-selection">
178
178
  <button v-if="selectionMode === 'multiple'" type="button" class="n-dt-selectbox" :class="{ 'is-checked': allVisibleSelected.value }" @click.stop="toggleAllVisible" :aria-label="allVisibleSelected.value ? 'Deselect all' : 'Select all'">
179
- <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
179
+ <svg v-if="allVisibleSelected.value" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
180
180
  </button>
181
181
  </th>
182
182
  <th v-for="col in normalizeColumns.value" :key="col.field" class="n-dt-th" :class="[`is-${col.align}`, col.sortable ? 'is-sortable' : '']" :style="{ width: getWidth(col) || undefined, minWidth: col.minWidth }" :data-field="col.field" @click="onSortClick">
@@ -201,7 +201,7 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
201
201
  <tr v-for="(row, i) in visibleRows.value" :key="getRowKey(row, i + internalFirst.value)" class="n-dt-row" :class="{ 'is-selected': isRowSelected(row, i + internalFirst.value) }" @click="toggleRowSelection(row, i + internalFirst.value)">
202
202
  <td v-if="selectionMode" class="n-dt-td is-selection">
203
203
  <button v-if="selectionMode === 'multiple'" type="button" class="n-dt-selectbox" :class="{ 'is-checked': isRowSelected(row, i + internalFirst.value) }" @click.stop="toggleRowSelection(row, i + internalFirst.value)" :aria-label="isRowSelected(row, i + internalFirst.value) ? 'Deselect row' : 'Select row'">
204
- <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
204
+ <svg v-if="isRowSelected(row, i + internalFirst.value)" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
205
205
  </button>
206
206
  </td>
207
207
  <td v-for="col in normalizeColumns.value" :key="col.field" class="n-dt-td" :class="`is-${col.align}`" :style="{ width: getWidth(col) || undefined, minWidth: col.minWidth }">
@@ -212,7 +212,9 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
212
212
  </tbody>
213
213
  </table>
214
214
  </div>
215
- <NPaginator v-if="paginator" :first="internalFirst.value" :rows="internalRows.value" :totalRecords="totalRecords.value" :rowsPerPageOptions="rowsPerPageOptions" @page="onPage" />
215
+ <div v-if="paginator" class="n-dt-paginator-wrap">
216
+ <NPaginator :first="internalFirst.value" :rows="internalRows.value" :totalRecords="totalRecords.value" :rowsPerPageOptions="rowsPerPageOptions" @page="onPage" />
217
+ </div>
216
218
  </div>
217
219
  </template>
218
220
 
@@ -270,6 +272,7 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
270
272
  .n-dt-wrapper {
271
273
  width: 100%;
272
274
  overflow: auto;
275
+ border-radius: inherit;
273
276
  }
274
277
 
275
278
  .n-dt-table {
@@ -279,7 +282,7 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
279
282
  }
280
283
 
281
284
  .n-dt-thead {
282
- background: var(--n-color-surface);
285
+ background: linear-gradient(180deg, var(--n-color-surface-alt, var(--n-color-surface)) 0%, var(--n-color-surface) 100%);
283
286
  }
284
287
 
285
288
  .n-dt-th {
@@ -335,6 +338,9 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
335
338
  overflow: hidden;
336
339
  text-overflow: ellipsis;
337
340
  white-space: nowrap;
341
+ letter-spacing: 0.02em;
342
+ text-transform: uppercase;
343
+ font-size: 0.6875rem;
338
344
  }
339
345
 
340
346
  .n-dt-sort {
@@ -408,11 +414,11 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
408
414
  }
409
415
 
410
416
  .n-dt-tbody .n-dt-row {
411
- transition: background 0.15s ease;
417
+ transition: background 0.2s cubic-bezier(0.16, 1, 0.3, 1);
412
418
  }
413
419
 
414
420
  .n-dt-tbody .n-dt-row.is-hover:hover {
415
- background: var(--n-color-glass);
421
+ background: color-mix(in srgb, var(--n-color-primary) 6%, var(--n-color-surface));
416
422
  }
417
423
 
418
424
  .n-dt-tbody .n-dt-row.is-selected {
@@ -420,13 +426,21 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
420
426
  outline: none;
421
427
  }
422
428
 
429
+ .n-dt-tbody .n-dt-row.is-selected td:first-child {
430
+ box-shadow: inset 3px 0 0 0 var(--n-color-primary);
431
+ }
432
+
423
433
  .n-dt-tbody .n-dt-row.is-hover.is-selected:hover {
424
434
  background: var(--n-color-primary-light);
425
435
  filter: brightness(0.96);
426
436
  }
427
437
 
428
438
  .n-dt-table.is-striped .n-dt-tbody .n-dt-row:nth-child(even) {
429
- background: var(--n-color-glass);
439
+ background: color-mix(in srgb, var(--n-color-glass) 50%, var(--n-color-surface));
440
+ }
441
+
442
+ .n-dt-table.is-striped .n-dt-tbody .n-dt-row:nth-child(even).is-hover:hover {
443
+ background: color-mix(in srgb, var(--n-color-primary) 6%, var(--n-color-surface));
430
444
  }
431
445
 
432
446
  .n-dt-table.is-striped .n-dt-tbody .n-dt-row:nth-child(even).is-selected {
@@ -459,14 +473,14 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
459
473
  width: 20px;
460
474
  height: 20px;
461
475
  border: 2px solid var(--n-color-border);
462
- border-radius: var(--n-radius-sm);
476
+ border-radius: 5px;
463
477
  background: transparent;
464
478
  cursor: pointer;
465
479
  display: inline-flex;
466
480
  align-items: center;
467
481
  justify-content: center;
468
482
  padding: 0;
469
- transition: all 0.15s ease;
483
+ transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
470
484
  color: transparent;
471
485
  }
472
486
 
@@ -480,14 +494,14 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
480
494
  border-color: var(--n-color-primary);
481
495
  }
482
496
 
483
- .n-dt-selectbox svg {
484
- display: block;
485
- opacity: 0;
486
- transition: opacity 0.1s ease;
497
+ .n-dt-selectbox.is-checked svg {
498
+ animation: n-dt-check-pop 0.25s cubic-bezier(0.16, 1, 0.3, 1);
487
499
  }
488
500
 
489
- .n-dt-selectbox.is-checked svg {
490
- opacity: 1;
501
+ @keyframes n-dt-check-pop {
502
+ 0% { transform: scale(0); }
503
+ 50% { transform: scale(1.15); }
504
+ 100% { transform: scale(1); }
491
505
  }
492
506
 
493
507
  .n-dt-empty-row .n-dt-empty {
@@ -508,4 +522,14 @@ const startResize = (e) => { if (!props.resizableColumns) return; const field =
508
522
  padding: 0.85rem 1rem;
509
523
  font-size: var(--n-text-base);
510
524
  }
525
+
526
+ .n-dt-paginator-wrap {
527
+ border-top: 1px solid var(--n-color-border);
528
+ background: var(--n-color-surface-alt, var(--n-color-surface));
529
+ }
530
+
531
+ .n-dt-paginator-wrap :deep(.n-paginator) {
532
+ border-top: none;
533
+ background: transparent;
534
+ }
511
535
  </style>
@@ -166,9 +166,10 @@ const togglePassword = () => {
166
166
 
167
167
  .n-input-label {
168
168
  font-size: var(--n-text-sm);
169
- font-weight: var(--n-weight-semibold);
169
+ font-weight: var(--n-weight-medium);
170
170
  color: var(--n-color-text-secondary);
171
171
  margin-left: var(--n-space-1);
172
+ letter-spacing: 0.01em;
172
173
  }
173
174
 
174
175
  .n-input-wrapper {
@@ -186,14 +187,17 @@ const togglePassword = () => {
186
187
  background: var(--n-color-bg);
187
188
  border: 1px solid var(--n-color-border);
188
189
  color: var(--n-color-text);
189
- padding: 0.75rem 1rem;
190
+ padding: 0.75rem 1.125rem;
190
191
  border-radius: var(--n-radius-md);
191
192
  font-family: inherit;
192
193
  font-size: var(--n-text-base);
193
194
  line-height: 1.2;
194
195
  box-sizing: border-box;
195
- transition: all var(--n-transition-normal);
196
+ transition: all var(--n-transition-normal) cubic-bezier(0.16, 1, 0.3, 1);
196
197
  outline: none;
198
+ caret-color: var(--n-color-primary);
199
+ -webkit-font-smoothing: antialiased;
200
+ -moz-osx-font-smoothing: grayscale;
197
201
  }
198
202
 
199
203
  .n-input.has-prefix {
@@ -215,17 +219,21 @@ const togglePassword = () => {
215
219
  background: linear-gradient(135deg, var(--n-color-primary), var(--n-color-info));
216
220
  opacity: 0;
217
221
  pointer-events: none;
218
- transition: opacity var(--n-transition-normal);
222
+ transition: opacity var(--n-transition-normal) cubic-bezier(0.16, 1, 0.3, 1);
219
223
  z-index: 0;
220
224
  }
221
225
 
222
226
  .is-focused .n-input-focus-ring {
223
- opacity: 0.35;
227
+ opacity: 0.15;
224
228
  }
225
229
 
226
230
  .is-focused .n-input {
227
231
  border-color: var(--n-color-primary);
228
232
  background: var(--n-color-surface);
233
+ box-shadow:
234
+ 0 0 0 3px var(--n-color-primary-light),
235
+ 0 0 0 1px var(--n-color-primary),
236
+ inset 0 1px 3px rgba(0,0,0,0.04);
229
237
  }
230
238
 
231
239
  .has-error .n-input {
@@ -304,8 +312,21 @@ const togglePassword = () => {
304
312
  margin-left: auto;
305
313
  }
306
314
 
315
+ .is-disabled {
316
+ position: relative;
317
+ }
318
+
319
+ .is-disabled::after {
320
+ content: '';
321
+ position: absolute;
322
+ inset: 0;
323
+ background: var(--n-color-glass);
324
+ border-radius: var(--n-radius-md);
325
+ pointer-events: none;
326
+ z-index: 2;
327
+ }
328
+
307
329
  .is-disabled .n-input {
308
- opacity: 0.5;
309
330
  cursor: not-allowed;
310
331
  background: var(--n-color-surface-alt);
311
332
  }
@@ -139,7 +139,7 @@ onUnmounted(() => {
139
139
  background: var(--n-color-overlay);
140
140
  backdrop-filter: blur(8px);
141
141
  opacity: 0;
142
- transition: opacity 0.25s ease;
142
+ transition: opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1);
143
143
  }
144
144
 
145
145
  .n-modal-overlay.is-active {
@@ -150,12 +150,14 @@ onUnmounted(() => {
150
150
  position: relative;
151
151
  width: 90%;
152
152
  background: var(--n-color-surface);
153
- border: 1px solid var(--n-color-border);
153
+ backdrop-filter: blur(20px);
154
+ -webkit-backdrop-filter: blur(20px);
155
+ border: 1px solid var(--n-color-glass-border);
154
156
  border-radius: var(--n-radius-2xl);
155
- box-shadow: var(--n-shadow-xl);
157
+ box-shadow: var(--n-shadow-xl), var(--n-shadow-glow-primary), 0 0 0 1px var(--n-color-glass-border);
156
158
  transform: scale(0.9) translateY(20px);
157
159
  opacity: 0;
158
- transition: all var(--n-transition-spring);
160
+ transition: opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1), transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
159
161
  overflow: hidden;
160
162
  outline: none;
161
163
  max-height: 85vh;
@@ -190,20 +192,31 @@ onUnmounted(() => {
190
192
  color: var(--n-color-text-secondary);
191
193
  font-size: 1.75rem;
192
194
  cursor: pointer;
193
- transition: color var(--n-transition-fast);
195
+ transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
194
196
  padding: 0;
195
197
  line-height: 1;
196
- width: 36px;
197
- height: 36px;
198
+ width: 44px;
199
+ height: 44px;
198
200
  display: flex;
199
201
  align-items: center;
200
202
  justify-content: center;
201
- border-radius: var(--n-radius-sm);
203
+ border-radius: var(--n-radius-lg);
204
+ flex-shrink: 0;
202
205
  }
203
206
 
204
207
  .n-modal-close:hover {
205
208
  color: var(--n-color-text);
206
- background: var(--n-color-glass);
209
+ background: var(--n-color-glass-hover);
210
+ transform: scale(1.1);
211
+ }
212
+
213
+ .n-modal-close:active {
214
+ transform: scale(0.95);
215
+ }
216
+
217
+ .n-modal-close:focus-visible {
218
+ outline: 2px solid var(--n-color-primary);
219
+ outline-offset: 2px;
207
220
  }
208
221
 
209
222
  .n-modal-content {
@@ -73,5 +73,5 @@ onBeforeUnmount(() => close())
73
73
  </template>
74
74
 
75
75
  <style scoped>
76
- .n-ms{position:relative;width:100%;font-family:var(--n-font-sans)}.n-ms-label{display:block;font-size:var(--n-text-sm);font-weight:var(--n-weight-medium);color:var(--n-color-text-secondary);margin-bottom:var(--n-space-2)}.n-ms-trigger{background:var(--n-color-surface);border:1px solid var(--n-color-border);border-radius:var(--n-radius-md);padding:0.5rem 0.75rem;display:flex;justify-content:space-between;align-items:center;cursor:pointer;transition:all var(--n-transition-fast);color:var(--n-color-text);gap:var(--n-space-2);min-height:44px}.n-ms-trigger:focus-visible{border-color:var(--n-color-primary);box-shadow:0 0 0 3px var(--n-color-primary-light)}.n-ms.is-open .n-ms-trigger{border-color:var(--n-color-primary);box-shadow:0 0 0 3px var(--n-color-primary-light)}.n-ms-placeholder{color:var(--n-color-text-muted)}.n-ms-actions{display:flex;align-items:center;gap:0.25rem;flex-shrink:0}.n-ms-clear{background:transparent;border:none;color:var(--n-color-text-muted);cursor:pointer;padding:0.15rem;font-size:var(--n-text-xs);border-radius:var(--n-radius-sm);line-height:1}.n-ms-clear:hover{color:var(--n-color-text)}.n-ms-arrow{color:var(--n-color-text-muted);transition:transform var(--n-transition-fast);font-size:var(--n-text-xs)}.is-open .n-ms-arrow{transform:rotate(180deg)}.n-ms-chips{display:flex;flex-wrap:wrap;gap:var(--n-space-2);align-items:center;min-width:0}.n-ms-chip{display:inline-flex;align-items:center;gap:0.35rem;padding:0.2rem 0.45rem;border-radius:999px;background:var(--n-color-glass);border:1px solid var(--n-color-border);font-size:var(--n-text-xs);line-height:1;max-width:12rem}.n-ms-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:10rem}.n-ms-chip-remove{background:transparent;border:none;color:var(--n-color-text-muted);cursor:pointer;padding:0;line-height:1;display:flex;align-items:center}.n-ms-chip-remove:hover:not(:disabled){color:var(--n-color-text)}.n-ms-chip-remove:disabled{opacity:0.5;cursor:not-allowed}.n-ms-more{font-size:var(--n-text-xs);color:var(--n-color-text-muted)}.n-ms-dropdown{position:absolute;top:calc(100% + 0.5rem);left:0;width:100%;background:var(--n-color-surface);border:1px solid var(--n-color-border);border-radius:var(--n-radius-md);box-shadow:var(--n-shadow-lg);z-index:var(--n-z-dropdown);overflow:hidden;animation:n-ms-in .2s cubic-bezier(0,1,0,1)}@keyframes n-ms-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.n-ms-dropdown.is-top{animation:n-ms-in-top .2s cubic-bezier(0,1,0,1)}@keyframes n-ms-in-top{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.n-ms-search{padding:var(--n-space-2);border-bottom:1px solid var(--n-color-border)}.n-ms-search-input{width:100%;background:var(--n-color-bg);border:1px solid var(--n-color-border);border-radius:var(--n-radius-sm);padding:var(--n-space-2) var(--n-space-3);color:var(--n-color-text);font-size:var(--n-text-sm);outline:none;font-family:inherit}.n-ms-search-input:focus{border-color:var(--n-color-primary)}.n-ms-options{max-height:260px;overflow-y:auto}.n-ms-option{width:100%;display:flex;align-items:center;gap:0.5rem;padding:0.7rem 1rem;background:transparent;border:none;color:var(--n-color-text-secondary);cursor:pointer;transition:all var(--n-transition-fast);text-align:left}.n-ms-option:hover:not(:disabled),.n-ms-option.is-focused{background:var(--n-color-glass);color:var(--n-color-text)}.n-ms-option.is-selected{background:var(--n-color-primary-light);color:var(--n-color-primary);font-weight:var(--n-weight-semibold)}.n-ms-option:disabled,.n-ms-option.is-disabled{opacity:0.4;cursor:not-allowed}.n-ms-check{width:1.25rem;display:inline-flex;align-items:center;justify-content:center;font-size:var(--n-text-xs)}.n-ms-empty{padding:var(--n-space-4);color:var(--n-color-text-muted);text-align:center;font-size:var(--n-text-sm)}.is-disabled .n-ms-trigger{opacity:0.5;cursor:not-allowed}
76
+ .n-ms{position:relative;width:100%;font-family:var(--n-font-sans)}.n-ms-label{display:block;font-size:var(--n-text-sm);font-weight:var(--n-weight-medium);color:var(--n-color-text-secondary);margin-bottom:var(--n-space-2)}.n-ms-trigger{background:var(--n-color-surface);border:1px solid var(--n-color-border);border-radius:var(--n-radius-md);padding:0.5rem 0.75rem;display:flex;justify-content:space-between;align-items:center;cursor:pointer;transition:all var(--n-transition-fast);color:var(--n-color-text);gap:var(--n-space-2);min-height:44px}.n-ms-trigger:focus-visible{border-color:var(--n-color-primary);box-shadow:0 0 0 3px var(--n-color-primary-light),0 0 16px rgba(99,102,241,.25)}.n-ms.is-open .n-ms-trigger{border-color:var(--n-color-primary);box-shadow:0 0 0 3px var(--n-color-primary-light)}.n-ms-placeholder{color:var(--n-color-text-muted)}.n-ms-actions{display:flex;align-items:center;gap:0.25rem;flex-shrink:0}.n-ms-clear{background:transparent;border:none;color:var(--n-color-text-muted);cursor:pointer;padding:0.15rem;font-size:var(--n-text-xs);border-radius:var(--n-radius-sm);line-height:1}.n-ms-clear:hover{color:var(--n-color-text)}.n-ms-arrow{color:var(--n-color-text-muted);transition:transform var(--n-transition-fast);font-size:var(--n-text-xs)}.is-open .n-ms-arrow{transform:rotate(180deg)}.n-ms-chips{display:flex;flex-wrap:wrap;gap:var(--n-space-2);align-items:center;min-width:0}.n-ms-chip{display:inline-flex;align-items:center;gap:0.35rem;padding:0.25rem 0.5rem;border-radius:999px;background:var(--n-color-glass);border:1px solid var(--n-color-border);font-size:var(--n-text-xs);line-height:1;max-width:12rem;transition:all .2s cubic-bezier(0.16,1,0.3,1)}.n-ms-chip:hover{background:var(--n-color-surface-hover)}.n-ms-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:10rem}.n-ms-chip-remove{background:transparent;border:none;color:var(--n-color-text-muted);cursor:pointer;padding:0;line-height:1;display:flex;align-items:center}.n-ms-chip-remove:hover:not(:disabled){color:var(--n-color-text)}.n-ms-chip-remove:disabled{opacity:0.5;cursor:not-allowed}.n-ms-more{font-size:var(--n-text-xs);color:var(--n-color-text-muted)}.n-ms-dropdown{position:absolute;top:calc(100% + 0.5rem);left:0;width:100%;background:var(--n-color-glass);border:1px solid var(--n-color-border);border-radius:var(--n-radius-md);box-shadow:var(--n-shadow-lg),0 8px 32px rgba(0,0,0,.08);z-index:var(--n-z-dropdown);overflow:hidden;animation:n-ms-in .2s cubic-bezier(0.16,1,0.3,1);backdrop-filter:blur(16px)}@keyframes n-ms-in{from{opacity:0;transform:translateY(-8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.n-ms-dropdown.is-top{animation:n-ms-in-top .2s cubic-bezier(0.16,1,0.3,1)}@keyframes n-ms-in-top{from{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.n-ms-search{padding:var(--n-space-2);border-bottom:1px solid var(--n-color-border)}.n-ms-search-input{width:100%;background:var(--n-color-bg);border:1px solid var(--n-color-border);border-radius:var(--n-radius-sm);padding:var(--n-space-2) var(--n-space-3);color:var(--n-color-text);font-size:var(--n-text-sm);outline:none;font-family:inherit}.n-ms-search-input:focus{border-color:var(--n-color-primary);box-shadow:0 0 0 3px var(--n-color-primary-light)}.n-ms-options{max-height:260px;overflow-y:auto}.n-ms-option{width:100%;display:flex;align-items:center;gap:0.5rem;padding:0.7rem 1rem;background:transparent;border:none;color:var(--n-color-text-secondary);cursor:pointer;transition:all .15s cubic-bezier(0.16,1,0.3,1);text-align:left;position:relative}.n-ms-option::before{content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:0;border-radius:0 3px 3px 0;background:var(--n-color-primary);transition:height .2s cubic-bezier(0.16,1,0.3,1)}.n-ms-option:hover:not(:disabled),.n-ms-option.is-focused{background:var(--n-color-glass);color:var(--n-color-text)}.n-ms-option:hover::before,.n-ms-option.is-focused::before{height:60%}.n-ms-option.is-selected{background:var(--n-color-primary-light);color:var(--n-color-primary);font-weight:var(--n-weight-semibold)}.n-ms-option:disabled,.n-ms-option.is-disabled{opacity:0.4;cursor:not-allowed}.n-ms-check{width:1.25rem;display:inline-flex;align-items:center;justify-content:center;font-size:var(--n-text-xs)}.n-ms-empty{padding:var(--n-space-4);color:var(--n-color-text-muted);text-align:center;font-size:var(--n-text-sm)}.is-disabled .n-ms-trigger{opacity:0.5;cursor:not-allowed}
77
77
  </style>