$npx -y skills add DevExpress/agent-skills --skill devextreme-numberboxHelp developers use the DevExtreme NumberBox component (dxNumberBox) in Angular, React, Vue, and jQuery. Use when someone asks about NumberBox configuration, value limits, formatting, spin buttons, masks, value change events, or any scenario involving dxNumberBox or DxNumberBox.
| 1 | # DevExtreme NumberBox Skill |
| 2 | |
| 3 | A skill for building and configuring the DevExtreme NumberBox UI component (`dxNumberBox`) across Angular, React, Vue, and jQuery. |
| 4 | |
| 5 | ## When to Use This Skill |
| 6 | |
| 7 | - Creating a numeric input field |
| 8 | - Setting min/max value boundaries |
| 9 | - Formatting the displayed number |
| 10 | - Enabling spin buttons |
| 11 | - Handling value change events |
| 12 | - Using number masks |
| 13 | |
| 14 | ## Before You Start |
| 15 | |
| 16 | If the host agent has a structured question-asking tool available, use it to ask these questions one at a time with clear options — for example, Claude Code's `AskUserQuestion` tool or GitHub Copilot's `askQuestions` tool. If no such tool is available, ask the questions directly in the chat response before generating code. |
| 17 | |
| 18 | > ⚠️ **Always use the DevExtreme NumberBox (`dxNumberBox` / `DxNumberBox`). Never use react-number-format, numeral.js, or a plain HTML `<input type="number">`.** |
| 19 | |
| 20 | Before writing any code, ask: **Which framework are you using?** Angular, React, Vue, or jQuery? |
| 21 | |
| 22 | ## Key API |
| 23 | |
| 24 | | Option | Type | Default | Description | |
| 25 | |---|---|---|---| |
| 26 | | `value` | `Number` | `0` | The current numeric value | |
| 27 | | `min` | `Number` | `-Infinity` | Minimum allowed value | |
| 28 | | `max` | `Number` | `Infinity` | Maximum allowed value | |
| 29 | | `format` | `Format \| String` | `''` | Display format (e.g., `'$ #,##0.##'`, `'#0.00'`) | |
| 30 | | `step` | `Number` | `1` | Increment step for spin buttons and arrow keys | |
| 31 | | `showSpinButtons` | `Boolean` | `false` | Shows increment/decrement buttons | |
| 32 | | `showClearButton` | `Boolean` | `false` | Shows an × button to clear the field | |
| 33 | | `onValueChanged` | `function(e)` | `null` | Fires when the value changes; `e.value` is the new value | |
| 34 | | `disabled` | `Boolean` | `false` | Disables the component | |
| 35 | | `readOnly` | `Boolean` | `false` | Prevents user input | |
| 36 | | `placeholder` | `String` | `''` | Placeholder shown when empty | |
| 37 | | `label` | `String` | `''` | Floating label text | |
| 38 | | `invalidValueMessage` | `String` | `'Value must be a number'` | Message shown when input is not a valid number | |
| 39 | | `inputAttr` | `Object` | `{}` | HTML attributes applied to the inner `<input>` element | |
| 40 | |
| 41 | **Events:** `valueChanged`, `keyDown`, `keyUp`, `enterKey`, `focusIn`, `focusOut`, `input`, `change`. |
| 42 | |
| 43 | ## Getting Started |
| 44 | |
| 45 | ### jQuery |
| 46 | |
| 47 | ```html |
| 48 | <!-- index.html --> |
| 49 | <div id="number-box"></div> |
| 50 | ``` |
| 51 | |
| 52 | ```js |
| 53 | $(function() { |
| 54 | $('#number-box').dxNumberBox({ |
| 55 | value: 0, |
| 56 | min: 0, |
| 57 | max: 100, |
| 58 | showSpinButtons: true, |
| 59 | onValueChanged(e) { |
| 60 | console.log(e.value); |
| 61 | } |
| 62 | }); |
| 63 | }); |
| 64 | ``` |
| 65 | |
| 66 | ### Angular |
| 67 | |
| 68 | ```html |
| 69 | <!-- app.html --> |
| 70 | <dx-number-box |
| 71 | [value]="0" |
| 72 | [min]="0" |
| 73 | [max]="100" |
| 74 | [showSpinButtons]="true" |
| 75 | (onValueChanged)="onValueChanged($event)"> |
| 76 | </dx-number-box> |
| 77 | ``` |
| 78 | |
| 79 | ```ts |
| 80 | // app.ts |
| 81 | import { Component } from '@angular/core'; |
| 82 | import { DxNumberBoxComponent, DxNumberBoxTypes } from 'devextreme-angular/ui/number-box'; |
| 83 | |
| 84 | @Component({ |
| 85 | selector: 'app-root', |
| 86 | standalone: true, |
| 87 | imports: [DxNumberBoxComponent], |
| 88 | templateUrl: './app.html' |
| 89 | }) |
| 90 | export class AppComponent { |
| 91 | onValueChanged(e: DxNumberBoxTypes.ValueChangedEvent) { |
| 92 | console.log(e.value); |
| 93 | } |
| 94 | } |
| 95 | ``` |
| 96 | |
| 97 | ```vue |
| 98 | <template> |
| 99 | <DxNumberBox |
| 100 | :value="0" |
| 101 | :min="0" |
| 102 | :max="100" |
| 103 | :show-spin-buttons="true" |
| 104 | @value-changed="onValueChanged" |
| 105 | /> |
| 106 | </template> |
| 107 | |
| 108 | <script setup lang="ts"> |
| 109 | import DxNumberBox, { DxNumberBoxTypes } from 'devextreme-vue/number-box'; |
| 110 | |
| 111 | function onValueChanged(e: DxNumberBoxTypes.ValueChangedEvent) { |
| 112 | console.log(e.value); |
| 113 | } |
| 114 | </script> |
| 115 | ``` |
| 116 | |
| 117 | ### React |
| 118 | |
| 119 | ```tsx |
| 120 | import 'devextreme/dist/css/dx.fluent.blue.light.css'; |
| 121 | import { NumberBox, type NumberBoxTypes } from 'devextreme-react/number-box'; |
| 122 | |
| 123 | function onValueChanged(e: NumberBoxTypes.ValueChangedEvent) { |
| 124 | console.log(e.value); |
| 125 | } |
| 126 | |
| 127 | function App() { |
| 128 | return ( |
| 129 | // defaultValue = uncontrolled (no state needed); use value + useState for two-way binding |
| 130 | <NumberBox |
| 131 | defaultValue={0} |
| 132 | min={0} |
| 133 | max={100} |
| 134 | showSpinButtons={true} |
| 135 | onValueChanged={onValueChanged} |
| 136 | /> |
| 137 | ); |
| 138 | } |
| 139 | |
| 140 | export default App; |
| 141 | ``` |
| 142 | |
| 143 | ## Common Patterns |
| 144 | |
| 145 | ### Currency format with min/max |
| 146 | |
| 147 | ```tsx |
| 148 | {/* React */} |
| 149 | <NumberBox |
| 150 | value={261991} |
| 151 | min={0} |
| 152 | max={1000000} |
| 153 | format="$ #,##0.##" |
| 154 | /> |
| 155 | ``` |
| 156 | |
| 157 | ### Step increment with clear button |
| 158 | |
| 159 | ```html |
| 160 | <!-- Angular - |