@umbra.ui/core 0.1.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 (272) hide show
  1. package/dist/components/controls/Dropdown/types.d.ts +5 -0
  2. package/dist/components/controls/Dropdown/types.d.ts.map +1 -0
  3. package/dist/components/controls/Dropdown/types.js +1 -0
  4. package/dist/components/controls/SegmentedControl/types.d.ts +6 -0
  5. package/dist/components/controls/SegmentedControl/types.d.ts.map +1 -0
  6. package/dist/components/controls/SegmentedControl/types.js +1 -0
  7. package/dist/components/dialogs/Alert/types.d.ts +7 -0
  8. package/dist/components/dialogs/Alert/types.d.ts.map +1 -0
  9. package/dist/components/dialogs/Alert/types.js +1 -0
  10. package/dist/components/dialogs/Toast/types.d.ts +34 -0
  11. package/dist/components/dialogs/Toast/types.d.ts.map +1 -0
  12. package/dist/components/dialogs/Toast/types.js +10 -0
  13. package/dist/components/dialogs/Toast/useToast.d.ts +36 -0
  14. package/dist/components/dialogs/Toast/useToast.d.ts.map +1 -0
  15. package/dist/components/dialogs/Toast/useToast.js +90 -0
  16. package/dist/components/indicators/Tooltip/tooltip.d.ts +3 -0
  17. package/dist/components/indicators/Tooltip/tooltip.d.ts.map +1 -0
  18. package/dist/components/indicators/Tooltip/tooltip.js +33 -0
  19. package/dist/components/indicators/Tooltip/types.d.ts +14 -0
  20. package/dist/components/indicators/Tooltip/types.d.ts.map +1 -0
  21. package/dist/components/indicators/Tooltip/types.js +1 -0
  22. package/dist/components/indicators/Tooltip/useTooltip.d.ts +18 -0
  23. package/dist/components/indicators/Tooltip/useTooltip.d.ts.map +1 -0
  24. package/dist/components/indicators/Tooltip/useTooltip.js +57 -0
  25. package/dist/components/inputs/Tags/tag-bar-styles.d.ts +14 -0
  26. package/dist/components/inputs/Tags/tag-bar-styles.d.ts.map +1 -0
  27. package/dist/components/inputs/Tags/tag-bar-styles.js +313 -0
  28. package/dist/components/inputs/Tags/types.d.ts +93 -0
  29. package/dist/components/inputs/Tags/types.d.ts.map +1 -0
  30. package/dist/components/inputs/Tags/types.js +216 -0
  31. package/dist/components/inputs/search/types.d.ts +9 -0
  32. package/dist/components/inputs/search/types.d.ts.map +1 -0
  33. package/dist/components/inputs/search/types.js +1 -0
  34. package/dist/components/navigation/adaptive/types.d.ts +16 -0
  35. package/dist/components/navigation/adaptive/types.d.ts.map +1 -0
  36. package/dist/components/navigation/adaptive/types.js +1 -0
  37. package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts +27 -0
  38. package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts.map +1 -0
  39. package/dist/components/navigation/adaptive/useAdaptiveLayout.js +40 -0
  40. package/dist/components/navigation/adaptive/useBreakpoints.d.ts +6 -0
  41. package/dist/components/navigation/adaptive/useBreakpoints.d.ts.map +1 -0
  42. package/dist/components/navigation/adaptive/useBreakpoints.js +37 -0
  43. package/dist/components/navigation/adaptive/useContainerMonitor.d.ts +93 -0
  44. package/dist/components/navigation/adaptive/useContainerMonitor.d.ts.map +1 -0
  45. package/dist/components/navigation/adaptive/useContainerMonitor.js +145 -0
  46. package/dist/components/navigation/adaptive/useViewAnimation.d.ts +31 -0
  47. package/dist/components/navigation/adaptive/useViewAnimation.d.ts.map +1 -0
  48. package/dist/components/navigation/adaptive/useViewAnimation.js +591 -0
  49. package/dist/components/navigation/adaptive/useViewResize.d.ts +52 -0
  50. package/dist/components/navigation/adaptive/useViewResize.d.ts.map +1 -0
  51. package/dist/components/navigation/adaptive/useViewResize.js +146 -0
  52. package/dist/components/navigation/navstack/useNavigationStack.d.ts +25 -0
  53. package/dist/components/navigation/navstack/useNavigationStack.d.ts.map +1 -0
  54. package/dist/components/navigation/navstack/useNavigationStack.js +133 -0
  55. package/dist/components/navigation/slideover/useSlideoverController.d.ts +20 -0
  56. package/dist/components/navigation/slideover/useSlideoverController.d.ts.map +1 -0
  57. package/dist/components/navigation/slideover/useSlideoverController.js +267 -0
  58. package/dist/components/navigation/splitview/useSplitViewController.d.ts +20 -0
  59. package/dist/components/navigation/splitview/useSplitViewController.d.ts.map +1 -0
  60. package/dist/components/navigation/splitview/useSplitViewController.js +325 -0
  61. package/dist/components/navigation/tabcontroller/types.d.ts +21 -0
  62. package/dist/components/navigation/tabcontroller/types.d.ts.map +1 -0
  63. package/dist/components/navigation/tabcontroller/types.js +1 -0
  64. package/dist/components/navigation/tabcontroller/useTabController.d.ts +5 -0
  65. package/dist/components/navigation/tabcontroller/useTabController.d.ts.map +1 -0
  66. package/dist/components/navigation/tabcontroller/useTabController.js +10 -0
  67. package/dist/components/navigation/types.d.ts +8 -0
  68. package/dist/components/navigation/types.d.ts.map +1 -0
  69. package/dist/components/navigation/types.js +1 -0
  70. package/dist/components/pickers/CollectionPicker/types.d.ts +11 -0
  71. package/dist/components/pickers/CollectionPicker/types.d.ts.map +1 -0
  72. package/dist/components/pickers/CollectionPicker/types.js +1 -0
  73. package/dist/components/pickers/ColorPicker/colors.d.ts +13 -0
  74. package/dist/components/pickers/ColorPicker/colors.d.ts.map +1 -0
  75. package/dist/components/pickers/ColorPicker/colors.js +266 -0
  76. package/dist/components/pickers/FilePicker/types.d.ts +10 -0
  77. package/dist/components/pickers/FilePicker/types.d.ts.map +1 -0
  78. package/dist/components/pickers/FilePicker/types.js +1 -0
  79. package/dist/index.d.ts +91 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +196 -0
  82. package/dist/theme.d.ts +73 -0
  83. package/dist/theme.d.ts.map +1 -0
  84. package/dist/theme.js +279 -0
  85. package/dist/themes/blank.d.ts +7 -0
  86. package/dist/themes/blank.d.ts.map +1 -0
  87. package/dist/themes/blank.js +543 -0
  88. package/dist/themes/crimson-dark.d.ts +4 -0
  89. package/dist/themes/crimson-dark.d.ts.map +1 -0
  90. package/dist/themes/crimson-dark.js +552 -0
  91. package/dist/themes/cyan-light.d.ts +4 -0
  92. package/dist/themes/cyan-light.d.ts.map +1 -0
  93. package/dist/themes/cyan-light.js +552 -0
  94. package/dist/themes/dark.d.ts +4 -0
  95. package/dist/themes/dark.d.ts.map +1 -0
  96. package/dist/themes/dark.js +551 -0
  97. package/dist/themes/gold-dark.d.ts +4 -0
  98. package/dist/themes/gold-dark.d.ts.map +1 -0
  99. package/dist/themes/gold-dark.js +552 -0
  100. package/dist/themes/grass-dark.d.ts +4 -0
  101. package/dist/themes/grass-dark.d.ts.map +1 -0
  102. package/dist/themes/grass-dark.js +552 -0
  103. package/dist/themes/indigo.d.ts +4 -0
  104. package/dist/themes/indigo.d.ts.map +1 -0
  105. package/dist/themes/indigo.js +552 -0
  106. package/dist/themes/light.d.ts +4 -0
  107. package/dist/themes/light.d.ts.map +1 -0
  108. package/dist/themes/light.js +551 -0
  109. package/dist/themes/orange-dark.d.ts +4 -0
  110. package/dist/themes/orange-dark.d.ts.map +1 -0
  111. package/dist/themes/orange-dark.js +551 -0
  112. package/dist/themes/orange-light.d.ts +4 -0
  113. package/dist/themes/orange-light.d.ts.map +1 -0
  114. package/dist/themes/orange-light.js +551 -0
  115. package/package.json +62 -0
  116. package/src/components/controls/Button/Button.vue +417 -0
  117. package/src/components/controls/Button/README.md +348 -0
  118. package/src/components/controls/Button/theme.css +200 -0
  119. package/src/components/controls/Checkbox/Checkbox.vue +164 -0
  120. package/src/components/controls/Checkbox/README.md +441 -0
  121. package/src/components/controls/Checkbox/theme.css +36 -0
  122. package/src/components/controls/Dropdown/Dropdown.vue +476 -0
  123. package/src/components/controls/Dropdown/README.md +370 -0
  124. package/src/components/controls/Dropdown/theme.css +50 -0
  125. package/src/components/controls/Dropdown/types.ts +6 -0
  126. package/src/components/controls/IconButton/IconButton.vue +267 -0
  127. package/src/components/controls/IconButton/README.md +502 -0
  128. package/src/components/controls/IconButton/theme.css +89 -0
  129. package/src/components/controls/Radio/README.md +591 -0
  130. package/src/components/controls/Radio/Radio.vue +89 -0
  131. package/src/components/controls/Radio/theme.css +14 -0
  132. package/src/components/controls/RangeSlider/README.md +608 -0
  133. package/src/components/controls/RangeSlider/RangeSlider.vue +535 -0
  134. package/src/components/controls/RangeSlider/theme.css +80 -0
  135. package/src/components/controls/SegmentedControl/README.md +587 -0
  136. package/src/components/controls/SegmentedControl/SegmentedControl.vue +284 -0
  137. package/src/components/controls/SegmentedControl/theme.css +60 -0
  138. package/src/components/controls/SegmentedControl/types.ts +5 -0
  139. package/src/components/controls/Slider/README.md +627 -0
  140. package/src/components/controls/Slider/Slider.vue +260 -0
  141. package/src/components/controls/Slider/theme.css +74 -0
  142. package/src/components/controls/Stepper/README.md +601 -0
  143. package/src/components/controls/Stepper/Stepper.vue +103 -0
  144. package/src/components/controls/Stepper/theme.css +53 -0
  145. package/src/components/controls/Switch/README.md +667 -0
  146. package/src/components/controls/Switch/Switch.vue +127 -0
  147. package/src/components/controls/Switch/theme.css +42 -0
  148. package/src/components/dialogs/Alert/Alert.vue +218 -0
  149. package/src/components/dialogs/Alert/README.md +450 -0
  150. package/src/components/dialogs/Alert/theme.css +44 -0
  151. package/src/components/dialogs/Alert/types.ts +11 -0
  152. package/src/components/dialogs/Toast/README.md +522 -0
  153. package/src/components/dialogs/Toast/Toast.vue +296 -0
  154. package/src/components/dialogs/Toast/ToastContainer.vue +330 -0
  155. package/src/components/dialogs/Toast/theme.css +44 -0
  156. package/src/components/dialogs/Toast/types.ts +46 -0
  157. package/src/components/dialogs/Toast/useToast.ts +127 -0
  158. package/src/components/indicators/ProgressBar/ProgressBar.vue +98 -0
  159. package/src/components/indicators/ProgressBar/README.md +744 -0
  160. package/src/components/indicators/ProgressBar/theme.css +36 -0
  161. package/src/components/indicators/Tooltip/README.md +723 -0
  162. package/src/components/indicators/Tooltip/TooltipProvider.vue +142 -0
  163. package/src/components/indicators/Tooltip/theme.css +18 -0
  164. package/src/components/indicators/Tooltip/tooltip.ts +48 -0
  165. package/src/components/indicators/Tooltip/types.ts +15 -0
  166. package/src/components/indicators/Tooltip/useTooltip.ts +71 -0
  167. package/src/components/inputs/AutogrowTextView/AutogrowTextView.vue +110 -0
  168. package/src/components/inputs/AutogrowTextView/README.md +643 -0
  169. package/src/components/inputs/AutogrowTextView/theme.css +28 -0
  170. package/src/components/inputs/InputCard/InputCard.vue +600 -0
  171. package/src/components/inputs/InputCard/README.md +636 -0
  172. package/src/components/inputs/InputEmail/InputEmail.vue +698 -0
  173. package/src/components/inputs/InputEmail/README.md +764 -0
  174. package/src/components/inputs/InputNumber/InputNumber.vue +300 -0
  175. package/src/components/inputs/InputNumber/README.md +749 -0
  176. package/src/components/inputs/InputPhone/InputPhone.vue +645 -0
  177. package/src/components/inputs/InputPhone/README.md +636 -0
  178. package/src/components/inputs/InputSecure/InputSecure.vue +646 -0
  179. package/src/components/inputs/InputSecure/README.md +771 -0
  180. package/src/components/inputs/InputText/InputText.vue +225 -0
  181. package/src/components/inputs/InputText/README.md +844 -0
  182. package/src/components/inputs/OTP/OTP.vue +349 -0
  183. package/src/components/inputs/OTP/README.md +736 -0
  184. package/src/components/inputs/OTP/theme.css +50 -0
  185. package/src/components/inputs/StringCapture/README.md +718 -0
  186. package/src/components/inputs/StringCapture/StringCapture.vue +315 -0
  187. package/src/components/inputs/StringCapture/theme.css +86 -0
  188. package/src/components/inputs/Tags/README.md +897 -0
  189. package/src/components/inputs/Tags/TagBar.vue +793 -0
  190. package/src/components/inputs/Tags/TagCreation.vue +219 -0
  191. package/src/components/inputs/Tags/TagPicker.vue +380 -0
  192. package/src/components/inputs/Tags/tag-bar-styles.ts +354 -0
  193. package/src/components/inputs/Tags/theme.css +121 -0
  194. package/src/components/inputs/Tags/types.ts +346 -0
  195. package/src/components/inputs/search/README.md +759 -0
  196. package/src/components/inputs/search/SearchBar.vue +394 -0
  197. package/src/components/inputs/search/SearchResults.vue +310 -0
  198. package/src/components/inputs/search/theme.css +187 -0
  199. package/src/components/inputs/search/types.ts +8 -0
  200. package/src/components/inputs/theme.css +102 -0
  201. package/src/components/menus/ActionMenu/ActionMenu.vue +383 -0
  202. package/src/components/menus/ActionMenu/README.md +825 -0
  203. package/src/components/menus/ActionMenu/theme.css +93 -0
  204. package/src/components/models/Popover/Popover.vue +551 -0
  205. package/src/components/models/Popover/README.md +885 -0
  206. package/src/components/models/Popover/theme.css +52 -0
  207. package/src/components/models/Sheet/README.md +1159 -0
  208. package/src/components/models/Sheet/Sheet.vue +465 -0
  209. package/src/components/models/Sheet/theme.css +72 -0
  210. package/src/components/models/Sidebar/README.md +1228 -0
  211. package/src/components/models/Sidebar/Sidebar.vue +480 -0
  212. package/src/components/models/Sidebar/theme.css +90 -0
  213. package/src/components/navigation/adaptive/AdaptiveLayout.vue +779 -0
  214. package/src/components/navigation/adaptive/AdaptiveLayoutBreadcrumbs.vue +192 -0
  215. package/src/components/navigation/adaptive/AdaptiveLayoutMenuButton.vue +149 -0
  216. package/src/components/navigation/adaptive/README.md +768 -0
  217. package/src/components/navigation/adaptive/types.ts +19 -0
  218. package/src/components/navigation/adaptive/useAdaptiveLayout.ts +89 -0
  219. package/src/components/navigation/adaptive/useBreakpoints.ts +41 -0
  220. package/src/components/navigation/adaptive/useContainerMonitor.ts +214 -0
  221. package/src/components/navigation/adaptive/useViewAnimation.ts +721 -0
  222. package/src/components/navigation/adaptive/useViewResize.ts +211 -0
  223. package/src/components/navigation/navstack/NavigationStack.vue +180 -0
  224. package/src/components/navigation/navstack/README.md +994 -0
  225. package/src/components/navigation/navstack/useNavigationStack.ts +164 -0
  226. package/src/components/navigation/slideover/README.md +1275 -0
  227. package/src/components/navigation/slideover/SlideoverController.vue +287 -0
  228. package/src/components/navigation/slideover/useSlideoverController.ts +320 -0
  229. package/src/components/navigation/splitview/README.md +1115 -0
  230. package/src/components/navigation/splitview/SplitViewController.vue +176 -0
  231. package/src/components/navigation/splitview/useSplitViewController.ts +388 -0
  232. package/src/components/navigation/tabcontroller/README.md +919 -0
  233. package/src/components/navigation/tabcontroller/TabController.vue +307 -0
  234. package/src/components/navigation/tabcontroller/TabItem.vue +57 -0
  235. package/src/components/navigation/tabcontroller/types.ts +24 -0
  236. package/src/components/navigation/tabcontroller/useTabController.ts +18 -0
  237. package/src/components/navigation/theme.css +91 -0
  238. package/src/components/navigation/types.ts +7 -0
  239. package/src/components/pickers/CollectionPicker/CollectionPicker.vue +398 -0
  240. package/src/components/pickers/CollectionPicker/README.md +1115 -0
  241. package/src/components/pickers/CollectionPicker/theme.css +14 -0
  242. package/src/components/pickers/CollectionPicker/types.ts +11 -0
  243. package/src/components/pickers/ColorPicker/ColorPicker.vue +376 -0
  244. package/src/components/pickers/ColorPicker/README.md +1439 -0
  245. package/src/components/pickers/ColorPicker/colors.ts +299 -0
  246. package/src/components/pickers/ColorPicker/theme.css +32 -0
  247. package/src/components/pickers/DatePicker/DatePicker.vue +660 -0
  248. package/src/components/pickers/DatePicker/README.md +1195 -0
  249. package/src/components/pickers/DatePicker/theme.css +22 -0
  250. package/src/components/pickers/FilePicker/FilePicker.vue +534 -0
  251. package/src/components/pickers/FilePicker/README.md +1542 -0
  252. package/src/components/pickers/FilePicker/theme.css +48 -0
  253. package/src/components/pickers/FilePicker/types.ts +10 -0
  254. package/src/components/pickers/IconPicker/IconPicker.vue +327 -0
  255. package/src/components/pickers/IconPicker/README.md +1161 -0
  256. package/src/components/pickers/IconPicker/theme.css +28 -0
  257. package/src/components/pickers/theme.css +82 -0
  258. package/src/components/views/MarkdownViewer/MarkdownViewer.vue +442 -0
  259. package/src/components/views/MarkdownViewer/README.md +833 -0
  260. package/src/components/views/MarkdownViewer/theme.css +130 -0
  261. package/src/index.ts +263 -0
  262. package/src/theme.ts +378 -0
  263. package/src/themes/crimson-dark.ts +556 -0
  264. package/src/themes/cyan-light.ts +556 -0
  265. package/src/themes/dark.ts +557 -0
  266. package/src/themes/gold-dark.ts +556 -0
  267. package/src/themes/grass-dark.ts +556 -0
  268. package/src/themes/indigo.ts +556 -0
  269. package/src/themes/light.ts +557 -0
  270. package/src/themes/orange-dark.ts +557 -0
  271. package/src/themes/orange-light.ts +557 -0
  272. package/src/vue.d.ts +45 -0
@@ -0,0 +1,749 @@
1
+ # InputNumber
2
+
3
+ A specialized numeric input component built with Vue 3 Composition API and TypeScript. The InputNumber component provides numeric input validation, range constraints, unit labels, and visual feedback with smooth animations and accessibility features.
4
+
5
+ ## Installation/Import
6
+
7
+ ```typescript
8
+ import { InputNumber } from "@umbra-ui/core";
9
+ ```
10
+
11
+ **Dependencies:**
12
+
13
+ - Vue 3.x
14
+ - @umbra-ui/icons (for ripple animation and lock icons)
15
+
16
+ ## Basic Usage
17
+
18
+ ```vue
19
+ <script setup lang="ts">
20
+ import { ref } from "vue";
21
+ import { InputNumber } from "@umbra-ui/core";
22
+
23
+ const number = ref(0);
24
+
25
+ const handleNumberUpdate = (value: number) => {
26
+ console.log("Number:", value);
27
+ number.value = value;
28
+ };
29
+ </script>
30
+
31
+ <template>
32
+ <div>
33
+ <InputNumber
34
+ v-model:value="number"
35
+ placeholder="Enter a number"
36
+ :min="0"
37
+ :max="100"
38
+ label="items"
39
+ @update:value="handleNumberUpdate"
40
+ />
41
+ </div>
42
+ </template>
43
+ ```
44
+
45
+ ## Props
46
+
47
+ | Prop Name | Type | Required | Default | Description |
48
+ | ------------- | ------------------------------------------------------------- | -------- | ----------- | -------------------------------------- |
49
+ | `value` | `number` | No | `undefined` | The numeric value |
50
+ | `placeholder` | `string` | No | `"0"` | Placeholder text displayed when empty |
51
+ | `min` | `number` | No | `undefined` | Minimum allowed value |
52
+ | `max` | `number` | No | `undefined` | Maximum allowed value |
53
+ | `label` | `string` | No | `undefined` | Unit label displayed next to the input |
54
+ | `state` | `"normal" \| "active" \| "disabled" \| "readonly" \| "error"` | No | `"normal"` | Current state of the input field |
55
+
56
+ ## Events
57
+
58
+ | Event Name | Payload Type | Description |
59
+ | -------------- | ------------ | -------------------------------------- |
60
+ | `update:value` | `number` | Emitted when the numeric value changes |
61
+
62
+ ## Slots
63
+
64
+ This component does not use slots.
65
+
66
+ ## Exposed Methods/Refs
67
+
68
+ This component does not expose any methods or refs.
69
+
70
+ ## Features
71
+
72
+ ### Range Validation
73
+
74
+ - **Min/Max Constraints**: Enforces minimum and maximum value limits
75
+ - **Real-time Validation**: Validates range constraints as the user types
76
+ - **Error Messages**: Displays specific error messages for out-of-range values
77
+ - **Visual Feedback**: Changes input state to error when values are out of range
78
+
79
+ ### Unit Labels
80
+
81
+ - **Custom Labels**: Display unit labels (e.g., "kg", "items", "years") next to the input
82
+ - **Dynamic Styling**: Unit labels adapt their appearance based on input state
83
+ - **Responsive Design**: Unit labels maintain proper spacing and alignment
84
+
85
+ ### Input States
86
+
87
+ - **Normal**: Standard input state
88
+ - **Active**: Shows animated ripple icon for active state
89
+ - **Disabled**: Prevents user interaction with lock icon
90
+ - **Readonly**: Shows lock icon and prevents editing
91
+ - **Error**: Automatically triggered when value is out of range
92
+
93
+ ## CSS Customization
94
+
95
+ The InputNumber component uses CSS custom properties for theming. It inherits from the general input theme:
96
+
97
+ ```css
98
+ /* Input colors */
99
+ --input-background-normal: #ffffff;
100
+ --input-background-filled: #f8f9fa;
101
+ --input-text-empty: #6c757d;
102
+ --input-text-filled: #212529;
103
+ --input-border: #ced4da;
104
+ --input-border-filled: #80bdff;
105
+ --input-focus-border: #007bff;
106
+ --input-placeholder: #6c757d;
107
+ --input-placeholder-filled: #adb5bd;
108
+
109
+ /* State-specific colors */
110
+ --input-disabled-bg: #e9ecef;
111
+ --input-disabled-text: #6c757d;
112
+ --input-disabled-border: #ced4da;
113
+ --input-disabled-placeholder: #adb5bd;
114
+
115
+ --input-readonly-bg: #f8f9fa;
116
+ --input-readonly-text: #495057;
117
+ --input-readonly-border: #ced4da;
118
+ --input-readonly-placeholder: #6c757d;
119
+
120
+ --input-error-bg: #f8d7da;
121
+ --input-error-text: #721c24;
122
+ --input-error-border: #dc3545;
123
+ --input-text-error: #dc3545;
124
+ ```
125
+
126
+ ## Examples
127
+
128
+ ### Basic Number Input
129
+
130
+ ```vue
131
+ <script setup lang="ts">
132
+ import { ref } from "vue";
133
+ import { InputNumber } from "@umbra-ui/core";
134
+
135
+ const quantity = ref(0);
136
+ </script>
137
+
138
+ <template>
139
+ <div class="number-form">
140
+ <h3>Product Configuration</h3>
141
+
142
+ <div class="form-group">
143
+ <label>Quantity</label>
144
+ <InputNumber
145
+ v-model:value="quantity"
146
+ placeholder="Enter quantity"
147
+ :min="1"
148
+ :max="1000"
149
+ label="items"
150
+ />
151
+ </div>
152
+ </div>
153
+ </template>
154
+
155
+ <style module>
156
+ .number-form {
157
+ max-width: 400px;
158
+ padding: 1.5rem;
159
+ border: 1px solid #e0e0e0;
160
+ border-radius: 8px;
161
+ }
162
+
163
+ .form-group {
164
+ margin-bottom: 1rem;
165
+ }
166
+
167
+ label {
168
+ display: block;
169
+ margin-bottom: 0.5rem;
170
+ font-weight: 500;
171
+ color: #333;
172
+ }
173
+ </style>
174
+ ```
175
+
176
+ ### Range Validation
177
+
178
+ ```vue
179
+ <script setup lang="ts">
180
+ import { ref } from "vue";
181
+ import { InputNumber } from "@umbra-ui/core";
182
+
183
+ const age = ref(0);
184
+ const temperature = ref(0);
185
+ const percentage = ref(0);
186
+ </script>
187
+
188
+ <template>
189
+ <div class="range-examples">
190
+ <h3>Range Validation Examples</h3>
191
+
192
+ <div class="form-group">
193
+ <label>Age (18-65)</label>
194
+ <InputNumber
195
+ v-model:value="age"
196
+ placeholder="Enter your age"
197
+ :min="18"
198
+ :max="65"
199
+ label="years"
200
+ />
201
+ </div>
202
+
203
+ <div class="form-group">
204
+ <label>Temperature (-50 to 50)</label>
205
+ <InputNumber
206
+ v-model:value="temperature"
207
+ placeholder="Enter temperature"
208
+ :min="-50"
209
+ :max="50"
210
+ label="°C"
211
+ />
212
+ </div>
213
+
214
+ <div class="form-group">
215
+ <label>Progress (0-100)</label>
216
+ <InputNumber
217
+ v-model:value="percentage"
218
+ placeholder="Enter percentage"
219
+ :min="0"
220
+ :max="100"
221
+ label="%"
222
+ />
223
+ </div>
224
+ </div>
225
+ </template>
226
+
227
+ <style module>
228
+ .range-examples {
229
+ max-width: 500px;
230
+ padding: 1.5rem;
231
+ border: 1px solid #e0e0e0;
232
+ border-radius: 8px;
233
+ }
234
+
235
+ .form-group {
236
+ margin-bottom: 1.5rem;
237
+ }
238
+
239
+ label {
240
+ display: block;
241
+ margin-bottom: 0.5rem;
242
+ font-weight: 500;
243
+ color: #333;
244
+ }
245
+ </style>
246
+ ```
247
+
248
+ ### Different States
249
+
250
+ ```vue
251
+ <script setup lang="ts">
252
+ import { ref } from "vue";
253
+ import { InputNumber } from "@umbra-ui/core";
254
+
255
+ const normalNumber = ref(0);
256
+ const disabledNumber = ref(42);
257
+ const readonlyNumber = ref(100);
258
+ const errorNumber = ref(150); // Will trigger error if max is 100
259
+ </script>
260
+
261
+ <template>
262
+ <div class="states-example">
263
+ <h3>Input States</h3>
264
+
265
+ <div class="state-group">
266
+ <label>Normal State</label>
267
+ <InputNumber
268
+ v-model:value="normalNumber"
269
+ placeholder="Enter a number"
270
+ state="normal"
271
+ label="units"
272
+ />
273
+ </div>
274
+
275
+ <div class="state-group">
276
+ <label>Disabled State</label>
277
+ <InputNumber
278
+ v-model:value="disabledNumber"
279
+ state="disabled"
280
+ label="items"
281
+ />
282
+ </div>
283
+
284
+ <div class="state-group">
285
+ <label>Readonly State</label>
286
+ <InputNumber
287
+ v-model:value="readonlyNumber"
288
+ state="readonly"
289
+ label="count"
290
+ />
291
+ </div>
292
+
293
+ <div class="state-group">
294
+ <label>Error State (Out of Range)</label>
295
+ <InputNumber
296
+ v-model:value="errorNumber"
297
+ :max="100"
298
+ state="normal"
299
+ label="items"
300
+ />
301
+ </div>
302
+ </div>
303
+ </template>
304
+
305
+ <style module>
306
+ .states-example {
307
+ max-width: 500px;
308
+ padding: 1.5rem;
309
+ border: 1px solid #e0e0e0;
310
+ border-radius: 8px;
311
+ }
312
+
313
+ .state-group {
314
+ margin-bottom: 1.5rem;
315
+ }
316
+
317
+ label {
318
+ display: block;
319
+ margin-bottom: 0.5rem;
320
+ font-weight: 500;
321
+ color: #333;
322
+ }
323
+ </style>
324
+ ```
325
+
326
+ ### Calculator Form
327
+
328
+ ```vue
329
+ <script setup lang="ts">
330
+ import { ref, computed } from "vue";
331
+ import { InputNumber } from "@umbra-ui/core";
332
+
333
+ const calculatorData = ref({
334
+ firstNumber: 0,
335
+ secondNumber: 0,
336
+ operation: "add",
337
+ });
338
+
339
+ const result = computed(() => {
340
+ const { firstNumber, secondNumber, operation } = calculatorData.value;
341
+
342
+ switch (operation) {
343
+ case "add":
344
+ return firstNumber + secondNumber;
345
+ case "subtract":
346
+ return firstNumber - secondNumber;
347
+ case "multiply":
348
+ return firstNumber * secondNumber;
349
+ case "divide":
350
+ return secondNumber !== 0 ? firstNumber / secondNumber : 0;
351
+ default:
352
+ return 0;
353
+ }
354
+ });
355
+ </script>
356
+
357
+ <template>
358
+ <div class="calculator-form">
359
+ <h3>Simple Calculator</h3>
360
+
361
+ <div class="calculator-inputs">
362
+ <div class="form-group">
363
+ <label>First Number</label>
364
+ <InputNumber
365
+ v-model:value="calculatorData.firstNumber"
366
+ placeholder="0"
367
+ label=""
368
+ />
369
+ </div>
370
+
371
+ <div class="form-group">
372
+ <label>Operation</label>
373
+ <select v-model="calculatorData.operation">
374
+ <option value="add">+ (Add)</option>
375
+ <option value="subtract">- (Subtract)</option>
376
+ <option value="multiply">× (Multiply)</option>
377
+ <option value="divide">÷ (Divide)</option>
378
+ </select>
379
+ </div>
380
+
381
+ <div class="form-group">
382
+ <label>Second Number</label>
383
+ <InputNumber
384
+ v-model:value="calculatorData.secondNumber"
385
+ placeholder="0"
386
+ label=""
387
+ />
388
+ </div>
389
+ </div>
390
+
391
+ <div class="result">
392
+ <h4>Result: {{ result }}</h4>
393
+ </div>
394
+ </div>
395
+ </template>
396
+
397
+ <style module>
398
+ .calculator-form {
399
+ max-width: 500px;
400
+ padding: 1.5rem;
401
+ border: 1px solid #e0e0e0;
402
+ border-radius: 8px;
403
+ }
404
+
405
+ .calculator-inputs {
406
+ display: grid;
407
+ grid-template-columns: 1fr auto 1fr;
408
+ gap: 1rem;
409
+ align-items: end;
410
+ margin-bottom: 1.5rem;
411
+ }
412
+
413
+ .form-group {
414
+ display: flex;
415
+ flex-direction: column;
416
+ }
417
+
418
+ label {
419
+ margin-bottom: 0.5rem;
420
+ font-weight: 500;
421
+ color: #333;
422
+ }
423
+
424
+ select {
425
+ padding: 0.5rem;
426
+ border: 1px solid #ddd;
427
+ border-radius: 4px;
428
+ font-size: 1rem;
429
+ }
430
+
431
+ .result {
432
+ padding: 1rem;
433
+ background-color: #f8f9fa;
434
+ border-radius: 4px;
435
+ text-align: center;
436
+ }
437
+
438
+ .result h4 {
439
+ margin: 0;
440
+ color: #333;
441
+ }
442
+ </style>
443
+ ```
444
+
445
+ ### Settings Panel
446
+
447
+ ```vue
448
+ <script setup lang="ts">
449
+ import { ref } from "vue";
450
+ import { InputNumber } from "@umbra-ui/core";
451
+
452
+ const settings = ref({
453
+ maxConnections: 10,
454
+ timeoutSeconds: 30,
455
+ retryAttempts: 3,
456
+ cacheSize: 100,
457
+ refreshInterval: 60,
458
+ });
459
+
460
+ const handleSaveSettings = () => {
461
+ console.log("Saving settings:", settings.value);
462
+ // Save settings logic here
463
+ };
464
+ </script>
465
+
466
+ <template>
467
+ <div class="settings-panel">
468
+ <h3>Application Settings</h3>
469
+
470
+ <form @submit.prevent="handleSaveSettings">
471
+ <div class="settings-grid">
472
+ <div class="setting-group">
473
+ <label>Max Connections</label>
474
+ <InputNumber
475
+ v-model:value="settings.maxConnections"
476
+ :min="1"
477
+ :max="100"
478
+ label="connections"
479
+ />
480
+ </div>
481
+
482
+ <div class="setting-group">
483
+ <label>Timeout</label>
484
+ <InputNumber
485
+ v-model:value="settings.timeoutSeconds"
486
+ :min="5"
487
+ :max="300"
488
+ label="seconds"
489
+ />
490
+ </div>
491
+
492
+ <div class="setting-group">
493
+ <label>Retry Attempts</label>
494
+ <InputNumber
495
+ v-model:value="settings.retryAttempts"
496
+ :min="0"
497
+ :max="10"
498
+ label="attempts"
499
+ />
500
+ </div>
501
+
502
+ <div class="setting-group">
503
+ <label>Cache Size</label>
504
+ <InputNumber
505
+ v-model:value="settings.cacheSize"
506
+ :min="10"
507
+ :max="1000"
508
+ label="MB"
509
+ />
510
+ </div>
511
+
512
+ <div class="setting-group">
513
+ <label>Refresh Interval</label>
514
+ <InputNumber
515
+ v-model:value="settings.refreshInterval"
516
+ :min="10"
517
+ :max="3600"
518
+ label="seconds"
519
+ />
520
+ </div>
521
+ </div>
522
+
523
+ <button type="submit">Save Settings</button>
524
+ </form>
525
+ </div>
526
+ </template>
527
+
528
+ <style module>
529
+ .settings-panel {
530
+ max-width: 600px;
531
+ padding: 1.5rem;
532
+ border: 1px solid #e0e0e0;
533
+ border-radius: 8px;
534
+ }
535
+
536
+ .settings-grid {
537
+ display: grid;
538
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
539
+ gap: 1rem;
540
+ margin-bottom: 1.5rem;
541
+ }
542
+
543
+ .setting-group {
544
+ display: flex;
545
+ flex-direction: column;
546
+ }
547
+
548
+ label {
549
+ margin-bottom: 0.5rem;
550
+ font-weight: 500;
551
+ color: #333;
552
+ font-size: 0.9rem;
553
+ }
554
+
555
+ button {
556
+ width: 100%;
557
+ padding: 0.75rem;
558
+ background-color: #007bff;
559
+ color: white;
560
+ border: none;
561
+ border-radius: 4px;
562
+ cursor: pointer;
563
+ font-size: 1rem;
564
+ }
565
+
566
+ button:hover {
567
+ background-color: #0056b3;
568
+ }
569
+ </style>
570
+ ```
571
+
572
+ ### Measurement Converter
573
+
574
+ ```vue
575
+ <script setup lang="ts">
576
+ import { ref, computed } from "vue";
577
+ import { InputNumber } from "@umbra-ui/core";
578
+
579
+ const measurement = ref({
580
+ value: 0,
581
+ unit: "meters",
582
+ });
583
+
584
+ const convertedValue = computed(() => {
585
+ const { value, unit } = measurement.value;
586
+
587
+ switch (unit) {
588
+ case "meters":
589
+ return {
590
+ feet: value * 3.28084,
591
+ inches: value * 39.3701,
592
+ yards: value * 1.09361,
593
+ };
594
+ case "feet":
595
+ return {
596
+ meters: value * 0.3048,
597
+ inches: value * 12,
598
+ yards: value * 0.333333,
599
+ };
600
+ case "inches":
601
+ return {
602
+ meters: value * 0.0254,
603
+ feet: value * 0.0833333,
604
+ yards: value * 0.0277778,
605
+ };
606
+ case "yards":
607
+ return {
608
+ meters: value * 0.9144,
609
+ feet: value * 3,
610
+ inches: value * 36,
611
+ };
612
+ default:
613
+ return { meters: 0, feet: 0, inches: 0, yards: 0 };
614
+ }
615
+ });
616
+ </script>
617
+
618
+ <template>
619
+ <div class="converter">
620
+ <h3>Length Converter</h3>
621
+
622
+ <div class="converter-input">
623
+ <div class="form-group">
624
+ <label>Enter Length</label>
625
+ <div class="input-with-select">
626
+ <InputNumber
627
+ v-model:value="measurement.value"
628
+ placeholder="0"
629
+ :min="0"
630
+ label=""
631
+ />
632
+ <select v-model="measurement.unit">
633
+ <option value="meters">Meters</option>
634
+ <option value="feet">Feet</option>
635
+ <option value="inches">Inches</option>
636
+ <option value="yards">Yards</option>
637
+ </select>
638
+ </div>
639
+ </div>
640
+ </div>
641
+
642
+ <div class="conversion-results">
643
+ <h4>Converted Values</h4>
644
+ <div class="results-grid">
645
+ <div class="result-item">
646
+ <span class="value">{{ convertedValue.meters.toFixed(2) }}</span>
647
+ <span class="unit">Meters</span>
648
+ </div>
649
+ <div class="result-item">
650
+ <span class="value">{{ convertedValue.feet.toFixed(2) }}</span>
651
+ <span class="unit">Feet</span>
652
+ </div>
653
+ <div class="result-item">
654
+ <span class="value">{{ convertedValue.inches.toFixed(2) }}</span>
655
+ <span class="unit">Inches</span>
656
+ </div>
657
+ <div class="result-item">
658
+ <span class="value">{{ convertedValue.yards.toFixed(2) }}</span>
659
+ <span class="unit">Yards</span>
660
+ </div>
661
+ </div>
662
+ </div>
663
+ </div>
664
+ </template>
665
+
666
+ <style module>
667
+ .converter {
668
+ max-width: 500px;
669
+ padding: 1.5rem;
670
+ border: 1px solid #e0e0e0;
671
+ border-radius: 8px;
672
+ }
673
+
674
+ .form-group {
675
+ margin-bottom: 1.5rem;
676
+ }
677
+
678
+ label {
679
+ display: block;
680
+ margin-bottom: 0.5rem;
681
+ font-weight: 500;
682
+ color: #333;
683
+ }
684
+
685
+ .input-with-select {
686
+ display: flex;
687
+ gap: 0.5rem;
688
+ align-items: end;
689
+ }
690
+
691
+ .input-with-select select {
692
+ padding: 0.5rem;
693
+ border: 1px solid #ddd;
694
+ border-radius: 4px;
695
+ font-size: 1rem;
696
+ min-width: 120px;
697
+ }
698
+
699
+ .conversion-results {
700
+ margin-top: 1.5rem;
701
+ }
702
+
703
+ .conversion-results h4 {
704
+ margin-bottom: 1rem;
705
+ color: #333;
706
+ }
707
+
708
+ .results-grid {
709
+ display: grid;
710
+ grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
711
+ gap: 1rem;
712
+ }
713
+
714
+ .result-item {
715
+ padding: 1rem;
716
+ background-color: #f8f9fa;
717
+ border-radius: 4px;
718
+ text-align: center;
719
+ }
720
+
721
+ .result-item .value {
722
+ display: block;
723
+ font-size: 1.5rem;
724
+ font-weight: bold;
725
+ color: #007bff;
726
+ }
727
+
728
+ .result-item .unit {
729
+ display: block;
730
+ font-size: 0.9rem;
731
+ color: #666;
732
+ margin-top: 0.25rem;
733
+ }
734
+ </style>
735
+ ```
736
+
737
+ ## Notes
738
+
739
+ - The component automatically validates numeric input and enforces min/max constraints
740
+ - Range validation triggers error state with specific error messages
741
+ - Unit labels are displayed in a styled container that adapts to input state
742
+ - The component hides browser default number input spinners for a cleaner appearance
743
+ - Input is optimized for mobile devices with proper font sizes to prevent zoom
744
+ - The component supports both positive and negative numbers within specified ranges
745
+ - Empty values are treated as valid (undefined) and don't trigger range errors
746
+ - Visual feedback includes animated icons for different states (active, readonly, disabled)
747
+ - The component is fully accessible with proper ARIA attributes and keyboard navigation
748
+ - Range validation messages are automatically generated based on min/max constraints
749
+ - Unit labels maintain consistent styling across different input states and themes