nexa-ui-kit 0.11.3 → 0.11.5

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 +57 -14
  10. package/dist/components/NButton.nexa +57 -14
  11. package/dist/components/NCard.js +6 -5
  12. package/dist/components/NCard.nexa +6 -5
  13. package/dist/components/NCheckbox.js +42 -33
  14. package/dist/components/NCheckbox.nexa +22 -15
  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 +79 -38
  42. package/dist/components/NTreeMenu.nexa +58 -17
  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 +57 -14
  51. package/src/components/NCard.nexa +6 -5
  52. package/src/components/NCheckbox.nexa +22 -15
  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 +58 -17
  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,6 +98,11 @@ 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
108
  background: linear-gradient(135deg, var(--n-color-primary) 0%, var(--n-color-primary-hover) 100%);
@@ -106,7 +114,7 @@ const btnClass = computed(() => {
106
114
  box-shadow: 0 8px 20px -3px var(--n-color-primary-glow);
107
115
  }
108
116
  .n-btn-primary:active:not(:disabled) {
109
- transform: translateY(0) scale(0.97);
117
+ box-shadow: var(--n-shadow-glow-primary), inset 0 1px 3px rgba(0,0,0,0.15);
110
118
  }
111
119
 
112
120
  /* Variant: Secondary */
@@ -118,6 +126,10 @@ const btnClass = computed(() => {
118
126
  .n-btn-secondary:hover:not(:disabled) {
119
127
  background: var(--n-color-surface-hover);
120
128
  border-color: var(--n-color-border-hover);
129
+ transform: translateY(-1px);
130
+ }
131
+ .n-btn-secondary:active:not(:disabled) {
132
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.08);
121
133
  }
122
134
 
123
135
  /* Variant: Success */
@@ -131,7 +143,7 @@ const btnClass = computed(() => {
131
143
  box-shadow: var(--n-shadow-glow-success);
132
144
  }
133
145
  .n-btn-success:active:not(:disabled) {
134
- transform: translateY(0) scale(0.97);
146
+ box-shadow: var(--n-shadow-glow-success), inset 0 1px 3px rgba(0,0,0,0.15);
135
147
  }
136
148
 
137
149
  /* Variant: Warning */
@@ -145,7 +157,7 @@ const btnClass = computed(() => {
145
157
  box-shadow: var(--n-shadow-glow-warning);
146
158
  }
147
159
  .n-btn-warning:active:not(:disabled) {
148
- transform: translateY(0) scale(0.97);
160
+ box-shadow: var(--n-shadow-glow-warning), inset 0 1px 3px rgba(0,0,0,0.15);
149
161
  }
150
162
 
151
163
  /* Variant: Info */
@@ -159,7 +171,7 @@ const btnClass = computed(() => {
159
171
  box-shadow: var(--n-shadow-glow-info);
160
172
  }
161
173
  .n-btn-info:active:not(:disabled) {
162
- transform: translateY(0) scale(0.97);
174
+ box-shadow: var(--n-shadow-glow-info), inset 0 1px 3px rgba(0,0,0,0.15);
163
175
  }
164
176
 
165
177
  /* Variant: Danger */
@@ -173,28 +185,46 @@ const btnClass = computed(() => {
173
185
  box-shadow: var(--n-shadow-glow-danger);
174
186
  }
175
187
  .n-btn-danger:active:not(:disabled) {
176
- transform: translateY(0) scale(0.97);
188
+ box-shadow: var(--n-shadow-glow-danger), inset 0 1px 3px rgba(0,0,0,0.15);
177
189
  }
178
190
 
179
191
  /* Variant: Ghost */
180
192
  .n-btn-ghost {
181
193
  background: transparent;
194
+ backdrop-filter: blur(12px);
195
+ -webkit-backdrop-filter: blur(12px);
182
196
  color: var(--n-color-text-secondary);
197
+ border-color: transparent;
183
198
  }
184
199
  .n-btn-ghost:hover:not(:disabled) {
185
200
  background: var(--n-color-glass);
201
+ backdrop-filter: blur(12px);
202
+ -webkit-backdrop-filter: blur(12px);
186
203
  color: var(--n-color-text);
204
+ border-color: var(--n-color-glass-border);
205
+ }
206
+ .n-btn-ghost:active:not(:disabled) {
207
+ background: var(--n-color-glass-hover);
208
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.06);
187
209
  }
188
210
 
189
211
  /* Variant: Outline */
190
212
  .n-btn-outline {
191
213
  background: transparent;
192
214
  color: var(--n-color-primary);
193
- border-color: var(--n-color-primary);
215
+ border: 1.5px solid transparent;
216
+ background-image: linear-gradient(transparent, transparent), linear-gradient(135deg, var(--n-color-primary), var(--n-color-primary-hover));
217
+ background-origin: padding-box, border-box;
218
+ background-clip: padding-box, border-box;
194
219
  }
195
220
  .n-btn-outline:hover:not(:disabled) {
196
- background: var(--n-color-primary-light);
197
- border-color: var(--n-color-primary-hover);
221
+ 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));
222
+ background-origin: padding-box, border-box;
223
+ background-clip: padding-box, border-box;
224
+ color: var(--n-color-primary-hover);
225
+ }
226
+ .n-btn-outline:active:not(:disabled) {
227
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.08);
198
228
  }
199
229
 
200
230
  /* Variant: Glass */
@@ -208,13 +238,26 @@ const btnClass = computed(() => {
208
238
  background: var(--n-color-glass-hover);
209
239
  border-color: var(--n-color-border-hover);
210
240
  }
241
+ .n-btn-glass:active:not(:disabled) {
242
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.08);
243
+ }
211
244
 
212
245
  /* Disabled */
213
246
  .n-btn:disabled {
214
- opacity: 0.45;
215
247
  cursor: not-allowed;
216
248
  transform: none !important;
217
249
  box-shadow: none !important;
250
+ pointer-events: none;
251
+ opacity: 0.55;
252
+ }
253
+ .n-btn:disabled::after {
254
+ content: '';
255
+ position: absolute;
256
+ inset: 0;
257
+ border-radius: inherit;
258
+ background: var(--n-color-surface, #fff);
259
+ opacity: 0.3;
260
+ pointer-events: none;
218
261
  }
219
262
 
220
263
  /* 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,9 +17,11 @@ 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>
20
+ <span v-if="modelValue && !indeterminate" class="n-checkbox-icon">
21
+ <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>
22
+ </span>
23
+ <span v-if="indeterminate" class="n-checkbox-icon">
24
+ <svg 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>
23
25
  </span>
24
26
  </div>
25
27
  <span v-if="label" class="n-checkbox-label">{{ label }}</span>
@@ -36,14 +38,14 @@ const toggle = () => {
36
38
  }
37
39
 
38
40
  .n-checkbox-box {
39
- width: 20px;
40
- height: 20px;
41
+ width: 22px;
42
+ height: 22px;
41
43
  border: 2px solid var(--n-color-border);
42
44
  border-radius: var(--n-radius-sm);
43
45
  display: flex;
44
46
  align-items: center;
45
47
  justify-content: center;
46
- transition: all var(--n-transition-fast);
48
+ transition: all var(--n-transition-normal);
47
49
  flex-shrink: 0;
48
50
  background: transparent;
49
51
  }
@@ -51,27 +53,32 @@ const toggle = () => {
51
53
  .is-checked .n-checkbox-box {
52
54
  background: var(--n-color-primary);
53
55
  border-color: var(--n-color-primary);
56
+ box-shadow: var(--n-shadow-glow-primary);
54
57
  }
55
58
 
56
59
  .is-indeterminate .n-checkbox-box {
57
60
  background: var(--n-color-primary);
58
61
  border-color: var(--n-color-primary);
62
+ box-shadow: var(--n-shadow-glow-primary);
59
63
  }
60
64
 
61
65
  .n-checkbox-icon {
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
62
69
  color: white;
63
- font-size: 12px;
64
- font-weight: var(--n-weight-bold);
65
70
  line-height: 1;
66
- opacity: 0;
67
- transform: scale(0);
68
- transition: all var(--n-transition-fast);
71
+ animation: n-checkbox-pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
72
+ }
73
+
74
+ .n-checkbox-icon svg {
75
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2));
69
76
  }
70
77
 
71
- .is-checked .n-checkbox-icon,
72
- .is-indeterminate .n-checkbox-icon {
73
- opacity: 1;
74
- transform: scale(1);
78
+ @keyframes n-checkbox-pop {
79
+ 0% { transform: scale(0); opacity: 0; }
80
+ 50% { transform: scale(1.15); }
81
+ 100% { transform: scale(1); opacity: 1; }
75
82
  }
76
83
 
77
84
  .n-checkbox-label {
@@ -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>
@@ -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>