@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,636 @@
1
+ # InputPhone
2
+
3
+ A specialized phone number input component built with Vue 3 Composition API and TypeScript. The InputPhone component provides automatic phone number formatting, country detection, validation, and visual feedback with smooth animations and accessibility features.
4
+
5
+ ## Installation/Import
6
+
7
+ ```typescript
8
+ import { InputPhone } from "@umbra-ui/core";
9
+ ```
10
+
11
+ **Dependencies:**
12
+
13
+ - Vue 3.x
14
+ - @umbra-ui/icons (for phone, warning, and check icons)
15
+
16
+ ## Basic Usage
17
+
18
+ ```vue
19
+ <script setup lang="ts">
20
+ import { ref } from "vue";
21
+ import { InputPhone } from "@umbra-ui/core";
22
+
23
+ const phoneNumber = ref("");
24
+
25
+ const handlePhoneUpdate = (value: string) => {
26
+ console.log("Phone:", value);
27
+ phoneNumber.value = value;
28
+ };
29
+
30
+ const handleFormattedUpdate = (formatted: string) => {
31
+ console.log("Formatted:", formatted);
32
+ };
33
+
34
+ const handleValidUpdate = (isValid: boolean) => {
35
+ console.log("Valid:", isValid);
36
+ };
37
+ </script>
38
+
39
+ <template>
40
+ <div>
41
+ <InputPhone
42
+ v-model:value="phoneNumber"
43
+ @update:formatted="handleFormattedUpdate"
44
+ @update:valid="handleValidUpdate"
45
+ placeholder="Enter phone number"
46
+ default-country="US"
47
+ :allow-international="true"
48
+ :show-country-code="true"
49
+ />
50
+ </div>
51
+ </template>
52
+ ```
53
+
54
+ ## Props
55
+
56
+ | Prop Name | Type | Required | Default | Description |
57
+ | -------------------- | ------------------------------------------------------------- | -------- | ---------------------- | -------------------------------------------- |
58
+ | `value` | `string` | No | `""` | The phone number value |
59
+ | `placeholder` | `string` | No | `"Enter phone number"` | Placeholder text displayed when empty |
60
+ | `defaultCountry` | `string` | No | `"US"` | ISO country code for default formatting |
61
+ | `allowInternational` | `boolean` | No | `true` | Whether to allow international phone numbers |
62
+ | `showCountryCode` | `boolean` | No | `true` | Whether to show country code when detected |
63
+ | `state` | `"normal" \| "active" \| "disabled" \| "readonly" \| "error"` | No | `"normal"` | Current state of the input field |
64
+
65
+ ## Events
66
+
67
+ | Event Name | Payload Type | Description |
68
+ | ------------------ | ------------ | ----------------------------------------------- |
69
+ | `update:value` | `string` | Emitted when the phone number value changes |
70
+ | `update:formatted` | `string` | Emitted when the formatted phone number changes |
71
+ | `update:valid` | `boolean` | Emitted when the validation state changes |
72
+
73
+ ## Slots
74
+
75
+ This component does not provide any slots.
76
+
77
+ ## Exposed Methods/Refs
78
+
79
+ This component does not expose any methods or refs.
80
+
81
+ ## CSS Customization
82
+
83
+ The InputPhone component uses CSS custom properties for theming and customization:
84
+
85
+ ### Input Container Variables
86
+
87
+ ```css
88
+ --input-border: 1px solid var(--input-border-color);
89
+ --input-border-radius: 0.588rem;
90
+ --input-focus-border: var(--input-focus-color);
91
+ --input-background-normal: var(--input-bg-normal);
92
+ --input-background-filled: var(--input-bg-filled);
93
+ --input-border-filled: var(--input-border-filled-color);
94
+ --input-text-empty: var(--input-text-empty-color);
95
+ --input-text-filled: var(--input-text-filled-color);
96
+ --input-placeholder: var(--input-placeholder-color);
97
+ --input-placeholder-filled: var(--input-placeholder-filled-color);
98
+ ```
99
+
100
+ ### State-Specific Variables
101
+
102
+ ```css
103
+ /* Disabled State */
104
+ --input-disabled-bg: var(--input-disabled-background);
105
+ --input-disabled-text: var(--input-disabled-text-color);
106
+ --input-disabled-border: var(--input-disabled-border-color);
107
+ --input-disabled-placeholder: var(--input-disabled-placeholder-color);
108
+
109
+ /* Readonly State */
110
+ --input-readonly-bg: var(--input-readonly-background);
111
+ --input-readonly-text: var(--input-readonly-text-color);
112
+ --input-readonly-border: var(--input-readonly-border-color);
113
+ --input-readonly-placeholder: var(--input-readonly-placeholder-color);
114
+
115
+ /* Error State */
116
+ --input-error-bg: var(--input-error-background);
117
+ --input-error-text: var(--input-error-text-color);
118
+ --input-error-border: var(--input-error-border-color);
119
+ --input-text-error: var(--input-error-text-color);
120
+ ```
121
+
122
+ ## Key Features
123
+
124
+ ### Automatic Formatting
125
+
126
+ - **Country Detection**: Automatically detects country from phone number patterns
127
+ - **Real-time Formatting**: Formats phone numbers as the user types
128
+ - **Multiple Formats**: Supports US, UK, and international phone number formats
129
+ - **Smart Cursor Positioning**: Maintains proper cursor position during formatting
130
+
131
+ ### Validation
132
+
133
+ - **Real-time Validation**: Validates phone numbers based on country-specific rules
134
+ - **Visual Feedback**: Shows validation state with icons and error messages
135
+ - **Digit Limits**: Enforces country-specific digit limits (US: 10/11, UK: 11/12, International: 7-15)
136
+ - **E.164 Compliance**: Follows international E.164 standard for phone numbers
137
+
138
+ ### User Experience
139
+
140
+ - **Input Restrictions**: Only allows digits and formatting characters
141
+ - **Paste Support**: Handles pasted phone numbers with proper formatting
142
+ - **Keyboard Navigation**: Supports standard keyboard navigation and editing
143
+ - **Responsive Design**: Adapts to different screen sizes with proper font scaling
144
+
145
+ ### Supported Countries
146
+
147
+ - **US**: `(555) 123-4567` or `+1 (555) 123-4567`
148
+ - **UK**: `20 1234 5678` or `+44 20 1234 5678`
149
+ - **International**: Generic formatting with country codes
150
+
151
+ ## Examples
152
+
153
+ ### Basic Phone Input
154
+
155
+ ```vue
156
+ <script setup lang="ts">
157
+ import { ref } from "vue";
158
+ import { InputPhone } from "@umbra-ui/core";
159
+
160
+ const phone = ref("");
161
+ </script>
162
+
163
+ <template>
164
+ <div class="phone-form">
165
+ <h3>Contact Information</h3>
166
+
167
+ <div class="form-group">
168
+ <label>Phone Number</label>
169
+ <InputPhone
170
+ v-model:value="phone"
171
+ placeholder="Enter your phone number"
172
+ default-country="US"
173
+ />
174
+ </div>
175
+
176
+ <div class="phone-display">
177
+ <p>Entered: {{ phone }}</p>
178
+ </div>
179
+ </div>
180
+ </template>
181
+
182
+ <style module>
183
+ .phone-form {
184
+ max-width: 400px;
185
+ padding: 1.5rem;
186
+ border: 1px solid #e0e0e0;
187
+ border-radius: 0.5rem;
188
+ }
189
+
190
+ .form-group {
191
+ margin-bottom: 1rem;
192
+ }
193
+
194
+ .form-group label {
195
+ display: block;
196
+ margin-bottom: 0.5rem;
197
+ font-weight: 500;
198
+ }
199
+
200
+ .phone-display {
201
+ margin-top: 1rem;
202
+ padding: 1rem;
203
+ background-color: #f5f5f5;
204
+ border-radius: 0.25rem;
205
+ }
206
+ </style>
207
+ ```
208
+
209
+ ### International Phone Numbers
210
+
211
+ ```vue
212
+ <script setup lang="ts">
213
+ import { ref } from "vue";
214
+ import { InputPhone } from "@umbra-ui/core";
215
+
216
+ const internationalPhone = ref("");
217
+ const isValid = ref(false);
218
+ const formatted = ref("");
219
+
220
+ const handleValidUpdate = (valid: boolean) => {
221
+ isValid.value = valid;
222
+ };
223
+
224
+ const handleFormattedUpdate = (formattedValue: string) => {
225
+ formatted.value = formattedValue;
226
+ };
227
+ </script>
228
+
229
+ <template>
230
+ <div class="international-example">
231
+ <h3>International Phone Numbers</h3>
232
+
233
+ <div class="form-group">
234
+ <label>Phone Number (Any Country)</label>
235
+ <InputPhone
236
+ v-model:value="internationalPhone"
237
+ @update:valid="handleValidUpdate"
238
+ @update:formatted="handleFormattedUpdate"
239
+ placeholder="Enter international phone number"
240
+ default-country="US"
241
+ :allow-international="true"
242
+ :show-country-code="true"
243
+ />
244
+ </div>
245
+
246
+ <div class="validation-status">
247
+ <div class="status-item">
248
+ <strong>Valid:</strong>
249
+ <span :class="{ valid: isValid, invalid: !isValid }">
250
+ {{ isValid ? "Yes" : "No" }}
251
+ </span>
252
+ </div>
253
+ <div class="status-item"><strong>Formatted:</strong> {{ formatted }}</div>
254
+ </div>
255
+ </div>
256
+ </template>
257
+
258
+ <style module>
259
+ .international-example {
260
+ max-width: 500px;
261
+ padding: 1.5rem;
262
+ border: 1px solid #e0e0e0;
263
+ border-radius: 0.5rem;
264
+ }
265
+
266
+ .form-group {
267
+ margin-bottom: 1rem;
268
+ }
269
+
270
+ .form-group label {
271
+ display: block;
272
+ margin-bottom: 0.5rem;
273
+ font-weight: 500;
274
+ }
275
+
276
+ .validation-status {
277
+ margin-top: 1rem;
278
+ padding: 1rem;
279
+ background-color: #f8f9fa;
280
+ border-radius: 0.25rem;
281
+ }
282
+
283
+ .status-item {
284
+ margin-bottom: 0.5rem;
285
+ }
286
+
287
+ .valid {
288
+ color: #28a745;
289
+ font-weight: 500;
290
+ }
291
+
292
+ .invalid {
293
+ color: #dc3545;
294
+ font-weight: 500;
295
+ }
296
+ </style>
297
+ ```
298
+
299
+ ### Contact Form Integration
300
+
301
+ ```vue
302
+ <script setup lang="ts">
303
+ import { ref, computed } from "vue";
304
+ import { InputPhone } from "@umbra-ui/core";
305
+
306
+ interface ContactForm {
307
+ name: string;
308
+ email: string;
309
+ phone: string;
310
+ message: string;
311
+ }
312
+
313
+ const form = ref<ContactForm>({
314
+ name: "",
315
+ email: "",
316
+ phone: "",
317
+ message: "",
318
+ });
319
+
320
+ const phoneValid = ref(false);
321
+
322
+ const isFormValid = computed(() => {
323
+ return (
324
+ form.value.name &&
325
+ form.value.email &&
326
+ form.value.phone &&
327
+ phoneValid.value &&
328
+ form.value.message
329
+ );
330
+ });
331
+
332
+ const handlePhoneValid = (valid: boolean) => {
333
+ phoneValid.value = valid;
334
+ };
335
+
336
+ const handleSubmit = () => {
337
+ if (isFormValid.value) {
338
+ console.log("Form submitted:", form.value);
339
+ // Handle form submission
340
+ }
341
+ };
342
+ </script>
343
+
344
+ <template>
345
+ <div class="contact-form">
346
+ <h3>Contact Us</h3>
347
+
348
+ <form @submit.prevent="handleSubmit">
349
+ <div class="form-group">
350
+ <label>Name *</label>
351
+ <input
352
+ v-model="form.name"
353
+ type="text"
354
+ placeholder="Your name"
355
+ required
356
+ />
357
+ </div>
358
+
359
+ <div class="form-group">
360
+ <label>Email *</label>
361
+ <input
362
+ v-model="form.email"
363
+ type="email"
364
+ placeholder="your@email.com"
365
+ required
366
+ />
367
+ </div>
368
+
369
+ <div class="form-group">
370
+ <label>Phone Number *</label>
371
+ <InputPhone
372
+ v-model:value="form.phone"
373
+ @update:valid="handlePhoneValid"
374
+ placeholder="Enter your phone number"
375
+ default-country="US"
376
+ />
377
+ <div v-if="form.phone && !phoneValid" class="error-message">
378
+ Please enter a valid phone number
379
+ </div>
380
+ </div>
381
+
382
+ <div class="form-group">
383
+ <label>Message *</label>
384
+ <textarea
385
+ v-model="form.message"
386
+ placeholder="Your message"
387
+ rows="4"
388
+ required
389
+ ></textarea>
390
+ </div>
391
+
392
+ <button type="submit" :disabled="!isFormValid" class="submit-button">
393
+ Send Message
394
+ </button>
395
+ </form>
396
+ </div>
397
+ </template>
398
+
399
+ <style module>
400
+ .contact-form {
401
+ max-width: 600px;
402
+ padding: 2rem;
403
+ border: 1px solid #e0e0e0;
404
+ border-radius: 0.5rem;
405
+ background-color: #fff;
406
+ }
407
+
408
+ .form-group {
409
+ margin-bottom: 1.5rem;
410
+ }
411
+
412
+ .form-group label {
413
+ display: block;
414
+ margin-bottom: 0.5rem;
415
+ font-weight: 500;
416
+ color: #333;
417
+ }
418
+
419
+ .form-group input,
420
+ .form-group textarea {
421
+ width: 100%;
422
+ padding: 0.75rem;
423
+ border: 1px solid #ddd;
424
+ border-radius: 0.25rem;
425
+ font-size: 1rem;
426
+ }
427
+
428
+ .form-group input:focus,
429
+ .form-group textarea:focus {
430
+ outline: none;
431
+ border-color: #007bff;
432
+ box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
433
+ }
434
+
435
+ .error-message {
436
+ color: #dc3545;
437
+ font-size: 0.875rem;
438
+ margin-top: 0.25rem;
439
+ }
440
+
441
+ .submit-button {
442
+ width: 100%;
443
+ padding: 0.75rem;
444
+ background-color: #007bff;
445
+ color: white;
446
+ border: none;
447
+ border-radius: 0.25rem;
448
+ font-size: 1rem;
449
+ cursor: pointer;
450
+ transition: background-color 0.2s;
451
+ }
452
+
453
+ .submit-button:hover:not(:disabled) {
454
+ background-color: #0056b3;
455
+ }
456
+
457
+ .submit-button:disabled {
458
+ background-color: #6c757d;
459
+ cursor: not-allowed;
460
+ }
461
+ </style>
462
+ ```
463
+
464
+ ### Different States
465
+
466
+ ```vue
467
+ <script setup lang="ts">
468
+ import { ref } from "vue";
469
+ import { InputPhone } from "@umbra-ui/core";
470
+
471
+ const normalPhone = ref("");
472
+ const disabledPhone = ref("(555) 123-4567");
473
+ const readonlyPhone = ref("+1 (555) 987-6543");
474
+ const errorPhone = ref("123");
475
+ </script>
476
+
477
+ <template>
478
+ <div class="states-example">
479
+ <h3>Input States</h3>
480
+
481
+ <div class="state-group">
482
+ <label>Normal State</label>
483
+ <InputPhone
484
+ v-model:value="normalPhone"
485
+ placeholder="Enter phone number"
486
+ state="normal"
487
+ />
488
+ </div>
489
+
490
+ <div class="state-group">
491
+ <label>Disabled State</label>
492
+ <InputPhone v-model:value="disabledPhone" state="disabled" />
493
+ </div>
494
+
495
+ <div class="state-group">
496
+ <label>Readonly State</label>
497
+ <InputPhone v-model:value="readonlyPhone" state="readonly" />
498
+ </div>
499
+
500
+ <div class="state-group">
501
+ <label>Error State (Invalid Number)</label>
502
+ <InputPhone
503
+ v-model:value="errorPhone"
504
+ placeholder="Enter valid phone number"
505
+ state="normal"
506
+ />
507
+ </div>
508
+ </div>
509
+ </template>
510
+
511
+ <style module>
512
+ .states-example {
513
+ max-width: 500px;
514
+ padding: 1.5rem;
515
+ border: 1px solid #e0e0e0;
516
+ border-radius: 0.5rem;
517
+ }
518
+
519
+ .state-group {
520
+ margin-bottom: 1.5rem;
521
+ }
522
+
523
+ .state-group label {
524
+ display: block;
525
+ margin-bottom: 0.5rem;
526
+ font-weight: 500;
527
+ color: #333;
528
+ }
529
+ </style>
530
+ ```
531
+
532
+ ### Country-Specific Examples
533
+
534
+ ```vue
535
+ <script setup lang="ts">
536
+ import { ref } from "vue";
537
+ import { InputPhone } from "@umbra-ui/core";
538
+
539
+ const usPhone = ref("");
540
+ const ukPhone = ref("");
541
+ const internationalPhone = ref("");
542
+
543
+ const handleUSPhone = (value: string) => {
544
+ usPhone.value = value;
545
+ };
546
+
547
+ const handleUKPhone = (value: string) => {
548
+ ukPhone.value = value;
549
+ };
550
+
551
+ const handleInternationalPhone = (value: string) => {
552
+ internationalPhone.value = value;
553
+ };
554
+ </script>
555
+
556
+ <template>
557
+ <div class="country-examples">
558
+ <h3>Country-Specific Formatting</h3>
559
+
560
+ <div class="country-group">
561
+ <h4>United States</h4>
562
+ <InputPhone
563
+ v-model:value="usPhone"
564
+ @update:value="handleUSPhone"
565
+ placeholder="Enter US phone number"
566
+ default-country="US"
567
+ :show-country-code="true"
568
+ />
569
+ <p class="format-info">Format: (555) 123-4567 or +1 (555) 123-4567</p>
570
+ </div>
571
+
572
+ <div class="country-group">
573
+ <h4>United Kingdom</h4>
574
+ <InputPhone
575
+ v-model:value="ukPhone"
576
+ @update:value="handleUKPhone"
577
+ placeholder="Enter UK phone number"
578
+ default-country="GB"
579
+ :show-country-code="true"
580
+ />
581
+ <p class="format-info">Format: 20 1234 5678 or +44 20 1234 5678</p>
582
+ </div>
583
+
584
+ <div class="country-group">
585
+ <h4>International</h4>
586
+ <InputPhone
587
+ v-model:value="internationalPhone"
588
+ @update:value="handleInternationalPhone"
589
+ placeholder="Enter international phone number"
590
+ default-country="US"
591
+ :allow-international="true"
592
+ :show-country-code="true"
593
+ />
594
+ <p class="format-info">Format: +[country code] [number]</p>
595
+ </div>
596
+ </div>
597
+ </template>
598
+
599
+ <style module>
600
+ .country-examples {
601
+ max-width: 600px;
602
+ padding: 1.5rem;
603
+ border: 1px solid #e0e0e0;
604
+ border-radius: 0.5rem;
605
+ }
606
+
607
+ .country-group {
608
+ margin-bottom: 2rem;
609
+ padding: 1rem;
610
+ border: 1px solid #f0f0f0;
611
+ border-radius: 0.25rem;
612
+ }
613
+
614
+ .country-group h4 {
615
+ margin: 0 0 1rem 0;
616
+ color: #333;
617
+ }
618
+
619
+ .format-info {
620
+ margin-top: 0.5rem;
621
+ font-size: 0.875rem;
622
+ color: #666;
623
+ font-style: italic;
624
+ }
625
+ </style>
626
+ ```
627
+
628
+ ## Technical Notes
629
+
630
+ - Phone number validation follows country-specific rules and E.164 international standard
631
+ - Automatic formatting preserves cursor position during input
632
+ - Supports paste operations with proper formatting and validation
633
+ - Input restrictions prevent non-digit characters except formatting symbols
634
+ - Responsive design prevents zoom on mobile devices with proper font sizing
635
+ - Error states are automatically triggered for invalid phone numbers
636
+ - Country detection works for US, UK, and generic international formats