@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.
- package/dist/components/controls/Dropdown/types.d.ts +5 -0
- package/dist/components/controls/Dropdown/types.d.ts.map +1 -0
- package/dist/components/controls/Dropdown/types.js +1 -0
- package/dist/components/controls/SegmentedControl/types.d.ts +6 -0
- package/dist/components/controls/SegmentedControl/types.d.ts.map +1 -0
- package/dist/components/controls/SegmentedControl/types.js +1 -0
- package/dist/components/dialogs/Alert/types.d.ts +7 -0
- package/dist/components/dialogs/Alert/types.d.ts.map +1 -0
- package/dist/components/dialogs/Alert/types.js +1 -0
- package/dist/components/dialogs/Toast/types.d.ts +34 -0
- package/dist/components/dialogs/Toast/types.d.ts.map +1 -0
- package/dist/components/dialogs/Toast/types.js +10 -0
- package/dist/components/dialogs/Toast/useToast.d.ts +36 -0
- package/dist/components/dialogs/Toast/useToast.d.ts.map +1 -0
- package/dist/components/dialogs/Toast/useToast.js +90 -0
- package/dist/components/indicators/Tooltip/tooltip.d.ts +3 -0
- package/dist/components/indicators/Tooltip/tooltip.d.ts.map +1 -0
- package/dist/components/indicators/Tooltip/tooltip.js +33 -0
- package/dist/components/indicators/Tooltip/types.d.ts +14 -0
- package/dist/components/indicators/Tooltip/types.d.ts.map +1 -0
- package/dist/components/indicators/Tooltip/types.js +1 -0
- package/dist/components/indicators/Tooltip/useTooltip.d.ts +18 -0
- package/dist/components/indicators/Tooltip/useTooltip.d.ts.map +1 -0
- package/dist/components/indicators/Tooltip/useTooltip.js +57 -0
- package/dist/components/inputs/Tags/tag-bar-styles.d.ts +14 -0
- package/dist/components/inputs/Tags/tag-bar-styles.d.ts.map +1 -0
- package/dist/components/inputs/Tags/tag-bar-styles.js +313 -0
- package/dist/components/inputs/Tags/types.d.ts +93 -0
- package/dist/components/inputs/Tags/types.d.ts.map +1 -0
- package/dist/components/inputs/Tags/types.js +216 -0
- package/dist/components/inputs/search/types.d.ts +9 -0
- package/dist/components/inputs/search/types.d.ts.map +1 -0
- package/dist/components/inputs/search/types.js +1 -0
- package/dist/components/navigation/adaptive/types.d.ts +16 -0
- package/dist/components/navigation/adaptive/types.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/types.js +1 -0
- package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts +27 -0
- package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useAdaptiveLayout.js +40 -0
- package/dist/components/navigation/adaptive/useBreakpoints.d.ts +6 -0
- package/dist/components/navigation/adaptive/useBreakpoints.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useBreakpoints.js +37 -0
- package/dist/components/navigation/adaptive/useContainerMonitor.d.ts +93 -0
- package/dist/components/navigation/adaptive/useContainerMonitor.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useContainerMonitor.js +145 -0
- package/dist/components/navigation/adaptive/useViewAnimation.d.ts +31 -0
- package/dist/components/navigation/adaptive/useViewAnimation.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useViewAnimation.js +591 -0
- package/dist/components/navigation/adaptive/useViewResize.d.ts +52 -0
- package/dist/components/navigation/adaptive/useViewResize.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useViewResize.js +146 -0
- package/dist/components/navigation/navstack/useNavigationStack.d.ts +25 -0
- package/dist/components/navigation/navstack/useNavigationStack.d.ts.map +1 -0
- package/dist/components/navigation/navstack/useNavigationStack.js +133 -0
- package/dist/components/navigation/slideover/useSlideoverController.d.ts +20 -0
- package/dist/components/navigation/slideover/useSlideoverController.d.ts.map +1 -0
- package/dist/components/navigation/slideover/useSlideoverController.js +267 -0
- package/dist/components/navigation/splitview/useSplitViewController.d.ts +20 -0
- package/dist/components/navigation/splitview/useSplitViewController.d.ts.map +1 -0
- package/dist/components/navigation/splitview/useSplitViewController.js +325 -0
- package/dist/components/navigation/tabcontroller/types.d.ts +21 -0
- package/dist/components/navigation/tabcontroller/types.d.ts.map +1 -0
- package/dist/components/navigation/tabcontroller/types.js +1 -0
- package/dist/components/navigation/tabcontroller/useTabController.d.ts +5 -0
- package/dist/components/navigation/tabcontroller/useTabController.d.ts.map +1 -0
- package/dist/components/navigation/tabcontroller/useTabController.js +10 -0
- package/dist/components/navigation/types.d.ts +8 -0
- package/dist/components/navigation/types.d.ts.map +1 -0
- package/dist/components/navigation/types.js +1 -0
- package/dist/components/pickers/CollectionPicker/types.d.ts +11 -0
- package/dist/components/pickers/CollectionPicker/types.d.ts.map +1 -0
- package/dist/components/pickers/CollectionPicker/types.js +1 -0
- package/dist/components/pickers/ColorPicker/colors.d.ts +13 -0
- package/dist/components/pickers/ColorPicker/colors.d.ts.map +1 -0
- package/dist/components/pickers/ColorPicker/colors.js +266 -0
- package/dist/components/pickers/FilePicker/types.d.ts +10 -0
- package/dist/components/pickers/FilePicker/types.d.ts.map +1 -0
- package/dist/components/pickers/FilePicker/types.js +1 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +196 -0
- package/dist/theme.d.ts +73 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +279 -0
- package/dist/themes/blank.d.ts +7 -0
- package/dist/themes/blank.d.ts.map +1 -0
- package/dist/themes/blank.js +543 -0
- package/dist/themes/crimson-dark.d.ts +4 -0
- package/dist/themes/crimson-dark.d.ts.map +1 -0
- package/dist/themes/crimson-dark.js +552 -0
- package/dist/themes/cyan-light.d.ts +4 -0
- package/dist/themes/cyan-light.d.ts.map +1 -0
- package/dist/themes/cyan-light.js +552 -0
- package/dist/themes/dark.d.ts +4 -0
- package/dist/themes/dark.d.ts.map +1 -0
- package/dist/themes/dark.js +551 -0
- package/dist/themes/gold-dark.d.ts +4 -0
- package/dist/themes/gold-dark.d.ts.map +1 -0
- package/dist/themes/gold-dark.js +552 -0
- package/dist/themes/grass-dark.d.ts +4 -0
- package/dist/themes/grass-dark.d.ts.map +1 -0
- package/dist/themes/grass-dark.js +552 -0
- package/dist/themes/indigo.d.ts +4 -0
- package/dist/themes/indigo.d.ts.map +1 -0
- package/dist/themes/indigo.js +552 -0
- package/dist/themes/light.d.ts +4 -0
- package/dist/themes/light.d.ts.map +1 -0
- package/dist/themes/light.js +551 -0
- package/dist/themes/orange-dark.d.ts +4 -0
- package/dist/themes/orange-dark.d.ts.map +1 -0
- package/dist/themes/orange-dark.js +551 -0
- package/dist/themes/orange-light.d.ts +4 -0
- package/dist/themes/orange-light.d.ts.map +1 -0
- package/dist/themes/orange-light.js +551 -0
- package/package.json +62 -0
- package/src/components/controls/Button/Button.vue +417 -0
- package/src/components/controls/Button/README.md +348 -0
- package/src/components/controls/Button/theme.css +200 -0
- package/src/components/controls/Checkbox/Checkbox.vue +164 -0
- package/src/components/controls/Checkbox/README.md +441 -0
- package/src/components/controls/Checkbox/theme.css +36 -0
- package/src/components/controls/Dropdown/Dropdown.vue +476 -0
- package/src/components/controls/Dropdown/README.md +370 -0
- package/src/components/controls/Dropdown/theme.css +50 -0
- package/src/components/controls/Dropdown/types.ts +6 -0
- package/src/components/controls/IconButton/IconButton.vue +267 -0
- package/src/components/controls/IconButton/README.md +502 -0
- package/src/components/controls/IconButton/theme.css +89 -0
- package/src/components/controls/Radio/README.md +591 -0
- package/src/components/controls/Radio/Radio.vue +89 -0
- package/src/components/controls/Radio/theme.css +14 -0
- package/src/components/controls/RangeSlider/README.md +608 -0
- package/src/components/controls/RangeSlider/RangeSlider.vue +535 -0
- package/src/components/controls/RangeSlider/theme.css +80 -0
- package/src/components/controls/SegmentedControl/README.md +587 -0
- package/src/components/controls/SegmentedControl/SegmentedControl.vue +284 -0
- package/src/components/controls/SegmentedControl/theme.css +60 -0
- package/src/components/controls/SegmentedControl/types.ts +5 -0
- package/src/components/controls/Slider/README.md +627 -0
- package/src/components/controls/Slider/Slider.vue +260 -0
- package/src/components/controls/Slider/theme.css +74 -0
- package/src/components/controls/Stepper/README.md +601 -0
- package/src/components/controls/Stepper/Stepper.vue +103 -0
- package/src/components/controls/Stepper/theme.css +53 -0
- package/src/components/controls/Switch/README.md +667 -0
- package/src/components/controls/Switch/Switch.vue +127 -0
- package/src/components/controls/Switch/theme.css +42 -0
- package/src/components/dialogs/Alert/Alert.vue +218 -0
- package/src/components/dialogs/Alert/README.md +450 -0
- package/src/components/dialogs/Alert/theme.css +44 -0
- package/src/components/dialogs/Alert/types.ts +11 -0
- package/src/components/dialogs/Toast/README.md +522 -0
- package/src/components/dialogs/Toast/Toast.vue +296 -0
- package/src/components/dialogs/Toast/ToastContainer.vue +330 -0
- package/src/components/dialogs/Toast/theme.css +44 -0
- package/src/components/dialogs/Toast/types.ts +46 -0
- package/src/components/dialogs/Toast/useToast.ts +127 -0
- package/src/components/indicators/ProgressBar/ProgressBar.vue +98 -0
- package/src/components/indicators/ProgressBar/README.md +744 -0
- package/src/components/indicators/ProgressBar/theme.css +36 -0
- package/src/components/indicators/Tooltip/README.md +723 -0
- package/src/components/indicators/Tooltip/TooltipProvider.vue +142 -0
- package/src/components/indicators/Tooltip/theme.css +18 -0
- package/src/components/indicators/Tooltip/tooltip.ts +48 -0
- package/src/components/indicators/Tooltip/types.ts +15 -0
- package/src/components/indicators/Tooltip/useTooltip.ts +71 -0
- package/src/components/inputs/AutogrowTextView/AutogrowTextView.vue +110 -0
- package/src/components/inputs/AutogrowTextView/README.md +643 -0
- package/src/components/inputs/AutogrowTextView/theme.css +28 -0
- package/src/components/inputs/InputCard/InputCard.vue +600 -0
- package/src/components/inputs/InputCard/README.md +636 -0
- package/src/components/inputs/InputEmail/InputEmail.vue +698 -0
- package/src/components/inputs/InputEmail/README.md +764 -0
- package/src/components/inputs/InputNumber/InputNumber.vue +300 -0
- package/src/components/inputs/InputNumber/README.md +749 -0
- package/src/components/inputs/InputPhone/InputPhone.vue +645 -0
- package/src/components/inputs/InputPhone/README.md +636 -0
- package/src/components/inputs/InputSecure/InputSecure.vue +646 -0
- package/src/components/inputs/InputSecure/README.md +771 -0
- package/src/components/inputs/InputText/InputText.vue +225 -0
- package/src/components/inputs/InputText/README.md +844 -0
- package/src/components/inputs/OTP/OTP.vue +349 -0
- package/src/components/inputs/OTP/README.md +736 -0
- package/src/components/inputs/OTP/theme.css +50 -0
- package/src/components/inputs/StringCapture/README.md +718 -0
- package/src/components/inputs/StringCapture/StringCapture.vue +315 -0
- package/src/components/inputs/StringCapture/theme.css +86 -0
- package/src/components/inputs/Tags/README.md +897 -0
- package/src/components/inputs/Tags/TagBar.vue +793 -0
- package/src/components/inputs/Tags/TagCreation.vue +219 -0
- package/src/components/inputs/Tags/TagPicker.vue +380 -0
- package/src/components/inputs/Tags/tag-bar-styles.ts +354 -0
- package/src/components/inputs/Tags/theme.css +121 -0
- package/src/components/inputs/Tags/types.ts +346 -0
- package/src/components/inputs/search/README.md +759 -0
- package/src/components/inputs/search/SearchBar.vue +394 -0
- package/src/components/inputs/search/SearchResults.vue +310 -0
- package/src/components/inputs/search/theme.css +187 -0
- package/src/components/inputs/search/types.ts +8 -0
- package/src/components/inputs/theme.css +102 -0
- package/src/components/menus/ActionMenu/ActionMenu.vue +383 -0
- package/src/components/menus/ActionMenu/README.md +825 -0
- package/src/components/menus/ActionMenu/theme.css +93 -0
- package/src/components/models/Popover/Popover.vue +551 -0
- package/src/components/models/Popover/README.md +885 -0
- package/src/components/models/Popover/theme.css +52 -0
- package/src/components/models/Sheet/README.md +1159 -0
- package/src/components/models/Sheet/Sheet.vue +465 -0
- package/src/components/models/Sheet/theme.css +72 -0
- package/src/components/models/Sidebar/README.md +1228 -0
- package/src/components/models/Sidebar/Sidebar.vue +480 -0
- package/src/components/models/Sidebar/theme.css +90 -0
- package/src/components/navigation/adaptive/AdaptiveLayout.vue +779 -0
- package/src/components/navigation/adaptive/AdaptiveLayoutBreadcrumbs.vue +192 -0
- package/src/components/navigation/adaptive/AdaptiveLayoutMenuButton.vue +149 -0
- package/src/components/navigation/adaptive/README.md +768 -0
- package/src/components/navigation/adaptive/types.ts +19 -0
- package/src/components/navigation/adaptive/useAdaptiveLayout.ts +89 -0
- package/src/components/navigation/adaptive/useBreakpoints.ts +41 -0
- package/src/components/navigation/adaptive/useContainerMonitor.ts +214 -0
- package/src/components/navigation/adaptive/useViewAnimation.ts +721 -0
- package/src/components/navigation/adaptive/useViewResize.ts +211 -0
- package/src/components/navigation/navstack/NavigationStack.vue +180 -0
- package/src/components/navigation/navstack/README.md +994 -0
- package/src/components/navigation/navstack/useNavigationStack.ts +164 -0
- package/src/components/navigation/slideover/README.md +1275 -0
- package/src/components/navigation/slideover/SlideoverController.vue +287 -0
- package/src/components/navigation/slideover/useSlideoverController.ts +320 -0
- package/src/components/navigation/splitview/README.md +1115 -0
- package/src/components/navigation/splitview/SplitViewController.vue +176 -0
- package/src/components/navigation/splitview/useSplitViewController.ts +388 -0
- package/src/components/navigation/tabcontroller/README.md +919 -0
- package/src/components/navigation/tabcontroller/TabController.vue +307 -0
- package/src/components/navigation/tabcontroller/TabItem.vue +57 -0
- package/src/components/navigation/tabcontroller/types.ts +24 -0
- package/src/components/navigation/tabcontroller/useTabController.ts +18 -0
- package/src/components/navigation/theme.css +91 -0
- package/src/components/navigation/types.ts +7 -0
- package/src/components/pickers/CollectionPicker/CollectionPicker.vue +398 -0
- package/src/components/pickers/CollectionPicker/README.md +1115 -0
- package/src/components/pickers/CollectionPicker/theme.css +14 -0
- package/src/components/pickers/CollectionPicker/types.ts +11 -0
- package/src/components/pickers/ColorPicker/ColorPicker.vue +376 -0
- package/src/components/pickers/ColorPicker/README.md +1439 -0
- package/src/components/pickers/ColorPicker/colors.ts +299 -0
- package/src/components/pickers/ColorPicker/theme.css +32 -0
- package/src/components/pickers/DatePicker/DatePicker.vue +660 -0
- package/src/components/pickers/DatePicker/README.md +1195 -0
- package/src/components/pickers/DatePicker/theme.css +22 -0
- package/src/components/pickers/FilePicker/FilePicker.vue +534 -0
- package/src/components/pickers/FilePicker/README.md +1542 -0
- package/src/components/pickers/FilePicker/theme.css +48 -0
- package/src/components/pickers/FilePicker/types.ts +10 -0
- package/src/components/pickers/IconPicker/IconPicker.vue +327 -0
- package/src/components/pickers/IconPicker/README.md +1161 -0
- package/src/components/pickers/IconPicker/theme.css +28 -0
- package/src/components/pickers/theme.css +82 -0
- package/src/components/views/MarkdownViewer/MarkdownViewer.vue +442 -0
- package/src/components/views/MarkdownViewer/README.md +833 -0
- package/src/components/views/MarkdownViewer/theme.css +130 -0
- package/src/index.ts +263 -0
- package/src/theme.ts +378 -0
- package/src/themes/crimson-dark.ts +556 -0
- package/src/themes/cyan-light.ts +556 -0
- package/src/themes/dark.ts +557 -0
- package/src/themes/gold-dark.ts +556 -0
- package/src/themes/grass-dark.ts +556 -0
- package/src/themes/indigo.ts +556 -0
- package/src/themes/light.ts +557 -0
- package/src/themes/orange-dark.ts +557 -0
- package/src/themes/orange-light.ts +557 -0
- 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
|