nexa-ui-kit 0.6.0

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 (114) hide show
  1. package/dist/NBadge.nexa +40 -0
  2. package/dist/NBottomSheet.nexa +124 -0
  3. package/dist/NButton.nexa +123 -0
  4. package/dist/NCard.nexa +74 -0
  5. package/dist/NInput.nexa +116 -0
  6. package/dist/NModal.nexa +165 -0
  7. package/dist/NSelect.nexa +169 -0
  8. package/dist/NToastContainer.nexa +86 -0
  9. package/dist/NTooltip.nexa +115 -0
  10. package/dist/components/NAlert.js +134 -0
  11. package/dist/components/NAlert.nexa +115 -0
  12. package/dist/components/NAutocomplete.js +94 -0
  13. package/dist/components/NAutocomplete.nexa +58 -0
  14. package/dist/components/NAvatar.js +75 -0
  15. package/dist/components/NAvatar.nexa +67 -0
  16. package/dist/components/NBadge.js +74 -0
  17. package/dist/components/NBadge.nexa +61 -0
  18. package/dist/components/NBottomSheet.js +149 -0
  19. package/dist/components/NBottomSheet.nexa +145 -0
  20. package/dist/components/NButton.js +284 -0
  21. package/dist/components/NButton.nexa +275 -0
  22. package/dist/components/NCard.js +117 -0
  23. package/dist/components/NCard.nexa +100 -0
  24. package/dist/components/NCheckbox.js +108 -0
  25. package/dist/components/NCheckbox.nexa +90 -0
  26. package/dist/components/NChips.js +72 -0
  27. package/dist/components/NChips.nexa +57 -0
  28. package/dist/components/NDataTable.js +252 -0
  29. package/dist/components/NDataTable.nexa +186 -0
  30. package/dist/components/NDatepicker.js +379 -0
  31. package/dist/components/NDatepicker.nexa +367 -0
  32. package/dist/components/NForm.js +132 -0
  33. package/dist/components/NForm.nexa +133 -0
  34. package/dist/components/NFormField.js +173 -0
  35. package/dist/components/NFormField.nexa +171 -0
  36. package/dist/components/NInput.js +311 -0
  37. package/dist/components/NInput.nexa +311 -0
  38. package/dist/components/NInputNumber.js +202 -0
  39. package/dist/components/NInputNumber.nexa +199 -0
  40. package/dist/components/NModal.js +221 -0
  41. package/dist/components/NModal.nexa +221 -0
  42. package/dist/components/NMultiSelect.js +156 -0
  43. package/dist/components/NMultiSelect.nexa +77 -0
  44. package/dist/components/NPaginator.js +117 -0
  45. package/dist/components/NPaginator.nexa +77 -0
  46. package/dist/components/NPassword.js +193 -0
  47. package/dist/components/NPassword.nexa +178 -0
  48. package/dist/components/NProgressBar.js +127 -0
  49. package/dist/components/NProgressBar.nexa +111 -0
  50. package/dist/components/NRadio.js +96 -0
  51. package/dist/components/NRadio.nexa +81 -0
  52. package/dist/components/NSelect.js +468 -0
  53. package/dist/components/NSelect.nexa +452 -0
  54. package/dist/components/NSkeleton.js +98 -0
  55. package/dist/components/NSkeleton.nexa +74 -0
  56. package/dist/components/NSwitch.js +92 -0
  57. package/dist/components/NSwitch.nexa +76 -0
  58. package/dist/components/NTabs.js +129 -0
  59. package/dist/components/NTabs.nexa +113 -0
  60. package/dist/components/NTag.js +108 -0
  61. package/dist/components/NTag.nexa +93 -0
  62. package/dist/components/NToastContainer.js +242 -0
  63. package/dist/components/NToastContainer.nexa +221 -0
  64. package/dist/components/NTooltip.js +163 -0
  65. package/dist/components/NTooltip.nexa +166 -0
  66. package/dist/components/NTreeMenu.js +151 -0
  67. package/dist/components/NTreeMenu.nexa +142 -0
  68. package/dist/index.d.ts +32 -0
  69. package/dist/index.js +34 -0
  70. package/dist/services/FloatingOverlay.d.ts +27 -0
  71. package/dist/services/FloatingOverlay.js +98 -0
  72. package/dist/services/FormValidation.d.ts +8 -0
  73. package/dist/services/FormValidation.js +46 -0
  74. package/dist/services/ToastService.d.ts +16 -0
  75. package/dist/services/ToastService.js +26 -0
  76. package/dist/styles/theme.d.ts +1 -0
  77. package/dist/styles/theme.js +144 -0
  78. package/package.json +32 -0
  79. package/src/components/NAlert.nexa +115 -0
  80. package/src/components/NAutocomplete.nexa +58 -0
  81. package/src/components/NAvatar.nexa +67 -0
  82. package/src/components/NBadge.nexa +61 -0
  83. package/src/components/NBottomSheet.nexa +145 -0
  84. package/src/components/NButton.nexa +275 -0
  85. package/src/components/NCard.nexa +100 -0
  86. package/src/components/NCheckbox.nexa +90 -0
  87. package/src/components/NChips.nexa +57 -0
  88. package/src/components/NDataTable.nexa +186 -0
  89. package/src/components/NDatepicker.nexa +367 -0
  90. package/src/components/NForm.nexa +133 -0
  91. package/src/components/NFormField.nexa +171 -0
  92. package/src/components/NInput.nexa +311 -0
  93. package/src/components/NInputNumber.nexa +199 -0
  94. package/src/components/NModal.nexa +221 -0
  95. package/src/components/NMultiSelect.nexa +77 -0
  96. package/src/components/NPaginator.nexa +77 -0
  97. package/src/components/NPassword.nexa +178 -0
  98. package/src/components/NProgressBar.nexa +111 -0
  99. package/src/components/NRadio.nexa +81 -0
  100. package/src/components/NSelect.nexa +452 -0
  101. package/src/components/NSkeleton.nexa +74 -0
  102. package/src/components/NSwitch.nexa +76 -0
  103. package/src/components/NTabs.nexa +113 -0
  104. package/src/components/NTag.nexa +93 -0
  105. package/src/components/NToastContainer.nexa +221 -0
  106. package/src/components/NTooltip.nexa +166 -0
  107. package/src/components/NTreeMenu.nexa +142 -0
  108. package/src/index.ts +36 -0
  109. package/src/services/FloatingOverlay.ts +133 -0
  110. package/src/services/FormValidation.ts +44 -0
  111. package/src/services/ToastService.ts +41 -0
  112. package/src/shims.d.ts +5 -0
  113. package/src/styles/theme.ts +146 -0
  114. package/src/styles/tokens.css +170 -0
@@ -0,0 +1,96 @@
1
+ import { h, hText, effect, defineComponent, registerComponent, reloadComponent, injectStyle } from 'nexa-framework'
2
+
3
+ const _sfc_main = defineComponent({
4
+ __scopeId: 'data-v-5c3cc2',
5
+ __hmrId: 'NRadio_nexa',
6
+ props: {
7
+ modelValue: { type: [String, Number], default: '' },
8
+ value: { type: [String, Number], default: '' },
9
+ label: { type: String, default: '' },
10
+ disabled: { type: Boolean, default: false },
11
+ name: { type: String, default: '' }
12
+ },
13
+ emits: ['update:modelValue'],
14
+ setup(props, setupContext) {
15
+ const { emit, slots, slots: $slots } = setupContext
16
+ const isChecked = () => props.modelValue === props.value
17
+ const select = () => {
18
+ if (props.disabled) return
19
+ emit('update:modelValue', props.value)
20
+ }
21
+ return { isChecked, select, $slots, emit }
22
+ }
23
+ })
24
+ // Injected render function
25
+ _sfc_main.render = function(ctx) {
26
+ const { isChecked, select, $slots, emit, modelValue, value, label, disabled, name, Fragment: _ntc_Fragment } = ctx
27
+ return h('label', { class: ["n-radio", { 'is-checked': isChecked(), 'is-disabled': disabled }], "data-v-5c3cc2": "" }, [
28
+ "\n ",
29
+ h('div', { class: "n-radio-circle", onClick: select, "data-v-5c3cc2": "" }, [
30
+ "\n ",
31
+ h('div', { class: "n-radio-dot", "data-v-5c3cc2": "" }),
32
+ "\n "
33
+ ]),
34
+ "\n ",
35
+ (label) ? h('span', { class: "n-radio-label", "data-v-5c3cc2": "" }, [
36
+ label
37
+ ]) : null
38
+ ])
39
+ }
40
+ _sfc_main.__scopeId = 'data-v-5c3cc2'
41
+ _sfc_main.__hmrId = 'NRadio_nexa'
42
+
43
+ export default _sfc_main
44
+
45
+ const __style = `.n-radio[data-v-5c3cc2]{
46
+ display: inline-flex;
47
+ align-items: center;
48
+ gap: var(--n-space-3);
49
+ cursor: pointer;
50
+ user-select: none;
51
+ }
52
+
53
+ .n-radio-circle[data-v-5c3cc2]{
54
+ width: 20px;
55
+ height: 20px;
56
+ border: 2px solid var(--n-color-border);
57
+ border-radius: var(--n-radius-full);
58
+ display: flex;
59
+ align-items: center;
60
+ justify-content: center;
61
+ transition: all var(--n-transition-fast);
62
+ flex-shrink: 0;
63
+ }
64
+
65
+ .is-checked .n-radio-circle[data-v-5c3cc2]{
66
+ border-color: var(--n-color-primary);
67
+ }
68
+
69
+ .n-radio-dot[data-v-5c3cc2]{
70
+ width: 10px;
71
+ height: 10px;
72
+ border-radius: var(--n-radius-full);
73
+ background: var(--n-color-primary);
74
+ transform: scale(0);
75
+ transition: all var(--n-transition-spring);
76
+ }
77
+
78
+ .is-checked .n-radio-dot[data-v-5c3cc2]{
79
+ transform: scale(1);
80
+ }
81
+
82
+ .n-radio-label[data-v-5c3cc2]{
83
+ font-size: var(--n-text-sm);
84
+ color: var(--n-color-text);
85
+ font-weight: var(--n-weight-medium);
86
+ }
87
+
88
+ .is-disabled[data-v-5c3cc2]{
89
+ opacity: 0.5;
90
+ cursor: not-allowed;
91
+ }
92
+
93
+ .n-radio[data-v-5c3cc2]:hover:not(.is-disabled) .n-radio-circle{
94
+ border-color: var(--n-color-primary);
95
+ }`
96
+ injectStyle('data-v-5c3cc2', __style)
@@ -0,0 +1,81 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ modelValue: { type: [String, Number], default: '' },
4
+ value: { type: [String, Number], default: '' },
5
+ label: { type: String, default: '' },
6
+ disabled: { type: Boolean, default: false },
7
+ name: { type: String, default: '' }
8
+ })
9
+
10
+ const emit = defineEmits(['update:modelValue'])
11
+
12
+ const isChecked = () => props.modelValue === props.value
13
+
14
+ const select = () => {
15
+ if (props.disabled) return
16
+ emit('update:modelValue', props.value)
17
+ }
18
+ </script>
19
+
20
+ <template>
21
+ <label class="n-radio" :class="{ 'is-checked': isChecked(), 'is-disabled': disabled }">
22
+ <div class="n-radio-circle" @click="select">
23
+ <div class="n-radio-dot"></div>
24
+ </div>
25
+ <span v-if="label" class="n-radio-label">{{ label }}</span>
26
+ </label>
27
+ </template>
28
+
29
+ <style scoped>
30
+ .n-radio {
31
+ display: inline-flex;
32
+ align-items: center;
33
+ gap: var(--n-space-3);
34
+ cursor: pointer;
35
+ user-select: none;
36
+ }
37
+
38
+ .n-radio-circle {
39
+ width: 20px;
40
+ height: 20px;
41
+ border: 2px solid var(--n-color-border);
42
+ border-radius: var(--n-radius-full);
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ transition: all var(--n-transition-fast);
47
+ flex-shrink: 0;
48
+ }
49
+
50
+ .is-checked .n-radio-circle {
51
+ border-color: var(--n-color-primary);
52
+ }
53
+
54
+ .n-radio-dot {
55
+ width: 10px;
56
+ height: 10px;
57
+ border-radius: var(--n-radius-full);
58
+ background: var(--n-color-primary);
59
+ transform: scale(0);
60
+ transition: all var(--n-transition-spring);
61
+ }
62
+
63
+ .is-checked .n-radio-dot {
64
+ transform: scale(1);
65
+ }
66
+
67
+ .n-radio-label {
68
+ font-size: var(--n-text-sm);
69
+ color: var(--n-color-text);
70
+ font-weight: var(--n-weight-medium);
71
+ }
72
+
73
+ .is-disabled {
74
+ opacity: 0.5;
75
+ cursor: not-allowed;
76
+ }
77
+
78
+ .n-radio:hover:not(.is-disabled) .n-radio-circle {
79
+ border-color: var(--n-color-primary);
80
+ }
81
+ </style>
@@ -0,0 +1,468 @@
1
+ import { signal, computed, onBeforeUnmount, h, hText, effect, defineComponent, registerComponent, reloadComponent, injectStyle, Teleport } from 'nexa-framework'
2
+ import { trackFloatingOverlay } from '../services/FloatingOverlay.js'
3
+
4
+ const _sfc_main = defineComponent({
5
+ __scopeId: 'data-v-fef169b',
6
+ __hmrId: 'NSelect_nexa',
7
+ props: {
8
+ modelValue: { type: [String, Number], default: '' },
9
+ options: { type: Array, default: () => [] },
10
+ placeholder: { type: String, default: 'Select option...' },
11
+ label: { type: String, default: '' },
12
+ disabled: { type: Boolean, default: false },
13
+ searchable: { type: Boolean, default: false },
14
+ clearable: { type: Boolean, default: false },
15
+ placement: { type: String, default: 'auto' },
16
+ appendTo: { type: String, default: 'self' }
17
+ },
18
+ emits: ['update:modelValue', 'clear'],
19
+ setup(props, setupContext) {
20
+ const { emit, slots, slots: $slots } = setupContext
21
+ const isOpen = signal(false)
22
+ const query = signal('')
23
+ const focusedIndex = signal(-1)
24
+ const instanceId = `n-sel-${Math.random().toString(16).slice(2)}`
25
+ const popupStyle = signal({})
26
+ const resolvedPlacement = signal('bottom')
27
+ const rootEl = signal(null)
28
+ let stopTracking = null
29
+ let outsideHandler = null
30
+ const filteredOptions = computed(() => {
31
+ if (!props.searchable || !query.value) return props.options
32
+ const q = query.value.toLowerCase()
33
+ if (props.options[0] && 'group' in props.options[0]) {
34
+ return props.options
35
+ }
36
+ return props.options.filter(opt =>
37
+ String(opt.label).toLowerCase().includes(q)
38
+ )
39
+ })
40
+ const selectedOption = computed(() => {
41
+ return props.options.find(opt => opt.value === props.modelValue) || null
42
+ })
43
+ const close = () => {
44
+ if (!isOpen.value) return
45
+ isOpen.value = false
46
+ focusedIndex.value = -1
47
+ query.value = ''
48
+ if (stopTracking) {
49
+ stopTracking()
50
+ stopTracking = null
51
+ }
52
+ if (outsideHandler) {
53
+ document.removeEventListener('mousedown', outsideHandler)
54
+ outsideHandler = null
55
+ }
56
+ }
57
+ const open = (e) => {
58
+ if (props.disabled) return
59
+ if (isOpen.value) return
60
+ isOpen.value = true
61
+ focusedIndex.value = -1
62
+ query.value = ''
63
+ const target = e?.currentTarget || e?.target
64
+ rootEl.value = target?.closest ? target.closest(`[data-select-root="${instanceId}"]`) : null
65
+ if (props.appendTo === 'body') {
66
+ stopTracking = trackFloatingOverlay({
67
+ isOpen: () => isOpen.value,
68
+ getAnchor: () => {
69
+ const root = rootEl.value
70
+ return root ? root.querySelector('.n-select-trigger') : null
71
+ },
72
+ getPopup: () => document.querySelector(`[data-select-popup="${instanceId}"]`),
73
+ placement: props.placement,
74
+ align: 'start',
75
+ matchWidth: true,
76
+ minWidth: 240,
77
+ gap: 8,
78
+ margin: 8,
79
+ zIndex: 9999,
80
+ onUpdate: (result) => {
81
+ popupStyle.value = result.style
82
+ resolvedPlacement.value = result.placement
83
+ },
84
+ isEventInside: (event) => {
85
+ const t = event.target
86
+ if (!t || typeof t.closest !== 'function') return false
87
+ if (t.closest(`[data-select-root="${instanceId}"]`)) return true
88
+ if (t.closest(`[data-select-popup="${instanceId}"]`)) return true
89
+ return false
90
+ },
91
+ onOutside: () => close(),
92
+ })
93
+ } else {
94
+ if (outsideHandler) document.removeEventListener('mousedown', outsideHandler)
95
+ outsideHandler = (event) => {
96
+ const t = event.target
97
+ if (!t || typeof t.closest !== 'function') return
98
+ if (t.closest(`[data-select-root="${instanceId}"]`)) return
99
+ close()
100
+ }
101
+ document.addEventListener('mousedown', outsideHandler)
102
+ }
103
+ requestAnimationFrame(() => {
104
+ if (!props.searchable) return
105
+ const search = props.appendTo === 'body'
106
+ ? document.querySelector(`[data-select-popup="${instanceId}"] .n-select-search-input`)
107
+ : rootEl.value?.querySelector?.('.n-select-search-input')
108
+ if (search && typeof search.focus === 'function') {
109
+ try { search.focus() } catch {}
110
+ }
111
+ })
112
+ }
113
+ const toggle = (e) => {
114
+ if (props.disabled) return
115
+ if (isOpen.value) close()
116
+ else open(e)
117
+ }
118
+ const select = (option) => {
119
+ if (option.disabled) return
120
+ emit('update:modelValue', option.value)
121
+ close()
122
+ }
123
+ const clear = () => {
124
+ emit('update:modelValue', '')
125
+ emit('clear')
126
+ query.value = ''
127
+ }
128
+ const handleKeydown = (e) => {
129
+ if (!isOpen.value) {
130
+ if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {
131
+ e.preventDefault()
132
+ open(e)
133
+ }
134
+ return
135
+ }
136
+ const items = getFlatOptions()
137
+ switch (e.key) {
138
+ case 'ArrowDown':
139
+ e.preventDefault()
140
+ focusedIndex.value = Math.min(focusedIndex.value + 1, items.length - 1)
141
+ break
142
+ case 'ArrowUp':
143
+ e.preventDefault()
144
+ focusedIndex.value = Math.max(focusedIndex.value - 1, 0)
145
+ break
146
+ case 'Enter':
147
+ e.preventDefault()
148
+ if (items[focusedIndex.value]) {
149
+ select(items[focusedIndex.value])
150
+ }
151
+ break
152
+ case 'Escape':
153
+ e.preventDefault()
154
+ close()
155
+ break
156
+ }
157
+ }
158
+ const getFlatOptions = () => {
159
+ const flat = []
160
+ for (const opt of filteredOptions.value) {
161
+ if ('group' in opt) {
162
+ flat.push(...opt.items)
163
+ } else {
164
+ flat.push(opt)
165
+ }
166
+ }
167
+ return flat
168
+ }
169
+ onBeforeUnmount(() => {
170
+ close()
171
+ })
172
+ return { isOpen, query, focusedIndex, instanceId, popupStyle, resolvedPlacement, rootEl, stopTracking, outsideHandler, filteredOptions, selectedOption, close, open, toggle, select, clear, handleKeydown, getFlatOptions, onBeforeUnmount, trackFloatingOverlay, $slots, emit }
173
+ }
174
+ })
175
+ // Injected render function
176
+ _sfc_main.render = function(ctx) {
177
+ const { isOpen, query, focusedIndex, instanceId, popupStyle, resolvedPlacement, rootEl, stopTracking, outsideHandler, filteredOptions, selectedOption, close, open, toggle, select, clear, handleKeydown, getFlatOptions, onBeforeUnmount, trackFloatingOverlay, $slots, emit, modelValue, options, placeholder, label, disabled, searchable, clearable, placement, appendTo, Fragment: _ntc_Fragment, Teleport: _ntc_Teleport } = ctx
178
+ return h('div', { class: ["n-select", { 'is-open': isOpen.value, 'is-disabled': disabled }], "data-select-root": instanceId, "data-v-fef169b": "" }, [
179
+ "\n ",
180
+ (label) ? h('label', { class: "n-select-label", "data-v-fef169b": "" }, [
181
+ label
182
+ ]) : null,
183
+ h('div', { class: "n-select-trigger", onClick: toggle, onKeydown: handleKeydown, tabindex: "0", role: "combobox", "aria-expanded": isOpen.value, "data-v-fef169b": "" }, [
184
+ "\n ",
185
+ (selectedOption.value) ? h('span', { class: "n-select-value", "data-v-fef169b": "" }, [
186
+ "\n ",
187
+ selectedOption.value.label,
188
+ "\n "
189
+ ]) : (true) ? h('span', { class: "n-select-placeholder", "data-v-fef169b": "" }, [
190
+ "\n ",
191
+ placeholder,
192
+ "\n "
193
+ ]) : null,
194
+ "\n ",
195
+ h('div', { class: "n-select-trigger-actions", "data-v-fef169b": "" }, [
196
+ "\n ",
197
+ (clearable && modelValue) ? h('button', { class: "n-select-clear", type: "button", onClick: ($event) => { $event.stopPropagation(); (clear)($event) }, tabindex: "-1", "data-v-fef169b": "" }, [
198
+ "✕"
199
+ ]) : null,
200
+ h('span', { class: "n-select-arrow", "data-v-fef169b": "" }, [
201
+ "▾"
202
+ ]),
203
+ "\n "
204
+ ]),
205
+ "\n "
206
+ ]),
207
+ "\n ",
208
+ (isOpen.value && appendTo !== 'body') ? h('div', { class: "n-select-dropdown", "data-v-fef169b": "" }, [
209
+ "\n ",
210
+ (searchable) ? h('div', { class: "n-select-search", "data-v-fef169b": "" }, [
211
+ "\n ",
212
+ h('input', { class: "n-select-search-input", value: query.value, onInput: ($event) => { query.value = $event.target.value }, placeholder: "Search...", onKeydown: ($event) => { $event.stopPropagation(); (handleKeydown)($event) }, "data-v-fef169b": "" }),
213
+ "\n "
214
+ ]) : null,
215
+ h('div', { class: "n-select-options", "data-v-fef169b": "" }, [
216
+ "\n ",
217
+ filteredOptions.value.map((item, i) =>
218
+ h('div', { key: i, "data-v-fef169b": "" }, [
219
+ "\n ",
220
+ ('group' in item) ? h('div', { class: "n-select-group-label", "data-v-fef169b": "" }, [
221
+ item.group
222
+ ]) : null,
223
+ 'items' in item ? item.items : [item].map((opt, index) =>
224
+ h('div', { class: ["n-select-option", {
225
+ 'is-selected': opt.value === modelValue,
226
+ 'is-focused': getFlatOptions().indexOf(opt) === focusedIndex.value,
227
+ 'is-disabled': opt.disabled
228
+ }], key: opt.value, onClick: ($event) => { select(opt) }, "data-v-fef169b": "" }, [
229
+ "\n ",
230
+ opt.label,
231
+ "\n "
232
+ ])
233
+ ),
234
+ "\n "
235
+ ])
236
+ ),
237
+ "\n ",
238
+ (filteredOptions.value.length === 0) ? h('div', { class: "n-select-empty", "data-v-fef169b": "" }, [
239
+ "\n No options available\n "
240
+ ]) : null
241
+ ]),
242
+ "\n "
243
+ ]) : null,
244
+ h(_ntc_Teleport, { to: "body", "data-v-fef169b": "" }, [
245
+ "\n ",
246
+ (isOpen.value && appendTo === 'body') ? h('div', { class: ["n-select-dropdown", { 'is-top': resolvedPlacement.value === 'top' }], "data-select-popup": instanceId, style: popupStyle.value, "data-v-fef169b": "" }, [
247
+ "\n ",
248
+ (searchable) ? h('div', { class: "n-select-search", "data-v-fef169b": "" }, [
249
+ "\n ",
250
+ h('input', { class: "n-select-search-input", value: query.value, onInput: ($event) => { query.value = $event.target.value }, placeholder: "Search...", onKeydown: ($event) => { $event.stopPropagation(); (handleKeydown)($event) }, "data-v-fef169b": "" }),
251
+ "\n "
252
+ ]) : null,
253
+ h('div', { class: "n-select-options", "data-v-fef169b": "" }, [
254
+ "\n ",
255
+ filteredOptions.value.map((item, i) =>
256
+ h('div', { key: i, "data-v-fef169b": "" }, [
257
+ "\n ",
258
+ ('group' in item) ? h('div', { class: "n-select-group-label", "data-v-fef169b": "" }, [
259
+ item.group
260
+ ]) : null,
261
+ 'items' in item ? item.items : [item].map((opt, index) =>
262
+ h('div', { class: ["n-select-option", {
263
+ 'is-selected': opt.value === modelValue,
264
+ 'is-focused': getFlatOptions().indexOf(opt) === focusedIndex.value,
265
+ 'is-disabled': opt.disabled
266
+ }], key: opt.value, onClick: ($event) => { select(opt) }, "data-v-fef169b": "" }, [
267
+ "\n ",
268
+ opt.label,
269
+ "\n "
270
+ ])
271
+ ),
272
+ "\n "
273
+ ])
274
+ ),
275
+ "\n ",
276
+ (filteredOptions.value.length === 0) ? h('div', { class: "n-select-empty", "data-v-fef169b": "" }, [
277
+ "\n No options available\n "
278
+ ]) : null
279
+ ]),
280
+ "\n "
281
+ ]) : null
282
+ ]),
283
+ "\n "
284
+ ])
285
+ }
286
+ _sfc_main.__scopeId = 'data-v-fef169b'
287
+ _sfc_main.__hmrId = 'NSelect_nexa'
288
+
289
+ export default _sfc_main
290
+
291
+ const __style = `.n-select[data-v-fef169b]{
292
+ position: relative;
293
+ width: 100%;
294
+ font-family: var(--n-font-sans);
295
+ }
296
+
297
+ .n-select-label[data-v-fef169b]{
298
+ display: block;
299
+ font-size: var(--n-text-sm);
300
+ font-weight: var(--n-weight-medium);
301
+ color: var(--n-color-text-secondary);
302
+ margin-bottom: var(--n-space-2);
303
+ }
304
+
305
+ .n-select-trigger[data-v-fef169b]{
306
+ background: var(--n-color-surface);
307
+ border: 1px solid var(--n-color-border);
308
+ border-radius: var(--n-radius-md);
309
+ padding: 0.75rem 1rem;
310
+ display: flex;
311
+ justify-content: space-between;
312
+ align-items: center;
313
+ cursor: pointer;
314
+ transition: all var(--n-transition-fast);
315
+ color: var(--n-color-text);
316
+ gap: var(--n-space-2);
317
+ }
318
+
319
+ .n-select-trigger[data-v-fef169b]:focus-visible{
320
+ border-color: var(--n-color-primary);
321
+ box-shadow: 0 0 0 3px var(--n-color-primary-light);
322
+ }
323
+
324
+ .n-select[data-v-fef169b]:hover .n-select-trigger:not(.is-disabled){
325
+ border-color: var(--n-color-border-hover);
326
+ }
327
+
328
+ .n-select.is-open .n-select-trigger[data-v-fef169b]{
329
+ border-color: var(--n-color-primary);
330
+ box-shadow: 0 0 0 3px var(--n-color-primary-light);
331
+ }
332
+
333
+ .n-select-placeholder[data-v-fef169b]{
334
+ color: var(--n-color-text-muted);
335
+ }
336
+
337
+ .n-select-trigger-actions[data-v-fef169b]{
338
+ display: flex;
339
+ align-items: center;
340
+ gap: 0.25rem;
341
+ flex-shrink: 0;
342
+ }
343
+
344
+ .n-select-clear[data-v-fef169b]{
345
+ background: transparent;
346
+ border: none;
347
+ color: var(--n-color-text-muted);
348
+ cursor: pointer;
349
+ padding: 0.15rem;
350
+ font-size: var(--n-text-xs);
351
+ border-radius: var(--n-radius-sm);
352
+ line-height: 1;
353
+ }
354
+
355
+ .n-select-clear[data-v-fef169b]:hover{
356
+ color: var(--n-color-text);
357
+ }
358
+
359
+ .n-select-arrow[data-v-fef169b]{
360
+ color: var(--n-color-text-muted);
361
+ transition: transform var(--n-transition-fast);
362
+ font-size: var(--n-text-xs);
363
+ }
364
+
365
+ .is-open .n-select-arrow[data-v-fef169b]{
366
+ transform: rotate(180deg);
367
+ }
368
+
369
+ .n-select-dropdown[data-v-fef169b]{
370
+ position: absolute;
371
+ top: calc(100% + 0.5rem);
372
+ left: 0;
373
+ width: 100%;
374
+ background: var(--n-color-surface);
375
+ border: 1px solid var(--n-color-border);
376
+ border-radius: var(--n-radius-md);
377
+ box-shadow: var(--n-shadow-lg);
378
+ z-index: var(--n-z-dropdown);
379
+ overflow: hidden;
380
+ animation: n-dropdown-in 0.2s cubic-bezier(0, 1, 0, 1);
381
+ }
382
+
383
+ @keyframes n-dropdown-in {
384
+ from[data-v-fef169b]{ opacity: 0; transform: translateY(-8px); }
385
+ to[data-v-fef169b]{ opacity: 1; transform: translateY(0); }
386
+ }
387
+
388
+ .n-select-dropdown.is-top[data-v-fef169b]{
389
+ animation: n-dropdown-in-top 0.2s cubic-bezier(0, 1, 0, 1);
390
+ }
391
+
392
+ @keyframes n-dropdown-in-top {
393
+ from[data-v-fef169b]{ opacity: 0; transform: translateY(8px); }
394
+ to[data-v-fef169b]{ opacity: 1; transform: translateY(0); }
395
+ }
396
+
397
+ .n-select-search[data-v-fef169b]{
398
+ padding: var(--n-space-2);
399
+ border-bottom: 1px solid var(--n-color-border);
400
+ }
401
+
402
+ .n-select-search-input[data-v-fef169b]{
403
+ width: 100%;
404
+ background: var(--n-color-bg);
405
+ border: 1px solid var(--n-color-border);
406
+ border-radius: var(--n-radius-sm);
407
+ padding: var(--n-space-2) var(--n-space-3);
408
+ color: var(--n-color-text);
409
+ font-size: var(--n-text-sm);
410
+ outline: none;
411
+ font-family: inherit;
412
+ }
413
+
414
+ .n-select-search-input[data-v-fef169b]:focus{
415
+ border-color: var(--n-color-primary);
416
+ }
417
+
418
+ .n-select-options[data-v-fef169b]{
419
+ max-height: 250px;
420
+ overflow-y: auto;
421
+ }
422
+
423
+ .n-select-group-label[data-v-fef169b]{
424
+ padding: var(--n-space-2) var(--n-space-3);
425
+ font-size: var(--n-text-xs);
426
+ font-weight: var(--n-weight-bold);
427
+ color: var(--n-color-text-muted);
428
+ text-transform: uppercase;
429
+ letter-spacing: var(--n-tracking-wide);
430
+ background: var(--n-color-bg);
431
+ }
432
+
433
+ .n-select-option[data-v-fef169b]{
434
+ padding: 0.7rem 1rem;
435
+ color: var(--n-color-text-secondary);
436
+ cursor: pointer;
437
+ transition: all var(--n-transition-fast);
438
+ }
439
+
440
+ .n-select-option[data-v-fef169b]:hover,
441
+ .n-select-option.is-focused[data-v-fef169b]{
442
+ background: var(--n-color-glass);
443
+ color: var(--n-color-text);
444
+ }
445
+
446
+ .n-select-option.is-selected[data-v-fef169b]{
447
+ background: var(--n-color-primary-light);
448
+ color: var(--n-color-primary);
449
+ font-weight: var(--n-weight-semibold);
450
+ }
451
+
452
+ .n-select-option.is-disabled[data-v-fef169b]{
453
+ opacity: 0.4;
454
+ cursor: not-allowed;
455
+ }
456
+
457
+ .n-select-empty[data-v-fef169b]{
458
+ padding: var(--n-space-4);
459
+ color: var(--n-color-text-muted);
460
+ text-align: center;
461
+ font-size: var(--n-text-sm);
462
+ }
463
+
464
+ .is-disabled .n-select-trigger[data-v-fef169b]{
465
+ opacity: 0.5;
466
+ cursor: not-allowed;
467
+ }`
468
+ injectStyle('data-v-fef169b', __style)