@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,771 @@
1
+ # InputSecure
2
+
3
+ A comprehensive password input component built with Vue 3 Composition API and TypeScript. The InputSecure component provides password visibility toggle, strength validation, requirement checking, secure password generation, and copy functionality with smooth animations and accessibility features.
4
+
5
+ ## Installation/Import
6
+
7
+ ```typescript
8
+ import { InputSecure } from "@umbra-ui/core";
9
+ ```
10
+
11
+ **Dependencies:**
12
+
13
+ - Vue 3.x
14
+ - @umbra-ui/icons (for eye, eye-slash, clone, and password edit icons)
15
+
16
+ ## Basic Usage
17
+
18
+ ```vue
19
+ <script setup lang="ts">
20
+ import { ref } from "vue";
21
+ import { InputSecure } from "@umbra-ui/core";
22
+
23
+ const password = ref("");
24
+
25
+ const handlePasswordUpdate = (value: string) => {
26
+ console.log("Password:", value);
27
+ password.value = value;
28
+ };
29
+
30
+ const handleValidUpdate = (isValid: boolean) => {
31
+ console.log("Valid:", isValid);
32
+ };
33
+
34
+ const handleStrengthUpdate = (strength: number) => {
35
+ console.log("Strength:", strength);
36
+ };
37
+ </script>
38
+
39
+ <template>
40
+ <div>
41
+ <InputSecure
42
+ v-model:value="password"
43
+ @update:valid="handleValidUpdate"
44
+ @update:strength="handleStrengthUpdate"
45
+ placeholder="Enter password"
46
+ :show-strength="true"
47
+ :allow-generate="true"
48
+ :show-requirements="true"
49
+ />
50
+ </div>
51
+ </template>
52
+ ```
53
+
54
+ ## Props
55
+
56
+ | Prop Name | Type | Required | Default | Description |
57
+ | --------------------- | ------------------------------------------------------------- | -------- | ------------------ | ------------------------------------------- |
58
+ | `value` | `string` | No | `""` | The password value |
59
+ | `placeholder` | `string` | No | `"Enter password"` | Placeholder text displayed when empty |
60
+ | `showStrength` | `boolean` | No | `true` | Whether to show password strength indicator |
61
+ | `allowGenerate` | `boolean` | No | `true` | Whether to show password generation button |
62
+ | `showRequirements` | `boolean` | No | `true` | Whether to show password requirements list |
63
+ | `minLength` | `number` | No | `8` | Minimum password length |
64
+ | `requireUppercase` | `boolean` | No | `true` | Whether to require uppercase letters |
65
+ | `requireLowercase` | `boolean` | No | `true` | Whether to require lowercase letters |
66
+ | `requireNumbers` | `boolean` | No | `true` | Whether to require numbers |
67
+ | `requireSpecialChars` | `boolean` | No | `true` | Whether to require special characters |
68
+ | `preventCommon` | `boolean` | No | `true` | Whether to prevent common passwords |
69
+ | `state` | `"normal" \| "active" \| "disabled" \| "readonly" \| "error"` | No | `"normal"` | Current state of the input field |
70
+
71
+ ## Events
72
+
73
+ | Event Name | Payload Type | Description |
74
+ | ----------------- | ------------ | ------------------------------------------------ |
75
+ | `update:value` | `string` | Emitted when the password value changes |
76
+ | `update:valid` | `boolean` | Emitted when the validation state changes |
77
+ | `update:strength` | `number` | Emitted when the password strength changes (0-4) |
78
+
79
+ ## Slots
80
+
81
+ This component does not provide any slots.
82
+
83
+ ## Exposed Methods/Refs
84
+
85
+ This component does not expose any methods or refs.
86
+
87
+ ## CSS Customization
88
+
89
+ The InputSecure component uses CSS custom properties for theming and customization:
90
+
91
+ ### Input Container Variables
92
+
93
+ ```css
94
+ --input-border: 1px solid var(--input-border-color);
95
+ --input-border-radius: 0.588rem;
96
+ --input-focus-border: var(--input-focus-color);
97
+ --input-background-normal: var(--input-bg-normal);
98
+ --input-background-filled: var(--input-bg-filled);
99
+ --input-border-filled: var(--input-border-filled-color);
100
+ --input-text-empty: var(--input-text-empty-color);
101
+ --input-text-filled: var(--input-text-filled-color);
102
+ --input-placeholder: var(--input-placeholder-color);
103
+ --input-placeholder-filled: var(--input-placeholder-filled-color);
104
+ ```
105
+
106
+ ### State-Specific Variables
107
+
108
+ ```css
109
+ /* Disabled State */
110
+ --input-disabled-bg: var(--input-disabled-background);
111
+ --input-disabled-text: var(--input-disabled-text-color);
112
+ --input-disabled-border: var(--input-disabled-border-color);
113
+ --input-disabled-placeholder: var(--input-disabled-placeholder-color);
114
+
115
+ /* Readonly State */
116
+ --input-readonly-bg: var(--input-readonly-background);
117
+ --input-readonly-text: var(--input-readonly-text-color);
118
+ --input-readonly-border: var(--input-readonly-border-color);
119
+ --input-readonly-placeholder: var(--input-readonly-placeholder-color);
120
+
121
+ /* Error State */
122
+ --input-error-bg: var(--input-error-background);
123
+ --input-error-text: var(--input-error-text-color);
124
+ --input-error-border: var(--input-error-border-color);
125
+
126
+ /* Success State */
127
+ --input-success-color: var(--input-success-text-color);
128
+ ```
129
+
130
+ ## Key Features
131
+
132
+ ### Password Visibility
133
+
134
+ - **Toggle Visibility**: Show/hide password with eye icon toggle
135
+ - **Secure by Default**: Password is hidden by default
136
+ - **Accessibility**: Proper ARIA labels and keyboard navigation
137
+
138
+ ### Password Strength
139
+
140
+ - **Real-time Assessment**: Calculates strength as user types (0-4 scale)
141
+ - **Visual Indicator**: Color-coded strength bar with labels
142
+ - **Strength Levels**: Very Weak, Weak, Fair, Good, Strong
143
+ - **Multiple Factors**: Length, character variety, pattern detection
144
+
145
+ ### Password Requirements
146
+
147
+ - **Configurable Rules**: Customizable password requirements
148
+ - **Real-time Validation**: Shows requirement status as user types
149
+ - **Visual Feedback**: Checkmarks for met requirements
150
+ - **Common Password Prevention**: Blocks common weak passwords
151
+
152
+ ### Password Generation
153
+
154
+ - **Secure Generation**: Creates cryptographically secure passwords
155
+ - **Requirement Compliance**: Generated passwords meet all requirements
156
+ - **Customizable Length**: Respects minimum length and requirements
157
+ - **Character Variety**: Includes all required character types
158
+
159
+ ### Additional Features
160
+
161
+ - **Copy to Clipboard**: One-click password copying
162
+ - **Input States**: Normal, disabled, readonly, error states
163
+ - **Responsive Design**: Mobile-friendly with proper font scaling
164
+ - **Smooth Animations**: Transitions for requirements and strength indicators
165
+
166
+ ## Examples
167
+
168
+ ### Basic Password Input
169
+
170
+ ```vue
171
+ <script setup lang="ts">
172
+ import { ref } from "vue";
173
+ import { InputSecure } from "@umbra-ui/core";
174
+
175
+ const password = ref("");
176
+ const isValid = ref(false);
177
+ const strength = ref(0);
178
+
179
+ const handleValidUpdate = (valid: boolean) => {
180
+ isValid.value = valid;
181
+ };
182
+
183
+ const handleStrengthUpdate = (strengthValue: number) => {
184
+ strength.value = strengthValue;
185
+ };
186
+ </script>
187
+
188
+ <template>
189
+ <div class="password-form">
190
+ <h3>Create Account</h3>
191
+
192
+ <div class="form-group">
193
+ <label>Password</label>
194
+ <InputSecure
195
+ v-model:value="password"
196
+ @update:valid="handleValidUpdate"
197
+ @update:strength="handleStrengthUpdate"
198
+ placeholder="Enter your password"
199
+ :show-strength="true"
200
+ :allow-generate="true"
201
+ :show-requirements="true"
202
+ />
203
+ </div>
204
+
205
+ <div class="password-info">
206
+ <p><strong>Valid:</strong> {{ isValid ? "Yes" : "No" }}</p>
207
+ <p><strong>Strength:</strong> {{ strength }}/4</p>
208
+ </div>
209
+ </div>
210
+ </template>
211
+
212
+ <style module>
213
+ .password-form {
214
+ max-width: 400px;
215
+ padding: 1.5rem;
216
+ border: 1px solid #e0e0e0;
217
+ border-radius: 0.5rem;
218
+ }
219
+
220
+ .form-group {
221
+ margin-bottom: 1rem;
222
+ }
223
+
224
+ .form-group label {
225
+ display: block;
226
+ margin-bottom: 0.5rem;
227
+ font-weight: 500;
228
+ }
229
+
230
+ .password-info {
231
+ margin-top: 1rem;
232
+ padding: 1rem;
233
+ background-color: #f5f5f5;
234
+ border-radius: 0.25rem;
235
+ }
236
+ </style>
237
+ ```
238
+
239
+ ### Custom Requirements
240
+
241
+ ```vue
242
+ <script setup lang="ts">
243
+ import { ref } from "vue";
244
+ import { InputSecure } from "@umbra-ui/core";
245
+
246
+ const customPassword = ref("");
247
+
248
+ const handleCustomValid = (valid: boolean) => {
249
+ console.log("Custom password valid:", valid);
250
+ };
251
+ </script>
252
+
253
+ <template>
254
+ <div class="custom-requirements">
255
+ <h3>Custom Password Requirements</h3>
256
+
257
+ <div class="form-group">
258
+ <label>Password (Min 12 chars, no special chars required)</label>
259
+ <InputSecure
260
+ v-model:value="customPassword"
261
+ @update:valid="handleCustomValid"
262
+ placeholder="Enter password"
263
+ :min-length="12"
264
+ :require-uppercase="true"
265
+ :require-lowercase="true"
266
+ :require-numbers="true"
267
+ :require-special-chars="false"
268
+ :prevent-common="true"
269
+ :show-strength="true"
270
+ :show-requirements="true"
271
+ />
272
+ </div>
273
+
274
+ <div class="requirements-info">
275
+ <h4>Custom Requirements:</h4>
276
+ <ul>
277
+ <li>At least 12 characters</li>
278
+ <li>One uppercase letter</li>
279
+ <li>One lowercase letter</li>
280
+ <li>One number</li>
281
+ <li>Not a common password</li>
282
+ </ul>
283
+ </div>
284
+ </div>
285
+ </template>
286
+
287
+ <style module>
288
+ .custom-requirements {
289
+ max-width: 500px;
290
+ padding: 1.5rem;
291
+ border: 1px solid #e0e0e0;
292
+ border-radius: 0.5rem;
293
+ }
294
+
295
+ .form-group {
296
+ margin-bottom: 1.5rem;
297
+ }
298
+
299
+ .form-group label {
300
+ display: block;
301
+ margin-bottom: 0.5rem;
302
+ font-weight: 500;
303
+ }
304
+
305
+ .requirements-info {
306
+ padding: 1rem;
307
+ background-color: #f8f9fa;
308
+ border-radius: 0.25rem;
309
+ }
310
+
311
+ .requirements-info h4 {
312
+ margin: 0 0 0.5rem 0;
313
+ color: #333;
314
+ }
315
+
316
+ .requirements-info ul {
317
+ margin: 0;
318
+ padding-left: 1.5rem;
319
+ }
320
+
321
+ .requirements-info li {
322
+ margin-bottom: 0.25rem;
323
+ color: #666;
324
+ }
325
+ </style>
326
+ ```
327
+
328
+ ### Registration Form Integration
329
+
330
+ ```vue
331
+ <script setup lang="ts">
332
+ import { ref, computed } from "vue";
333
+ import { InputSecure } from "@umbra-ui/core";
334
+
335
+ interface RegistrationForm {
336
+ username: string;
337
+ email: string;
338
+ password: string;
339
+ confirmPassword: string;
340
+ }
341
+
342
+ const form = ref<RegistrationForm>({
343
+ username: "",
344
+ email: "",
345
+ password: "",
346
+ confirmPassword: "",
347
+ });
348
+
349
+ const passwordValid = ref(false);
350
+ const passwordsMatch = ref(false);
351
+
352
+ const isFormValid = computed(() => {
353
+ return (
354
+ form.value.username &&
355
+ form.value.email &&
356
+ form.value.password &&
357
+ passwordValid.value &&
358
+ passwordsMatch.value
359
+ );
360
+ });
361
+
362
+ const handlePasswordValid = (valid: boolean) => {
363
+ passwordValid.value = valid;
364
+ };
365
+
366
+ const handlePasswordChange = (password: string) => {
367
+ form.value.password = password;
368
+ passwordsMatch.value = password === form.value.confirmPassword;
369
+ };
370
+
371
+ const handleConfirmPasswordChange = (confirmPassword: string) => {
372
+ form.value.confirmPassword = confirmPassword;
373
+ passwordsMatch.value = form.value.password === confirmPassword;
374
+ };
375
+
376
+ const handleSubmit = () => {
377
+ if (isFormValid.value) {
378
+ console.log("Registration submitted:", form.value);
379
+ // Handle form submission
380
+ }
381
+ };
382
+ </script>
383
+
384
+ <template>
385
+ <div class="registration-form">
386
+ <h3>Create Account</h3>
387
+
388
+ <form @submit.prevent="handleSubmit">
389
+ <div class="form-group">
390
+ <label>Username *</label>
391
+ <input
392
+ v-model="form.username"
393
+ type="text"
394
+ placeholder="Choose a username"
395
+ required
396
+ />
397
+ </div>
398
+
399
+ <div class="form-group">
400
+ <label>Email *</label>
401
+ <input
402
+ v-model="form.email"
403
+ type="email"
404
+ placeholder="your@email.com"
405
+ required
406
+ />
407
+ </div>
408
+
409
+ <div class="form-group">
410
+ <label>Password *</label>
411
+ <InputSecure
412
+ v-model:value="form.password"
413
+ @update:value="handlePasswordChange"
414
+ @update:valid="handlePasswordValid"
415
+ placeholder="Create a password"
416
+ :show-strength="true"
417
+ :allow-generate="true"
418
+ :show-requirements="true"
419
+ />
420
+ </div>
421
+
422
+ <div class="form-group">
423
+ <label>Confirm Password *</label>
424
+ <InputSecure
425
+ v-model:value="form.confirmPassword"
426
+ @update:value="handleConfirmPasswordChange"
427
+ placeholder="Confirm your password"
428
+ :show-strength="false"
429
+ :allow-generate="false"
430
+ :show-requirements="false"
431
+ />
432
+ <div
433
+ v-if="form.confirmPassword && !passwordsMatch"
434
+ class="error-message"
435
+ >
436
+ Passwords do not match
437
+ </div>
438
+ </div>
439
+
440
+ <button type="submit" :disabled="!isFormValid" class="submit-button">
441
+ Create Account
442
+ </button>
443
+ </form>
444
+ </div>
445
+ </template>
446
+
447
+ <style module>
448
+ .registration-form {
449
+ max-width: 500px;
450
+ padding: 2rem;
451
+ border: 1px solid #e0e0e0;
452
+ border-radius: 0.5rem;
453
+ background-color: #fff;
454
+ }
455
+
456
+ .form-group {
457
+ margin-bottom: 1.5rem;
458
+ }
459
+
460
+ .form-group label {
461
+ display: block;
462
+ margin-bottom: 0.5rem;
463
+ font-weight: 500;
464
+ color: #333;
465
+ }
466
+
467
+ .form-group input {
468
+ width: 100%;
469
+ padding: 0.75rem;
470
+ border: 1px solid #ddd;
471
+ border-radius: 0.25rem;
472
+ font-size: 1rem;
473
+ }
474
+
475
+ .form-group input:focus {
476
+ outline: none;
477
+ border-color: #007bff;
478
+ box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
479
+ }
480
+
481
+ .error-message {
482
+ color: #dc3545;
483
+ font-size: 0.875rem;
484
+ margin-top: 0.25rem;
485
+ }
486
+
487
+ .submit-button {
488
+ width: 100%;
489
+ padding: 0.75rem;
490
+ background-color: #007bff;
491
+ color: white;
492
+ border: none;
493
+ border-radius: 0.25rem;
494
+ font-size: 1rem;
495
+ cursor: pointer;
496
+ transition: background-color 0.2s;
497
+ }
498
+
499
+ .submit-button:hover:not(:disabled) {
500
+ background-color: #0056b3;
501
+ }
502
+
503
+ .submit-button:disabled {
504
+ background-color: #6c757d;
505
+ cursor: not-allowed;
506
+ }
507
+ </style>
508
+ ```
509
+
510
+ ### Different States
511
+
512
+ ```vue
513
+ <script setup lang="ts">
514
+ import { ref } from "vue";
515
+ import { InputSecure } from "@umbra-ui/core";
516
+
517
+ const normalPassword = ref("");
518
+ const disabledPassword = ref("password123");
519
+ const readonlyPassword = ref("readonly123");
520
+ const errorPassword = ref("weak");
521
+ </script>
522
+
523
+ <template>
524
+ <div class="states-example">
525
+ <h3>Input States</h3>
526
+
527
+ <div class="state-group">
528
+ <label>Normal State</label>
529
+ <InputSecure
530
+ v-model:value="normalPassword"
531
+ placeholder="Enter password"
532
+ state="normal"
533
+ :show-strength="true"
534
+ :show-requirements="true"
535
+ />
536
+ </div>
537
+
538
+ <div class="state-group">
539
+ <label>Disabled State</label>
540
+ <InputSecure
541
+ v-model:value="disabledPassword"
542
+ state="disabled"
543
+ :show-strength="false"
544
+ :show-requirements="false"
545
+ />
546
+ </div>
547
+
548
+ <div class="state-group">
549
+ <label>Readonly State</label>
550
+ <InputSecure
551
+ v-model:value="readonlyPassword"
552
+ state="readonly"
553
+ :show-strength="false"
554
+ :show-requirements="false"
555
+ />
556
+ </div>
557
+
558
+ <div class="state-group">
559
+ <label>Error State (Weak Password)</label>
560
+ <InputSecure
561
+ v-model:value="errorPassword"
562
+ placeholder="Enter strong password"
563
+ state="normal"
564
+ :show-strength="true"
565
+ :show-requirements="true"
566
+ />
567
+ </div>
568
+ </div>
569
+ </template>
570
+
571
+ <style module>
572
+ .states-example {
573
+ max-width: 500px;
574
+ padding: 1.5rem;
575
+ border: 1px solid #e0e0e0;
576
+ border-radius: 0.5rem;
577
+ }
578
+
579
+ .state-group {
580
+ margin-bottom: 1.5rem;
581
+ }
582
+
583
+ .state-group label {
584
+ display: block;
585
+ margin-bottom: 0.5rem;
586
+ font-weight: 500;
587
+ color: #333;
588
+ }
589
+ </style>
590
+ ```
591
+
592
+ ### Password Manager Integration
593
+
594
+ ```vue
595
+ <script setup lang="ts">
596
+ import { ref, computed } from "vue";
597
+ import { InputSecure } from "@umbra-ui/core";
598
+
599
+ const masterPassword = ref("");
600
+ const generatedPasswords = ref<string[]>([]);
601
+
602
+ const handleMasterPasswordValid = (valid: boolean) => {
603
+ console.log("Master password valid:", valid);
604
+ };
605
+
606
+ const generateNewPassword = () => {
607
+ // This would typically call a password generation service
608
+ const newPassword = "Generated" + Math.random().toString(36).substr(2, 9);
609
+ generatedPasswords.value.push(newPassword);
610
+ };
611
+
612
+ const copyPassword = async (password: string) => {
613
+ try {
614
+ await navigator.clipboard.writeText(password);
615
+ console.log("Password copied to clipboard");
616
+ } catch (err) {
617
+ console.error("Failed to copy password");
618
+ }
619
+ };
620
+ </script>
621
+
622
+ <template>
623
+ <div class="password-manager">
624
+ <h3>Password Manager</h3>
625
+
626
+ <div class="master-password-section">
627
+ <h4>Master Password</h4>
628
+ <InputSecure
629
+ v-model:value="masterPassword"
630
+ @update:valid="handleMasterPasswordValid"
631
+ placeholder="Enter master password"
632
+ :show-strength="true"
633
+ :allow-generate="false"
634
+ :show-requirements="true"
635
+ :min-length="12"
636
+ />
637
+ </div>
638
+
639
+ <div class="generated-passwords-section">
640
+ <div class="section-header">
641
+ <h4>Generated Passwords</h4>
642
+ <button @click="generateNewPassword" class="generate-btn">
643
+ Generate New
644
+ </button>
645
+ </div>
646
+
647
+ <div v-if="generatedPasswords.length === 0" class="empty-state">
648
+ <p>No passwords generated yet</p>
649
+ </div>
650
+
651
+ <div v-else class="password-list">
652
+ <div
653
+ v-for="(password, index) in generatedPasswords"
654
+ :key="index"
655
+ class="password-item"
656
+ >
657
+ <InputSecure
658
+ v-model:value="generatedPasswords[index]"
659
+ :show-strength="false"
660
+ :allow-generate="false"
661
+ :show-requirements="false"
662
+ state="readonly"
663
+ />
664
+ <button
665
+ @click="copyPassword(password)"
666
+ class="copy-btn"
667
+ title="Copy password"
668
+ >
669
+ Copy
670
+ </button>
671
+ </div>
672
+ </div>
673
+ </div>
674
+ </div>
675
+ </template>
676
+
677
+ <style module>
678
+ .password-manager {
679
+ max-width: 600px;
680
+ padding: 1.5rem;
681
+ border: 1px solid #e0e0e0;
682
+ border-radius: 0.5rem;
683
+ }
684
+
685
+ .master-password-section {
686
+ margin-bottom: 2rem;
687
+ padding: 1rem;
688
+ border: 1px solid #f0f0f0;
689
+ border-radius: 0.25rem;
690
+ }
691
+
692
+ .master-password-section h4 {
693
+ margin: 0 0 1rem 0;
694
+ color: #333;
695
+ }
696
+
697
+ .generated-passwords-section h4 {
698
+ margin: 0 0 1rem 0;
699
+ color: #333;
700
+ }
701
+
702
+ .section-header {
703
+ display: flex;
704
+ justify-content: space-between;
705
+ align-items: center;
706
+ margin-bottom: 1rem;
707
+ }
708
+
709
+ .generate-btn {
710
+ padding: 0.5rem 1rem;
711
+ background-color: #28a745;
712
+ color: white;
713
+ border: none;
714
+ border-radius: 0.25rem;
715
+ cursor: pointer;
716
+ font-size: 0.875rem;
717
+ }
718
+
719
+ .generate-btn:hover {
720
+ background-color: #218838;
721
+ }
722
+
723
+ .empty-state {
724
+ text-align: center;
725
+ padding: 2rem;
726
+ color: #666;
727
+ font-style: italic;
728
+ }
729
+
730
+ .password-list {
731
+ display: flex;
732
+ flex-direction: column;
733
+ gap: 0.75rem;
734
+ }
735
+
736
+ .password-item {
737
+ display: flex;
738
+ align-items: center;
739
+ gap: 0.75rem;
740
+ padding: 0.75rem;
741
+ border: 1px solid #f0f0f0;
742
+ border-radius: 0.25rem;
743
+ }
744
+
745
+ .copy-btn {
746
+ padding: 0.5rem 0.75rem;
747
+ background-color: #007bff;
748
+ color: white;
749
+ border: none;
750
+ border-radius: 0.25rem;
751
+ cursor: pointer;
752
+ font-size: 0.875rem;
753
+ flex-shrink: 0;
754
+ }
755
+
756
+ .copy-btn:hover {
757
+ background-color: #0056b3;
758
+ }
759
+ </style>
760
+ ```
761
+
762
+ ## Technical Notes
763
+
764
+ - Password strength calculation considers length, character variety, and pattern detection
765
+ - Common password prevention uses a curated list of weak passwords
766
+ - Password generation creates cryptographically secure passwords meeting all requirements
767
+ - Copy functionality uses the modern Clipboard API with fallback handling
768
+ - Input states provide proper accessibility and visual feedback
769
+ - Responsive design prevents zoom on mobile devices with proper font sizing
770
+ - Requirements list shows/hides based on focus state and validation status
771
+ - Strength indicator updates in real-time with smooth color transitions