@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
+ # InputCard
2
+
3
+ A specialized credit card number input component built with Vue 3 Composition API and TypeScript. The InputCard component provides automatic formatting, card type detection, validation using the Luhn algorithm, and visual feedback with card brand icons.
4
+
5
+ ## Installation/Import
6
+
7
+ ```typescript
8
+ import { InputCard } from "@umbra-ui/core";
9
+ ```
10
+
11
+ **Dependencies:**
12
+
13
+ - Vue 3.x
14
+ - @umbra-ui/icons (for card and validation icons)
15
+
16
+ ## Basic Usage
17
+
18
+ ```vue
19
+ <script setup lang="ts">
20
+ import { ref } from "vue";
21
+ import { InputCard } from "@umbra-ui/core";
22
+
23
+ const cardNumber = ref("");
24
+ const formattedCardNumber = ref("");
25
+ const cardType = ref("");
26
+ const isValid = ref(false);
27
+
28
+ const handleCardUpdate = (value: string) => {
29
+ console.log("Raw card number:", value);
30
+ cardNumber.value = value;
31
+ };
32
+
33
+ const handleFormattedUpdate = (formatted: string) => {
34
+ console.log("Formatted card number:", formatted);
35
+ formattedCardNumber.value = formatted;
36
+ };
37
+
38
+ const handleCardTypeUpdate = (type: string) => {
39
+ console.log("Card type:", type);
40
+ cardType.value = type;
41
+ };
42
+
43
+ const handleValidUpdate = (valid: boolean) => {
44
+ console.log("Is valid:", valid);
45
+ isValid.value = valid;
46
+ };
47
+ </script>
48
+
49
+ <template>
50
+ <div>
51
+ <InputCard
52
+ v-model:value="cardNumber"
53
+ placeholder="4242 4242 4242 4242"
54
+ :showCardType="true"
55
+ @update:value="handleCardUpdate"
56
+ @update:formatted="handleFormattedUpdate"
57
+ @update:cardType="handleCardTypeUpdate"
58
+ @update:valid="handleValidUpdate"
59
+ />
60
+
61
+ <div v-if="cardType" class="card-info">
62
+ <p>Card Type: {{ cardType }}</p>
63
+ <p>Valid: {{ isValid ? "Yes" : "No" }}</p>
64
+ </div>
65
+ </div>
66
+ </template>
67
+ ```
68
+
69
+ ## Props
70
+
71
+ | Prop Name | Type | Required | Default | Description |
72
+ | -------------- | ------------------------------------------------------------- | -------- | ----------------------- | ------------------------------------------- |
73
+ | `value` | `string` | No | `""` | The raw card number (digits only) |
74
+ | `placeholder` | `string` | No | `"4242 4242 4242 4242"` | Placeholder text displayed when empty |
75
+ | `showCardType` | `boolean` | No | `true` | Whether to show the detected card type icon |
76
+ | `state` | `"normal" \| "active" \| "disabled" \| "readonly" \| "error"` | No | `"normal"` | Current state of the input field |
77
+
78
+ ## Events
79
+
80
+ | Event Name | Payload Type | Description |
81
+ | ------------------ | ------------ | --------------------------------------------------------------------------------- |
82
+ | `update:value` | `string` | Emitted when the card number changes, returns raw digits only |
83
+ | `update:formatted` | `string` | Emitted when the card number changes, returns formatted display value |
84
+ | `update:cardType` | `string` | Emitted when the card type is detected, returns card brand name |
85
+ | `update:valid` | `boolean` | Emitted when validation state changes, returns true if card is complete and valid |
86
+
87
+ ## Slots
88
+
89
+ This component does not use slots.
90
+
91
+ ## Exposed Methods/Refs
92
+
93
+ This component does not expose any methods or refs.
94
+
95
+ ## Supported Card Types
96
+
97
+ The component automatically detects and supports the following card types:
98
+
99
+ - **Visa**: 4xxx (16 or 19 digits)
100
+ - **Mastercard**: 5[1-5]xxx or 2[2-7]xxx (16 digits)
101
+ - **American Express**: 3[47]xxx (15 digits)
102
+ - **Discover**: 6011xxx, 65xxx, or 64[4-9]xxx (16 digits)
103
+ - **Diners Club**: 36xxx, 38xxx, or 30[0-5]xxx (14 digits)
104
+ - **JCB**: 35xxx (16 digits)
105
+
106
+ ## CSS Customization
107
+
108
+ The InputCard component uses CSS custom properties for theming. It inherits from the general input theme:
109
+
110
+ ```css
111
+ /* Input colors */
112
+ --input-background-normal: #ffffff;
113
+ --input-background-filled: #f8f9fa;
114
+ --input-text-empty: #6c757d;
115
+ --input-text-filled: #212529;
116
+ --input-border: #ced4da;
117
+ --input-border-filled: #80bdff;
118
+ --input-focus-border: #007bff;
119
+ --input-placeholder: #6c757d;
120
+ --input-placeholder-filled: #adb5bd;
121
+
122
+ /* State-specific colors */
123
+ --input-disabled-bg: #e9ecef;
124
+ --input-disabled-text: #6c757d;
125
+ --input-disabled-border: #ced4da;
126
+ --input-disabled-placeholder: #adb5bd;
127
+
128
+ --input-readonly-bg: #f8f9fa;
129
+ --input-readonly-text: #495057;
130
+ --input-readonly-border: #ced4da;
131
+ --input-readonly-placeholder: #6c757d;
132
+
133
+ --input-error-bg: #f8d7da;
134
+ --input-error-text: #721c24;
135
+ --input-error-border: #dc3545;
136
+ --input-text-error: #dc3545;
137
+ ```
138
+
139
+ ## Examples
140
+
141
+ ### Basic Card Input
142
+
143
+ ```vue
144
+ <script setup lang="ts">
145
+ import { ref } from "vue";
146
+ import { InputCard } from "@umbra-ui/core";
147
+
148
+ const cardNumber = ref("");
149
+ </script>
150
+
151
+ <template>
152
+ <div class="card-form">
153
+ <h3>Payment Information</h3>
154
+
155
+ <div class="form-group">
156
+ <label>Card Number</label>
157
+ <InputCard
158
+ v-model:value="cardNumber"
159
+ placeholder="1234 5678 9012 3456"
160
+ :showCardType="true"
161
+ />
162
+ </div>
163
+ </div>
164
+ </template>
165
+
166
+ <style module>
167
+ .card-form {
168
+ max-width: 400px;
169
+ padding: 1.5rem;
170
+ border: 1px solid #e0e0e0;
171
+ border-radius: 8px;
172
+ }
173
+
174
+ .form-group {
175
+ margin-bottom: 1rem;
176
+ }
177
+
178
+ label {
179
+ display: block;
180
+ margin-bottom: 0.5rem;
181
+ font-weight: 500;
182
+ color: #333;
183
+ }
184
+ </style>
185
+ ```
186
+
187
+ ### Complete Payment Form
188
+
189
+ ```vue
190
+ <script setup lang="ts">
191
+ import { ref, computed } from "vue";
192
+ import { InputCard } from "@umbra-ui/core";
193
+
194
+ const paymentData = ref({
195
+ cardNumber: "",
196
+ cardType: "",
197
+ isValid: false,
198
+ expiryMonth: "",
199
+ expiryYear: "",
200
+ cvv: "",
201
+ cardholderName: "",
202
+ });
203
+
204
+ const canSubmit = computed(() => {
205
+ return (
206
+ paymentData.value.isValid &&
207
+ paymentData.value.expiryMonth &&
208
+ paymentData.value.expiryYear &&
209
+ paymentData.value.cvv &&
210
+ paymentData.value.cardholderName
211
+ );
212
+ });
213
+
214
+ const handleSubmit = () => {
215
+ if (canSubmit.value) {
216
+ console.log("Processing payment:", paymentData.value);
217
+ // Process payment logic here
218
+ }
219
+ };
220
+ </script>
221
+
222
+ <template>
223
+ <div class="payment-form">
224
+ <h3>Complete Payment</h3>
225
+
226
+ <form @submit.prevent="handleSubmit">
227
+ <div class="form-group">
228
+ <label>Card Number</label>
229
+ <InputCard
230
+ v-model:value="paymentData.cardNumber"
231
+ @update:cardType="paymentData.cardType = $event"
232
+ @update:valid="paymentData.isValid = $event"
233
+ placeholder="1234 5678 9012 3456"
234
+ />
235
+ <p v-if="paymentData.cardType" class="card-type">
236
+ Detected: {{ paymentData.cardType }}
237
+ </p>
238
+ </div>
239
+
240
+ <div class="form-row">
241
+ <div class="form-group">
242
+ <label>Expiry Month</label>
243
+ <select v-model="paymentData.expiryMonth" required>
244
+ <option value="">Month</option>
245
+ <option
246
+ v-for="month in 12"
247
+ :key="month"
248
+ :value="month.toString().padStart(2, '0')"
249
+ >
250
+ {{ month.toString().padStart(2, "0") }}
251
+ </option>
252
+ </select>
253
+ </div>
254
+
255
+ <div class="form-group">
256
+ <label>Expiry Year</label>
257
+ <select v-model="paymentData.expiryYear" required>
258
+ <option value="">Year</option>
259
+ <option
260
+ v-for="year in 10"
261
+ :key="year"
262
+ :value="(new Date().getFullYear() + year).toString()"
263
+ >
264
+ {{ new Date().getFullYear() + year }}
265
+ </option>
266
+ </select>
267
+ </div>
268
+
269
+ <div class="form-group">
270
+ <label>CVV</label>
271
+ <input
272
+ v-model="paymentData.cvv"
273
+ type="text"
274
+ placeholder="123"
275
+ maxlength="4"
276
+ pattern="[0-9]*"
277
+ inputmode="numeric"
278
+ required
279
+ />
280
+ </div>
281
+ </div>
282
+
283
+ <div class="form-group">
284
+ <label>Cardholder Name</label>
285
+ <input
286
+ v-model="paymentData.cardholderName"
287
+ type="text"
288
+ placeholder="John Doe"
289
+ required
290
+ />
291
+ </div>
292
+
293
+ <button type="submit" :disabled="!canSubmit">Process Payment</button>
294
+ </form>
295
+ </div>
296
+ </template>
297
+
298
+ <style module>
299
+ .payment-form {
300
+ max-width: 500px;
301
+ padding: 1.5rem;
302
+ border: 1px solid #e0e0e0;
303
+ border-radius: 8px;
304
+ }
305
+
306
+ .form-group {
307
+ margin-bottom: 1rem;
308
+ }
309
+
310
+ .form-row {
311
+ display: grid;
312
+ grid-template-columns: 1fr 1fr 1fr;
313
+ gap: 1rem;
314
+ }
315
+
316
+ label {
317
+ display: block;
318
+ margin-bottom: 0.5rem;
319
+ font-weight: 500;
320
+ color: #333;
321
+ }
322
+
323
+ input,
324
+ select {
325
+ width: 100%;
326
+ padding: 0.5rem;
327
+ border: 1px solid #ddd;
328
+ border-radius: 4px;
329
+ font-size: 1rem;
330
+ }
331
+
332
+ .card-type {
333
+ margin-top: 0.25rem;
334
+ font-size: 0.9rem;
335
+ color: #666;
336
+ }
337
+
338
+ button {
339
+ width: 100%;
340
+ padding: 0.75rem;
341
+ background-color: #007bff;
342
+ color: white;
343
+ border: none;
344
+ border-radius: 4px;
345
+ cursor: pointer;
346
+ font-size: 1rem;
347
+ }
348
+
349
+ button:disabled {
350
+ background-color: #ccc;
351
+ cursor: not-allowed;
352
+ }
353
+ </style>
354
+ ```
355
+
356
+ ### Different States
357
+
358
+ ```vue
359
+ <script setup lang="ts">
360
+ import { ref } from "vue";
361
+ import { InputCard } from "@umbra-ui/core";
362
+
363
+ const normalCard = ref("");
364
+ const disabledCard = ref("4242424242424242");
365
+ const readonlyCard = ref("5555555555554444");
366
+ const errorCard = ref("1234567890123456"); // Invalid card
367
+ </script>
368
+
369
+ <template>
370
+ <div class="states-example">
371
+ <h3>Input States</h3>
372
+
373
+ <div class="state-group">
374
+ <label>Normal State</label>
375
+ <InputCard
376
+ v-model:value="normalCard"
377
+ placeholder="Enter card number"
378
+ state="normal"
379
+ />
380
+ </div>
381
+
382
+ <div class="state-group">
383
+ <label>Disabled State</label>
384
+ <InputCard v-model:value="disabledCard" state="disabled" />
385
+ </div>
386
+
387
+ <div class="state-group">
388
+ <label>Readonly State</label>
389
+ <InputCard v-model:value="readonlyCard" state="readonly" />
390
+ </div>
391
+
392
+ <div class="state-group">
393
+ <label>Error State (Invalid Card)</label>
394
+ <InputCard v-model:value="errorCard" state="normal" />
395
+ </div>
396
+ </div>
397
+ </template>
398
+
399
+ <style module>
400
+ .states-example {
401
+ max-width: 500px;
402
+ padding: 1.5rem;
403
+ border: 1px solid #e0e0e0;
404
+ border-radius: 8px;
405
+ }
406
+
407
+ .state-group {
408
+ margin-bottom: 1.5rem;
409
+ }
410
+
411
+ label {
412
+ display: block;
413
+ margin-bottom: 0.5rem;
414
+ font-weight: 500;
415
+ color: #333;
416
+ }
417
+ </style>
418
+ ```
419
+
420
+ ### Card Type Detection Demo
421
+
422
+ ```vue
423
+ <script setup lang="ts">
424
+ import { ref } from "vue";
425
+ import { InputCard } from "@umbra-ui/core";
426
+
427
+ const testCards = ref([
428
+ { name: "Visa", number: "4111111111111111" },
429
+ { name: "Mastercard", number: "5555555555554444" },
430
+ { name: "American Express", number: "378282246310005" },
431
+ { name: "Discover", number: "6011111111111117" },
432
+ { name: "Diners Club", number: "30569309025904" },
433
+ { name: "JCB", number: "3530111333300000" },
434
+ ]);
435
+
436
+ const currentCard = ref("");
437
+ const detectedType = ref("");
438
+ const isValid = ref(false);
439
+
440
+ const testCard = (cardNumber: string) => {
441
+ currentCard.value = cardNumber;
442
+ };
443
+ </script>
444
+
445
+ <template>
446
+ <div class="detection-demo">
447
+ <h3>Card Type Detection</h3>
448
+
449
+ <div class="demo-input">
450
+ <InputCard
451
+ v-model:value="currentCard"
452
+ @update:cardType="detectedType = $event"
453
+ @update:valid="isValid = $event"
454
+ placeholder="Enter or test a card number"
455
+ />
456
+
457
+ <div v-if="detectedType || isValid !== null" class="detection-info">
458
+ <p><strong>Detected Type:</strong> {{ detectedType || "Unknown" }}</p>
459
+ <p><strong>Valid:</strong> {{ isValid ? "Yes" : "No" }}</p>
460
+ </div>
461
+ </div>
462
+
463
+ <div class="test-cards">
464
+ <h4>Test Cards</h4>
465
+ <div class="card-buttons">
466
+ <button
467
+ v-for="card in testCards"
468
+ :key="card.name"
469
+ @click="testCard(card.number)"
470
+ class="test-button"
471
+ >
472
+ {{ card.name }}
473
+ </button>
474
+ </div>
475
+ </div>
476
+ </div>
477
+ </template>
478
+
479
+ <style module>
480
+ .detection-demo {
481
+ max-width: 600px;
482
+ padding: 1.5rem;
483
+ border: 1px solid #e0e0e0;
484
+ border-radius: 8px;
485
+ }
486
+
487
+ .demo-input {
488
+ margin-bottom: 2rem;
489
+ }
490
+
491
+ .detection-info {
492
+ margin-top: 1rem;
493
+ padding: 1rem;
494
+ background-color: #f8f9fa;
495
+ border-radius: 4px;
496
+ }
497
+
498
+ .detection-info p {
499
+ margin: 0.25rem 0;
500
+ }
501
+
502
+ .test-cards h4 {
503
+ margin-bottom: 1rem;
504
+ color: #333;
505
+ }
506
+
507
+ .card-buttons {
508
+ display: grid;
509
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
510
+ gap: 0.5rem;
511
+ }
512
+
513
+ .test-button {
514
+ padding: 0.5rem;
515
+ background-color: #6c757d;
516
+ color: white;
517
+ border: none;
518
+ border-radius: 4px;
519
+ cursor: pointer;
520
+ font-size: 0.9rem;
521
+ }
522
+
523
+ .test-button:hover {
524
+ background-color: #5a6268;
525
+ }
526
+ </style>
527
+ ```
528
+
529
+ ### Validation Feedback
530
+
531
+ ```vue
532
+ <script setup lang="ts">
533
+ import { ref, computed } from "vue";
534
+ import { InputCard } from "@umbra-ui/core";
535
+
536
+ const cardNumber = ref("");
537
+ const isValid = ref(false);
538
+ const isComplete = ref(false);
539
+
540
+ const validationMessage = computed(() => {
541
+ if (!isComplete.value) {
542
+ return "Enter your card number";
543
+ }
544
+ if (!isValid.value) {
545
+ return "Please enter a valid card number";
546
+ }
547
+ return "Card number is valid";
548
+ });
549
+
550
+ const validationClass = computed(() => {
551
+ if (!isComplete.value) return "neutral";
552
+ return isValid.value ? "valid" : "invalid";
553
+ });
554
+ </script>
555
+
556
+ <template>
557
+ <div class="validation-example">
558
+ <h3>Validation Feedback</h3>
559
+
560
+ <div class="form-group">
561
+ <label>Card Number</label>
562
+ <InputCard
563
+ v-model:value="cardNumber"
564
+ @update:valid="
565
+ (valid) => {
566
+ isValid = valid;
567
+ isComplete = cardNumber.length > 0;
568
+ }
569
+ "
570
+ placeholder="1234 5678 9012 3456"
571
+ />
572
+
573
+ <div :class="['validation-message', validationClass]">
574
+ {{ validationMessage }}
575
+ </div>
576
+ </div>
577
+ </div>
578
+ </template>
579
+
580
+ <style module>
581
+ .validation-example {
582
+ max-width: 400px;
583
+ padding: 1.5rem;
584
+ border: 1px solid #e0e0e0;
585
+ border-radius: 8px;
586
+ }
587
+
588
+ .form-group {
589
+ margin-bottom: 1rem;
590
+ }
591
+
592
+ label {
593
+ display: block;
594
+ margin-bottom: 0.5rem;
595
+ font-weight: 500;
596
+ color: #333;
597
+ }
598
+
599
+ .validation-message {
600
+ margin-top: 0.5rem;
601
+ padding: 0.5rem;
602
+ border-radius: 4px;
603
+ font-size: 0.9rem;
604
+ }
605
+
606
+ .validation-message.neutral {
607
+ background-color: #e9ecef;
608
+ color: #6c757d;
609
+ }
610
+
611
+ .validation-message.valid {
612
+ background-color: #d4edda;
613
+ color: #155724;
614
+ }
615
+
616
+ .validation-message.invalid {
617
+ background-color: #f8d7da;
618
+ color: #721c24;
619
+ }
620
+ </style>
621
+ ```
622
+
623
+ ## Notes
624
+
625
+ - The component automatically formats card numbers with appropriate spacing based on the detected card type
626
+ - Card validation uses the Luhn algorithm for accurate validation
627
+ - The component prevents non-numeric input and enforces maximum length limits per card type
628
+ - Card type detection happens in real-time as the user types
629
+ - The component includes smooth animations for card type icons and error states
630
+ - Visual feedback includes card brand icons and validation error indicators
631
+ - The component supports paste operations with automatic formatting
632
+ - All major credit card types are supported with their specific formatting rules
633
+ - The component is fully accessible with proper ARIA attributes and keyboard navigation
634
+ - Error states are automatically triggered when a complete but invalid card number is entered
635
+ - The component includes responsive design considerations for mobile devices
636
+ - Input is restricted to numeric characters only with proper input mode settings