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,311 @@
1
+ <script setup>
2
+ import { signal, computed, inject, effect } from 'nexa-framework'
3
+
4
+ const props = defineProps({
5
+ modelValue: { type: [String, Number], default: '' },
6
+ type: { type: String, default: 'text' },
7
+ placeholder: { type: String, default: '' },
8
+ label: { type: String, default: '' },
9
+ error: { type: String, default: '' },
10
+ id: { type: String, default: '' },
11
+ name: { type: String, default: '' },
12
+ autocomplete: { type: String, default: '' },
13
+ ariaDescribedby: { type: String, default: '' },
14
+ ariaInvalid: { type: [Boolean, String], default: false },
15
+ bindField: { type: Boolean, default: false },
16
+ disabled: { type: Boolean, default: false },
17
+ readonly: { type: Boolean, default: false },
18
+ clearable: { type: Boolean, default: false },
19
+ maxlength: { type: Number, default: 0 },
20
+ prefixIcon: { type: String, default: '' },
21
+ suffixIcon: { type: String, default: '' }
22
+ })
23
+
24
+ const emit = defineEmits(['update:modelValue', 'clear', 'focus', 'blur'])
25
+
26
+ const field = inject('nexa-ui:form-field', undefined)
27
+
28
+ const showPassword = signal(false)
29
+ const isFocused = signal(false)
30
+
31
+ const effectiveValue = computed(() => {
32
+ if (props.bindField && field?.value) return field.value.value
33
+ return props.modelValue
34
+ })
35
+
36
+ const draft = signal(String(effectiveValue.value ?? ''))
37
+
38
+ effect(() => {
39
+ const next = String(effectiveValue.value ?? '')
40
+ if (draft.value === next) return
41
+ draft.value = next
42
+ })
43
+
44
+ const effectiveId = computed(() => {
45
+ if (props.id) return props.id
46
+ if (props.bindField && field?.inputId) return field.inputId.value
47
+ return ''
48
+ })
49
+
50
+ const effectiveDescribedBy = computed(() => {
51
+ if (props.ariaDescribedby) return props.ariaDescribedby
52
+ if (props.bindField && field?.describedBy) return field.describedBy.value || ''
53
+ return ''
54
+ })
55
+
56
+ const effectiveInvalid = computed(() => {
57
+ if (props.bindField && field?.invalid) return field.invalid.value
58
+ return props.ariaInvalid
59
+ })
60
+
61
+ const effectiveError = computed(() => {
62
+ if (props.error) return props.error
63
+ if (props.bindField && field?.error) return field.error.value || ''
64
+ return ''
65
+ })
66
+
67
+ const effectiveDisabled = computed(() => {
68
+ if (props.disabled) return true
69
+ if (props.bindField && field?.disabled) return !!field.disabled.value
70
+ return false
71
+ })
72
+
73
+ const inputType = computed(() => {
74
+ if (props.type === 'password' && showPassword.value) return 'text'
75
+ return props.type
76
+ })
77
+
78
+ const currentLength = computed(() => draft.value.length)
79
+
80
+ const onInput = (e) => {
81
+ const next = e.target.value
82
+ if (draft.value !== next) draft.value = next
83
+ if (props.bindField && field?.setValue) {
84
+ field.setValue(next)
85
+ return
86
+ }
87
+ emit('update:modelValue', next)
88
+ }
89
+
90
+ const onFocus = () => {
91
+ isFocused.value = true
92
+ emit('focus')
93
+ }
94
+
95
+ const onBlur = () => {
96
+ isFocused.value = false
97
+ if (props.bindField && field?.onBlur) {
98
+ field.onBlur()
99
+ }
100
+ emit('blur')
101
+ }
102
+
103
+ const clear = () => {
104
+ if (draft.value) draft.value = ''
105
+ if (props.bindField && field?.setValue) {
106
+ field.setValue('')
107
+ emit('clear')
108
+ return
109
+ }
110
+ emit('update:modelValue', '')
111
+ emit('clear')
112
+ }
113
+
114
+ const togglePassword = () => {
115
+ showPassword.value = !showPassword.value
116
+ }
117
+ </script>
118
+
119
+ <template>
120
+ <div class="n-input-group">
121
+ <label v-if="label" class="n-input-label">{{ label }}</label>
122
+ <div class="n-input-wrapper" :class="{ 'is-focused': isFocused.value, 'has-error': effectiveError.value, 'is-disabled': effectiveDisabled.value }">
123
+ <span v-if="prefixIcon" class="n-input-icon is-prefix">{{ prefixIcon }}</span>
124
+ <input
125
+ :id="effectiveId.value || undefined"
126
+ :name="name || undefined"
127
+ :type="inputType.value"
128
+ :value="draft.value"
129
+ :placeholder="placeholder"
130
+ :disabled="effectiveDisabled.value"
131
+ :readonly="readonly"
132
+ :autocomplete="autocomplete || undefined"
133
+ :aria-describedby="effectiveDescribedBy.value || undefined"
134
+ :aria-invalid="effectiveInvalid.value || undefined"
135
+ :maxlength="maxlength || undefined"
136
+ class="n-input"
137
+ :class="{ 'has-prefix': !!prefixIcon, 'has-suffix': !!suffixIcon || clearable || type === 'password' }"
138
+ @input="onInput"
139
+ @focus="onFocus"
140
+ @blur="onBlur"
141
+ />
142
+ <div class="n-input-focus-ring"></div>
143
+ <div class="n-input-actions">
144
+ <button v-if="clearable && draft.value" class="n-input-action" @click="clear" tabindex="-1" type="button">✕</button>
145
+ <button v-if="type === 'password'" class="n-input-action" @click="togglePassword" tabindex="-1" type="button">
146
+ {{ showPassword.value ? '◉' : '◎' }}
147
+ </button>
148
+ <span v-if="suffixIcon" class="n-input-icon is-suffix">{{ suffixIcon }}</span>
149
+ </div>
150
+ </div>
151
+ <div class="n-input-bottom">
152
+ <span v-if="effectiveError.value" class="n-input-error-msg">{{ effectiveError.value }}</span>
153
+ <span v-if="maxlength > 0" class="n-input-counter">{{ currentLength.value }}/{{ maxlength }}</span>
154
+ </div>
155
+ </div>
156
+ </template>
157
+
158
+ <style scoped>
159
+ .n-input-group {
160
+ display: flex;
161
+ flex-direction: column;
162
+ gap: var(--n-space-2);
163
+ width: 100%;
164
+ }
165
+
166
+ .n-input-label {
167
+ font-size: var(--n-text-sm);
168
+ font-weight: var(--n-weight-semibold);
169
+ color: var(--n-color-text-secondary);
170
+ margin-left: var(--n-space-1);
171
+ }
172
+
173
+ .n-input-wrapper {
174
+ position: relative;
175
+ display: flex;
176
+ align-items: center;
177
+ transition: all var(--n-transition-fast);
178
+ }
179
+
180
+ .n-input {
181
+ position: relative;
182
+ z-index: 1;
183
+ width: 100%;
184
+ min-height: 44px;
185
+ background: var(--n-color-bg);
186
+ border: 1px solid var(--n-color-border);
187
+ color: var(--n-color-text);
188
+ padding: 0.75rem 1rem;
189
+ border-radius: var(--n-radius-md);
190
+ font-family: inherit;
191
+ font-size: var(--n-text-base);
192
+ line-height: 1.2;
193
+ box-sizing: border-box;
194
+ transition: all var(--n-transition-normal);
195
+ outline: none;
196
+ }
197
+
198
+ .n-input.has-prefix {
199
+ padding-left: 2.5rem;
200
+ }
201
+
202
+ .n-input.has-suffix {
203
+ padding-right: 2.5rem;
204
+ }
205
+
206
+ .n-input::placeholder {
207
+ color: var(--n-color-text-muted);
208
+ }
209
+
210
+ .n-input-focus-ring {
211
+ position: absolute;
212
+ inset: 0;
213
+ border-radius: var(--n-radius-md);
214
+ background: linear-gradient(135deg, var(--n-color-primary), var(--n-color-info));
215
+ opacity: 0;
216
+ pointer-events: none;
217
+ transition: opacity var(--n-transition-normal);
218
+ z-index: 0;
219
+ }
220
+
221
+ .is-focused .n-input-focus-ring {
222
+ opacity: 0.35;
223
+ }
224
+
225
+ .is-focused .n-input {
226
+ border-color: var(--n-color-primary);
227
+ background: var(--n-color-surface);
228
+ }
229
+
230
+ .has-error .n-input {
231
+ border-color: var(--n-color-danger);
232
+ }
233
+
234
+ .has-error .n-input-focus-ring {
235
+ background: var(--n-color-danger);
236
+ opacity: 0.35;
237
+ }
238
+
239
+ .n-input-icon {
240
+ position: absolute;
241
+ top: 50%;
242
+ transform: translateY(-50%);
243
+ color: var(--n-color-text-muted);
244
+ font-size: var(--n-text-sm);
245
+ pointer-events: none;
246
+ display: flex;
247
+ align-items: center;
248
+ line-height: 1;
249
+ }
250
+
251
+ .n-input-icon.is-prefix {
252
+ left: 0.85rem;
253
+ }
254
+
255
+ .n-input-icon.is-suffix {
256
+ right: 0.85rem;
257
+ }
258
+
259
+ .n-input-actions {
260
+ position: absolute;
261
+ right: 0.5rem;
262
+ top: 50%;
263
+ transform: translateY(-50%);
264
+ display: flex;
265
+ align-items: center;
266
+ gap: 0.15rem;
267
+ }
268
+
269
+ .n-input-action {
270
+ background: transparent;
271
+ border: none;
272
+ color: var(--n-color-text-muted);
273
+ cursor: pointer;
274
+ padding: 0.25rem;
275
+ font-size: var(--n-text-sm);
276
+ border-radius: var(--n-radius-sm);
277
+ transition: all var(--n-transition-fast);
278
+ display: flex;
279
+ align-items: center;
280
+ line-height: 1;
281
+ }
282
+
283
+ .n-input-action:hover {
284
+ color: var(--n-color-text);
285
+ background: var(--n-color-glass);
286
+ }
287
+
288
+ .n-input-bottom {
289
+ display: flex;
290
+ justify-content: space-between;
291
+ align-items: center;
292
+ padding: 0 var(--n-space-1);
293
+ }
294
+
295
+ .n-input-error-msg {
296
+ font-size: var(--n-text-xs);
297
+ color: var(--n-color-danger);
298
+ }
299
+
300
+ .n-input-counter {
301
+ font-size: var(--n-text-xs);
302
+ color: var(--n-color-text-muted);
303
+ margin-left: auto;
304
+ }
305
+
306
+ .is-disabled .n-input {
307
+ opacity: 0.5;
308
+ cursor: not-allowed;
309
+ background: var(--n-color-surface-alt);
310
+ }
311
+ </style>
@@ -0,0 +1,202 @@
1
+ import { signal, computed, inject, effect, batch, h, hText, defineComponent, registerComponent, reloadComponent, injectStyle } from 'nexa-framework'
2
+
3
+ const _sfc_main = defineComponent({
4
+ __scopeId: 'data-v-6dd313',
5
+ __hmrId: 'NInputNumber_nexa',
6
+ props: {
7
+ modelValue: { type: Number, default: 0 },
8
+ min: { type: Number, default: null },
9
+ max: { type: Number, default: null },
10
+ step: { type: Number, default: 1 },
11
+ bindField: { type: Boolean, default: false },
12
+ disabled: { type: Boolean, default: false },
13
+ readonly: { type: Boolean, default: false },
14
+ label: { type: String, default: '' },
15
+ placeholder: { type: String, default: '' }
16
+ },
17
+ emits: ['update:modelValue', 'focus', 'blur'],
18
+ setup(props, setupContext) {
19
+ const { emit, slots, slots: $slots } = setupContext
20
+ const field = inject('nexa-ui:form-field', undefined)
21
+ const effectiveValue = computed(() => {
22
+ if (props.bindField && field?.value) {
23
+ const v = field.value.value
24
+ return typeof v === 'number' ? v : Number(v)
25
+ }
26
+ return props.modelValue
27
+ })
28
+ const effectiveDisabled = computed(() => {
29
+ if (props.disabled) return true
30
+ if (props.bindField && field?.disabled) return !!field.disabled.value
31
+ return false
32
+ })
33
+ const text = signal(String(effectiveValue.value ?? ''))
34
+ effect(() => {
35
+ const next = effectiveValue.value
36
+ const nextText = next === null || next === undefined ? '' : String(next)
37
+ if (text.value === nextText) return
38
+ text.value = nextText
39
+ })
40
+ const canEdit = computed(() => !effectiveDisabled.value && !props.readonly)
41
+ const sanitize = (raw) => {
42
+ const input = String(raw ?? '')
43
+ if (!input) return ''
44
+ const allowMinus = typeof props.min === 'number' ? props.min < 0 : true
45
+ let out = ''
46
+ let hasDot = false
47
+ let hasMinus = false
48
+ for (let i = 0; i < input.length; i++) {
49
+ const ch = input[i] === ',' ? '.' : input[i]
50
+ const isDigit = ch >= '0' && ch <= '9'
51
+ if (isDigit) {
52
+ out += ch
53
+ continue
54
+ }
55
+ if (ch === '.' && !hasDot) {
56
+ hasDot = true
57
+ out += ch
58
+ continue
59
+ }
60
+ if (ch === '-' && allowMinus && !hasMinus && out.length === 0) {
61
+ hasMinus = true
62
+ out += ch
63
+ }
64
+ }
65
+ return out
66
+ }
67
+ const clamp = (n) => {
68
+ if (n == null || Number.isNaN(n)) return null
69
+ let out = n
70
+ if (typeof props.min === 'number' && !Number.isNaN(props.min)) out = Math.max(out, props.min)
71
+ if (typeof props.max === 'number' && !Number.isNaN(props.max)) out = Math.min(out, props.max)
72
+ return out
73
+ }
74
+ const parse = (raw) => {
75
+ const s = sanitize(raw).trim()
76
+ if (!s) return null
77
+ const n = Number(s)
78
+ if (Number.isNaN(n)) return null
79
+ return n
80
+ }
81
+ const setValue = (next) => {
82
+ if (!canEdit.value) return
83
+ const clamped = clamp(next)
84
+ if (clamped == null) return
85
+ batch(() => {
86
+ if (props.bindField && field?.setValue) field.setValue(clamped)
87
+ else emit('update:modelValue', clamped)
88
+ text.value = String(clamped)
89
+ })
90
+ }
91
+ const inc = () => {
92
+ if (!canEdit.value) return
93
+ const base = typeof effectiveValue.value === 'number' && !Number.isNaN(effectiveValue.value) ? effectiveValue.value : 0
94
+ setValue(base + (props.step || 1))
95
+ }
96
+ const dec = () => {
97
+ if (!canEdit.value) return
98
+ const base = typeof effectiveValue.value === 'number' && !Number.isNaN(effectiveValue.value) ? effectiveValue.value : 0
99
+ setValue(base - (props.step || 1))
100
+ }
101
+ const onInput = (e) => {
102
+ if (!canEdit.value) return
103
+ const nextRaw = e.target.value
104
+ const nextText = sanitize(nextRaw)
105
+ if (e?.target && e.target.value !== nextText) {
106
+ e.target.value = nextText
107
+ }
108
+ batch(() => {
109
+ text.value = nextText
110
+ const n = parse(nextText)
111
+ const clamped = clamp(n)
112
+ if (clamped == null) return
113
+ if (props.bindField && field?.setValue) field.setValue(clamped)
114
+ else emit('update:modelValue', clamped)
115
+ })
116
+ }
117
+ const onBeforeInput = (e) => {
118
+ if (!canEdit.value) return
119
+ const inputType = e?.inputType
120
+ if (typeof inputType === 'string' && inputType.includes('Composition')) return
121
+ if (typeof inputType === 'string' && !inputType.startsWith('insert')) return
122
+ const data = e?.data
123
+ if (typeof data !== 'string' || !data) return
124
+ for (let i = 0; i < data.length; i++) {
125
+ const ch = data[i] === ',' ? '.' : data[i]
126
+ const isDigit = ch >= '0' && ch <= '9'
127
+ if (isDigit || ch === '.' || ch === '-') continue
128
+ e.preventDefault()
129
+ return
130
+ }
131
+ }
132
+ const onPaste = (e) => {
133
+ if (!canEdit.value) return
134
+ const pasted = e?.clipboardData?.getData?.('text')
135
+ if (typeof pasted !== 'string') return
136
+ e.preventDefault()
137
+ const nextText = sanitize(pasted)
138
+ const target = e?.target
139
+ if (!target) return
140
+ target.value = nextText
141
+ onInput({ target })
142
+ }
143
+ const onKeydown = (e) => {
144
+ if (!canEdit.value) return
145
+ if (e.ctrlKey || e.metaKey || e.altKey) return
146
+ const key = e.key
147
+ if (typeof key !== 'string' || key.length !== 1) return
148
+ const ch = key === ',' ? '.' : key
149
+ const isDigit = ch >= '0' && ch <= '9'
150
+ if (isDigit || ch === '.' || ch === '-') return
151
+ e.preventDefault()
152
+ }
153
+ const onBlur = () => {
154
+ emit('blur')
155
+ if (props.bindField && field?.onBlur) field.onBlur()
156
+ const n = parse(text.value)
157
+ const clamped = clamp(n)
158
+ if (clamped == null) {
159
+ text.value = String(effectiveValue.value ?? '')
160
+ return
161
+ }
162
+ batch(() => {
163
+ text.value = String(clamped)
164
+ if (props.bindField && field?.setValue) field.setValue(clamped)
165
+ else emit('update:modelValue', clamped)
166
+ })
167
+ }
168
+ const onFocus = () => emit('focus')
169
+ return { field, effectiveValue, effectiveDisabled, text, canEdit, sanitize, clamp, parse, setValue, inc, dec, onInput, onBeforeInput, onPaste, onKeydown, onBlur, onFocus, inject, batch, $slots, emit }
170
+ }
171
+ })
172
+ // Injected render function
173
+ _sfc_main.render = function(ctx) {
174
+ const { field, effectiveValue, effectiveDisabled, text, canEdit, sanitize, clamp, parse, setValue, inc, dec, onInput, onBeforeInput, onPaste, onKeydown, onBlur, onFocus, inject, batch, $slots, emit, modelValue, min, max, step, bindField, disabled, readonly, label, placeholder, Fragment: _ntc_Fragment } = ctx
175
+ return h('div', { class: "n-inum", "data-v-6dd313": "" }, [
176
+ "\n ",
177
+ (label) ? h('label', { class: "n-inum-label", "data-v-6dd313": "" }, [
178
+ label
179
+ ]) : null,
180
+ h('div', { class: ["n-inum-wrap", { 'is-disabled': effectiveDisabled.value }], "data-v-6dd313": "" }, [
181
+ "\n ",
182
+ h('button', { class: "n-inum-btn n-inum-dec", type: "button", disabled: effectiveDisabled.value || readonly, "aria-label": "Decrement", onClick: dec, "data-v-6dd313": "" }, [
183
+ "−"
184
+ ]),
185
+ "\n ",
186
+ h('input', { class: "n-inum-input", type: "text", value: text.value, placeholder: placeholder, disabled: effectiveDisabled.value, readonly: readonly, inputmode: "decimal", autocomplete: "off", onBeforeinput: onBeforeInput, onKeydown: onKeydown, onPaste: onPaste, onInput: onInput, onFocus: onFocus, onBlur: onBlur, "data-v-6dd313": "" }),
187
+ "\n ",
188
+ h('button', { class: "n-inum-btn n-inum-inc", type: "button", disabled: effectiveDisabled.value || readonly, "aria-label": "Increment", onClick: inc, "data-v-6dd313": "" }, [
189
+ "+"
190
+ ]),
191
+ "\n "
192
+ ]),
193
+ "\n "
194
+ ])
195
+ }
196
+ _sfc_main.__scopeId = 'data-v-6dd313'
197
+ _sfc_main.__hmrId = 'NInputNumber_nexa'
198
+
199
+ export default _sfc_main
200
+
201
+ const __style = `.n-inum[data-v-6dd313]{display:flex;flex-direction:column;gap:var(--n-space-2);width:100%;font-family:var(--n-font-sans)}.n-inum-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-inum-wrap{display:flex;align-items:stretch;min-height:44px;background:var(--n-color-surface);border:1px solid var(--n-color-border);border-radius:var(--n-radius-md);overflow:hidden;transition:all var(--n-transition-fast)}.n-inum-wrap:focus-within{border-color:var(--n-color-primary);box-shadow:0 0 0 3px var(--n-color-primary-light)}.n-inum-input{flex:1;background:transparent;border:none;outline:none;padding:0.75rem 0.75rem;color:var(--n-color-text);font-size:var(--n-text-base);font-family:inherit;text-align:center;line-height:1.2;box-sizing:border-box}.n-inum-btn{width:2.5rem;background:transparent;border:none;color:var(--n-color-text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:var(--n-text-base);transition:all var(--n-transition-fast)}.n-inum-btn:hover:not(:disabled){background:var(--n-color-glass);color:var(--n-color-text)}.n-inum-btn:disabled{opacity:0.5;cursor:not-allowed}.is-disabled{opacity:0.6;cursor:not-allowed;background:var(--n-color-surface-alt)}`
202
+ injectStyle('data-v-6dd313', __style)