@cloud-ru/ds-fields 1.0.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 (314) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +201 -0
  3. package/README.md +888 -0
  4. package/dist/cjs/components/FieldColor/FieldColor.d.ts +48 -0
  5. package/dist/cjs/components/FieldColor/FieldColor.js +147 -0
  6. package/dist/cjs/components/FieldColor/index.d.ts +1 -0
  7. package/dist/cjs/components/FieldColor/index.js +17 -0
  8. package/dist/cjs/components/FieldColor/styles.module.css +79 -0
  9. package/dist/cjs/components/FieldColor/utils.d.ts +7 -0
  10. package/dist/cjs/components/FieldColor/utils.js +19 -0
  11. package/dist/cjs/components/FieldCombo/FieldCombo.d.ts +91 -0
  12. package/dist/cjs/components/FieldCombo/FieldCombo.js +200 -0
  13. package/dist/cjs/components/FieldCombo/index.d.ts +1 -0
  14. package/dist/cjs/components/FieldCombo/index.js +17 -0
  15. package/dist/cjs/components/FieldDate/FieldDate.d.ts +2 -0
  16. package/dist/cjs/components/FieldDate/FieldDate.js +369 -0
  17. package/dist/cjs/components/FieldDate/constants.d.ts +10 -0
  18. package/dist/cjs/components/FieldDate/constants.js +13 -0
  19. package/dist/cjs/components/FieldDate/index.d.ts +3 -0
  20. package/dist/cjs/components/FieldDate/index.js +19 -0
  21. package/dist/cjs/components/FieldDate/mask.d.ts +20 -0
  22. package/dist/cjs/components/FieldDate/mask.js +117 -0
  23. package/dist/cjs/components/FieldDate/styles.module.css +43 -0
  24. package/dist/cjs/components/FieldDate/types.d.ts +100 -0
  25. package/dist/cjs/components/FieldDate/types.js +2 -0
  26. package/dist/cjs/components/FieldDate/utils.d.ts +3 -0
  27. package/dist/cjs/components/FieldDate/utils.js +8 -0
  28. package/dist/cjs/components/FieldSecure/FieldSecure.d.ts +64 -0
  29. package/dist/cjs/components/FieldSecure/FieldSecure.js +158 -0
  30. package/dist/cjs/components/FieldSecure/index.d.ts +1 -0
  31. package/dist/cjs/components/FieldSecure/index.js +17 -0
  32. package/dist/cjs/components/FieldSelect/FieldSelect.d.ts +2 -0
  33. package/dist/cjs/components/FieldSelect/FieldSelect.js +360 -0
  34. package/dist/cjs/components/FieldSelect/constants.d.ts +4 -0
  35. package/dist/cjs/components/FieldSelect/constants.js +7 -0
  36. package/dist/cjs/components/FieldSelect/index.d.ts +3 -0
  37. package/dist/cjs/components/FieldSelect/index.js +19 -0
  38. package/dist/cjs/components/FieldSelect/styles.module.css +92 -0
  39. package/dist/cjs/components/FieldSelect/types.d.ts +197 -0
  40. package/dist/cjs/components/FieldSelect/types.js +2 -0
  41. package/dist/cjs/components/FieldSelect/utils.d.ts +19 -0
  42. package/dist/cjs/components/FieldSelect/utils.js +104 -0
  43. package/dist/cjs/components/FieldSlider/FieldSlider.d.ts +92 -0
  44. package/dist/cjs/components/FieldSlider/FieldSlider.js +196 -0
  45. package/dist/cjs/components/FieldSlider/index.d.ts +2 -0
  46. package/dist/cjs/components/FieldSlider/index.js +18 -0
  47. package/dist/cjs/components/FieldSlider/styles.module.css +44 -0
  48. package/dist/cjs/components/FieldSlider/types.d.ts +4 -0
  49. package/dist/cjs/components/FieldSlider/types.js +2 -0
  50. package/dist/cjs/components/FieldSlider/utils/generateAllowedValues.d.ts +1 -0
  51. package/dist/cjs/components/FieldSlider/utils/generateAllowedValues.js +16 -0
  52. package/dist/cjs/components/FieldSlider/utils/getClosestMark.d.ts +4 -0
  53. package/dist/cjs/components/FieldSlider/utils/getClosestMark.js +16 -0
  54. package/dist/cjs/components/FieldSlider/utils/getMarkLabel.d.ts +2 -0
  55. package/dist/cjs/components/FieldSlider/utils/getMarkLabel.js +7 -0
  56. package/dist/cjs/components/FieldSlider/utils/getTextFieldValue.d.ts +2 -0
  57. package/dist/cjs/components/FieldSlider/utils/getTextFieldValue.js +9 -0
  58. package/dist/cjs/components/FieldSlider/utils/index.d.ts +5 -0
  59. package/dist/cjs/components/FieldSlider/utils/index.js +21 -0
  60. package/dist/cjs/components/FieldSlider/utils/isMarkObject.d.ts +6 -0
  61. package/dist/cjs/components/FieldSlider/utils/isMarkObject.js +6 -0
  62. package/dist/cjs/components/FieldStepper/FieldStepper.d.ts +81 -0
  63. package/dist/cjs/components/FieldStepper/FieldStepper.js +160 -0
  64. package/dist/cjs/components/FieldStepper/index.d.ts +1 -0
  65. package/dist/cjs/components/FieldStepper/index.js +17 -0
  66. package/dist/cjs/components/FieldStepper/styles.module.css +78 -0
  67. package/dist/cjs/components/FieldStepper/utils.d.ts +14 -0
  68. package/dist/cjs/components/FieldStepper/utils.js +45 -0
  69. package/dist/cjs/components/FieldText/FieldText.d.ts +11 -0
  70. package/dist/cjs/components/FieldText/FieldText.js +14 -0
  71. package/dist/cjs/components/FieldText/index.d.ts +1 -0
  72. package/dist/cjs/components/FieldText/index.js +17 -0
  73. package/dist/cjs/components/FieldTextArea/FieldTextArea.d.ts +95 -0
  74. package/dist/cjs/components/FieldTextArea/FieldTextArea.js +114 -0
  75. package/dist/cjs/components/FieldTextArea/index.d.ts +1 -0
  76. package/dist/cjs/components/FieldTextArea/index.js +17 -0
  77. package/dist/cjs/components/FieldTextArea/styles.module.css +123 -0
  78. package/dist/cjs/components/FieldTime/FieldTime.d.ts +74 -0
  79. package/dist/cjs/components/FieldTime/FieldTime.js +167 -0
  80. package/dist/cjs/components/FieldTime/index.d.ts +2 -0
  81. package/dist/cjs/components/FieldTime/index.js +17 -0
  82. package/dist/cjs/components/FieldTime/mask.d.ts +3 -0
  83. package/dist/cjs/components/FieldTime/mask.js +24 -0
  84. package/dist/cjs/components/FieldTime/styles.module.css +3 -0
  85. package/dist/cjs/components/index.d.ts +14 -0
  86. package/dist/cjs/components/index.js +32 -0
  87. package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButton.d.ts +35 -0
  88. package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButton.js +47 -0
  89. package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.d.ts +26 -0
  90. package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.js +24 -0
  91. package/dist/cjs/components/shared/helperComponents/FieldElementButton/constants.d.ts +9 -0
  92. package/dist/cjs/components/shared/helperComponents/FieldElementButton/constants.js +12 -0
  93. package/dist/cjs/components/shared/helperComponents/FieldElementButton/index.d.ts +4 -0
  94. package/dist/cjs/components/shared/helperComponents/FieldElementButton/index.js +20 -0
  95. package/dist/cjs/components/shared/helperComponents/FieldElementButton/styles.module.css +204 -0
  96. package/dist/cjs/components/shared/helperComponents/FieldElementButton/types.d.ts +4 -0
  97. package/dist/cjs/components/shared/helperComponents/FieldElementButton/types.js +2 -0
  98. package/dist/cjs/components/shared/helperComponents/FieldShell/FieldShell.d.ts +43 -0
  99. package/dist/cjs/components/shared/helperComponents/FieldShell/FieldShell.js +22 -0
  100. package/dist/cjs/components/shared/helperComponents/FieldShell/index.d.ts +1 -0
  101. package/dist/cjs/components/shared/helperComponents/FieldShell/index.js +17 -0
  102. package/dist/cjs/components/shared/helperComponents/FieldShell/styles.module.css +11 -0
  103. package/dist/cjs/components/shared/hooks/useCopyButton.d.ts +20 -0
  104. package/dist/cjs/components/shared/hooks/useCopyButton.js +58 -0
  105. package/dist/cjs/components/shared/index.d.ts +4 -0
  106. package/dist/cjs/components/shared/index.js +20 -0
  107. package/dist/cjs/components/shared/styles.module.css +673 -0
  108. package/dist/cjs/components/shared/utils.d.ts +69 -0
  109. package/dist/cjs/components/shared/utils.js +104 -0
  110. package/dist/cjs/constants.d.ts +61 -0
  111. package/dist/cjs/constants.js +76 -0
  112. package/dist/cjs/hooks/index.d.ts +1 -0
  113. package/dist/cjs/hooks/index.js +17 -0
  114. package/dist/cjs/hooks/useAdaptiveAutoFocus.d.ts +7 -0
  115. package/dist/cjs/hooks/useAdaptiveAutoFocus.js +10 -0
  116. package/dist/cjs/index.d.ts +3 -0
  117. package/dist/cjs/index.js +19 -0
  118. package/dist/cjs/package.json +3 -0
  119. package/dist/cjs/segments/index.d.ts +2 -0
  120. package/dist/cjs/segments/index.js +18 -0
  121. package/dist/cjs/segments/segments.d.ts +22 -0
  122. package/dist/cjs/segments/segments.js +46 -0
  123. package/dist/cjs/segments/useSegmentedMask.d.ts +43 -0
  124. package/dist/cjs/segments/useSegmentedMask.js +282 -0
  125. package/dist/cjs/style.css +1350 -0
  126. package/dist/esm/components/FieldColor/FieldColor.d.ts +48 -0
  127. package/dist/esm/components/FieldColor/FieldColor.js +141 -0
  128. package/dist/esm/components/FieldColor/index.d.ts +1 -0
  129. package/dist/esm/components/FieldColor/index.js +1 -0
  130. package/dist/esm/components/FieldColor/styles.module.css +79 -0
  131. package/dist/esm/components/FieldColor/utils.d.ts +7 -0
  132. package/dist/esm/components/FieldColor/utils.js +16 -0
  133. package/dist/esm/components/FieldCombo/FieldCombo.d.ts +91 -0
  134. package/dist/esm/components/FieldCombo/FieldCombo.js +194 -0
  135. package/dist/esm/components/FieldCombo/index.d.ts +1 -0
  136. package/dist/esm/components/FieldCombo/index.js +1 -0
  137. package/dist/esm/components/FieldDate/FieldDate.d.ts +2 -0
  138. package/dist/esm/components/FieldDate/FieldDate.js +363 -0
  139. package/dist/esm/components/FieldDate/constants.d.ts +10 -0
  140. package/dist/esm/components/FieldDate/constants.js +10 -0
  141. package/dist/esm/components/FieldDate/index.d.ts +3 -0
  142. package/dist/esm/components/FieldDate/index.js +3 -0
  143. package/dist/esm/components/FieldDate/mask.d.ts +20 -0
  144. package/dist/esm/components/FieldDate/mask.js +111 -0
  145. package/dist/esm/components/FieldDate/styles.module.css +43 -0
  146. package/dist/esm/components/FieldDate/types.d.ts +100 -0
  147. package/dist/esm/components/FieldDate/types.js +1 -0
  148. package/dist/esm/components/FieldDate/utils.d.ts +3 -0
  149. package/dist/esm/components/FieldDate/utils.js +5 -0
  150. package/dist/esm/components/FieldSecure/FieldSecure.d.ts +64 -0
  151. package/dist/esm/components/FieldSecure/FieldSecure.js +152 -0
  152. package/dist/esm/components/FieldSecure/index.d.ts +1 -0
  153. package/dist/esm/components/FieldSecure/index.js +1 -0
  154. package/dist/esm/components/FieldSelect/FieldSelect.d.ts +2 -0
  155. package/dist/esm/components/FieldSelect/FieldSelect.js +354 -0
  156. package/dist/esm/components/FieldSelect/constants.d.ts +4 -0
  157. package/dist/esm/components/FieldSelect/constants.js +4 -0
  158. package/dist/esm/components/FieldSelect/index.d.ts +3 -0
  159. package/dist/esm/components/FieldSelect/index.js +3 -0
  160. package/dist/esm/components/FieldSelect/styles.module.css +92 -0
  161. package/dist/esm/components/FieldSelect/types.d.ts +197 -0
  162. package/dist/esm/components/FieldSelect/types.js +1 -0
  163. package/dist/esm/components/FieldSelect/utils.d.ts +19 -0
  164. package/dist/esm/components/FieldSelect/utils.js +93 -0
  165. package/dist/esm/components/FieldSlider/FieldSlider.d.ts +92 -0
  166. package/dist/esm/components/FieldSlider/FieldSlider.js +190 -0
  167. package/dist/esm/components/FieldSlider/index.d.ts +2 -0
  168. package/dist/esm/components/FieldSlider/index.js +2 -0
  169. package/dist/esm/components/FieldSlider/styles.module.css +44 -0
  170. package/dist/esm/components/FieldSlider/types.d.ts +4 -0
  171. package/dist/esm/components/FieldSlider/types.js +1 -0
  172. package/dist/esm/components/FieldSlider/utils/generateAllowedValues.d.ts +1 -0
  173. package/dist/esm/components/FieldSlider/utils/generateAllowedValues.js +13 -0
  174. package/dist/esm/components/FieldSlider/utils/getClosestMark.d.ts +4 -0
  175. package/dist/esm/components/FieldSlider/utils/getClosestMark.js +13 -0
  176. package/dist/esm/components/FieldSlider/utils/getMarkLabel.d.ts +2 -0
  177. package/dist/esm/components/FieldSlider/utils/getMarkLabel.js +4 -0
  178. package/dist/esm/components/FieldSlider/utils/getTextFieldValue.d.ts +2 -0
  179. package/dist/esm/components/FieldSlider/utils/getTextFieldValue.js +6 -0
  180. package/dist/esm/components/FieldSlider/utils/index.d.ts +5 -0
  181. package/dist/esm/components/FieldSlider/utils/index.js +5 -0
  182. package/dist/esm/components/FieldSlider/utils/isMarkObject.d.ts +6 -0
  183. package/dist/esm/components/FieldSlider/utils/isMarkObject.js +3 -0
  184. package/dist/esm/components/FieldStepper/FieldStepper.d.ts +81 -0
  185. package/dist/esm/components/FieldStepper/FieldStepper.js +154 -0
  186. package/dist/esm/components/FieldStepper/index.d.ts +1 -0
  187. package/dist/esm/components/FieldStepper/index.js +1 -0
  188. package/dist/esm/components/FieldStepper/styles.module.css +78 -0
  189. package/dist/esm/components/FieldStepper/utils.d.ts +14 -0
  190. package/dist/esm/components/FieldStepper/utils.js +38 -0
  191. package/dist/esm/components/FieldText/FieldText.d.ts +11 -0
  192. package/dist/esm/components/FieldText/FieldText.js +11 -0
  193. package/dist/esm/components/FieldText/index.d.ts +1 -0
  194. package/dist/esm/components/FieldText/index.js +1 -0
  195. package/dist/esm/components/FieldTextArea/FieldTextArea.d.ts +95 -0
  196. package/dist/esm/components/FieldTextArea/FieldTextArea.js +108 -0
  197. package/dist/esm/components/FieldTextArea/index.d.ts +1 -0
  198. package/dist/esm/components/FieldTextArea/index.js +1 -0
  199. package/dist/esm/components/FieldTextArea/styles.module.css +123 -0
  200. package/dist/esm/components/FieldTime/FieldTime.d.ts +74 -0
  201. package/dist/esm/components/FieldTime/FieldTime.js +161 -0
  202. package/dist/esm/components/FieldTime/index.d.ts +2 -0
  203. package/dist/esm/components/FieldTime/index.js +1 -0
  204. package/dist/esm/components/FieldTime/mask.d.ts +3 -0
  205. package/dist/esm/components/FieldTime/mask.js +20 -0
  206. package/dist/esm/components/FieldTime/styles.module.css +3 -0
  207. package/dist/esm/components/index.d.ts +14 -0
  208. package/dist/esm/components/index.js +12 -0
  209. package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButton.d.ts +35 -0
  210. package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButton.js +41 -0
  211. package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.d.ts +26 -0
  212. package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.js +21 -0
  213. package/dist/esm/components/shared/helperComponents/FieldElementButton/constants.d.ts +9 -0
  214. package/dist/esm/components/shared/helperComponents/FieldElementButton/constants.js +9 -0
  215. package/dist/esm/components/shared/helperComponents/FieldElementButton/index.d.ts +4 -0
  216. package/dist/esm/components/shared/helperComponents/FieldElementButton/index.js +4 -0
  217. package/dist/esm/components/shared/helperComponents/FieldElementButton/styles.module.css +204 -0
  218. package/dist/esm/components/shared/helperComponents/FieldElementButton/types.d.ts +4 -0
  219. package/dist/esm/components/shared/helperComponents/FieldElementButton/types.js +1 -0
  220. package/dist/esm/components/shared/helperComponents/FieldShell/FieldShell.d.ts +43 -0
  221. package/dist/esm/components/shared/helperComponents/FieldShell/FieldShell.js +16 -0
  222. package/dist/esm/components/shared/helperComponents/FieldShell/index.d.ts +1 -0
  223. package/dist/esm/components/shared/helperComponents/FieldShell/index.js +1 -0
  224. package/dist/esm/components/shared/helperComponents/FieldShell/styles.module.css +11 -0
  225. package/dist/esm/components/shared/hooks/useCopyButton.d.ts +20 -0
  226. package/dist/esm/components/shared/hooks/useCopyButton.js +55 -0
  227. package/dist/esm/components/shared/index.d.ts +4 -0
  228. package/dist/esm/components/shared/index.js +4 -0
  229. package/dist/esm/components/shared/styles.module.css +673 -0
  230. package/dist/esm/components/shared/utils.d.ts +69 -0
  231. package/dist/esm/components/shared/utils.js +91 -0
  232. package/dist/esm/constants.d.ts +61 -0
  233. package/dist/esm/constants.js +73 -0
  234. package/dist/esm/hooks/index.d.ts +1 -0
  235. package/dist/esm/hooks/index.js +1 -0
  236. package/dist/esm/hooks/useAdaptiveAutoFocus.d.ts +7 -0
  237. package/dist/esm/hooks/useAdaptiveAutoFocus.js +7 -0
  238. package/dist/esm/index.d.ts +3 -0
  239. package/dist/esm/index.js +3 -0
  240. package/dist/esm/segments/index.d.ts +2 -0
  241. package/dist/esm/segments/index.js +2 -0
  242. package/dist/esm/segments/segments.d.ts +22 -0
  243. package/dist/esm/segments/segments.js +43 -0
  244. package/dist/esm/segments/useSegmentedMask.d.ts +43 -0
  245. package/dist/esm/segments/useSegmentedMask.js +279 -0
  246. package/dist/esm/style.css +1350 -0
  247. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  248. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  249. package/package.json +62 -0
  250. package/src/components/FieldColor/FieldColor.tsx +426 -0
  251. package/src/components/FieldColor/index.ts +1 -0
  252. package/src/components/FieldColor/styles.module.scss +120 -0
  253. package/src/components/FieldColor/utils.ts +17 -0
  254. package/src/components/FieldCombo/FieldCombo.tsx +495 -0
  255. package/src/components/FieldCombo/index.ts +1 -0
  256. package/src/components/FieldDate/FieldDate.tsx +658 -0
  257. package/src/components/FieldDate/constants.ts +11 -0
  258. package/src/components/FieldDate/index.ts +3 -0
  259. package/src/components/FieldDate/mask.ts +123 -0
  260. package/src/components/FieldDate/styles.module.scss +56 -0
  261. package/src/components/FieldDate/types.ts +124 -0
  262. package/src/components/FieldDate/utils.ts +7 -0
  263. package/src/components/FieldSecure/FieldSecure.tsx +398 -0
  264. package/src/components/FieldSecure/index.ts +1 -0
  265. package/src/components/FieldSelect/FieldSelect.tsx +689 -0
  266. package/src/components/FieldSelect/constants.ts +4 -0
  267. package/src/components/FieldSelect/index.ts +3 -0
  268. package/src/components/FieldSelect/styles.module.scss +104 -0
  269. package/src/components/FieldSelect/types.ts +212 -0
  270. package/src/components/FieldSelect/utils.ts +134 -0
  271. package/src/components/FieldSlider/FieldSlider.tsx +502 -0
  272. package/src/components/FieldSlider/index.ts +2 -0
  273. package/src/components/FieldSlider/styles.module.scss +47 -0
  274. package/src/components/FieldSlider/types.ts +5 -0
  275. package/src/components/FieldSlider/utils/generateAllowedValues.ts +13 -0
  276. package/src/components/FieldSlider/utils/getClosestMark.ts +21 -0
  277. package/src/components/FieldSlider/utils/getMarkLabel.ts +7 -0
  278. package/src/components/FieldSlider/utils/getTextFieldValue.ts +8 -0
  279. package/src/components/FieldSlider/utils/index.ts +5 -0
  280. package/src/components/FieldSlider/utils/isMarkObject.ts +7 -0
  281. package/src/components/FieldStepper/FieldStepper.tsx +457 -0
  282. package/src/components/FieldStepper/index.ts +1 -0
  283. package/src/components/FieldStepper/styles.module.scss +98 -0
  284. package/src/components/FieldStepper/utils.ts +44 -0
  285. package/src/components/FieldText/FieldText.tsx +27 -0
  286. package/src/components/FieldText/index.ts +1 -0
  287. package/src/components/FieldTextArea/FieldTextArea.tsx +374 -0
  288. package/src/components/FieldTextArea/index.ts +1 -0
  289. package/src/components/FieldTextArea/styles.module.scss +192 -0
  290. package/src/components/FieldTime/FieldTime.tsx +401 -0
  291. package/src/components/FieldTime/index.ts +2 -0
  292. package/src/components/FieldTime/mask.ts +22 -0
  293. package/src/components/FieldTime/styles.module.scss +3 -0
  294. package/src/components/index.ts +14 -0
  295. package/src/components/shared/helperComponents/FieldElementButton/FieldElementButton.tsx +127 -0
  296. package/src/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.tsx +72 -0
  297. package/src/components/shared/helperComponents/FieldElementButton/constants.ts +10 -0
  298. package/src/components/shared/helperComponents/FieldElementButton/index.ts +4 -0
  299. package/src/components/shared/helperComponents/FieldElementButton/styles.module.scss +137 -0
  300. package/src/components/shared/helperComponents/FieldElementButton/types.ts +6 -0
  301. package/src/components/shared/helperComponents/FieldShell/FieldShell.tsx +100 -0
  302. package/src/components/shared/helperComponents/FieldShell/index.ts +1 -0
  303. package/src/components/shared/helperComponents/FieldShell/styles.module.scss +13 -0
  304. package/src/components/shared/hooks/useCopyButton.tsx +103 -0
  305. package/src/components/shared/index.ts +4 -0
  306. package/src/components/shared/styles.module.scss +409 -0
  307. package/src/components/shared/utils.ts +128 -0
  308. package/src/constants.ts +73 -0
  309. package/src/hooks/index.ts +1 -0
  310. package/src/hooks/useAdaptiveAutoFocus.ts +16 -0
  311. package/src/index.ts +3 -0
  312. package/src/segments/index.ts +2 -0
  313. package/src/segments/segments.ts +74 -0
  314. package/src/segments/useSegmentedMask.ts +361 -0
@@ -0,0 +1,398 @@
1
+ // Имя совпадает с мастер-нодой Figma (`fieldSecure`). Легаси-проп `prefixIcon` ниже
2
+ // сохраняет совместимость с `@snack-uikit/fields` (`FieldSecure.prefixIcon`).
3
+ import { Divider } from '@cloud-ru/ds-divider';
4
+ import { FieldDecorator, FieldDecoratorProps, SIZE, VALIDATION_STATE } from '@cloud-ru/ds-field-decorator';
5
+ import { EyeClosedSVG, EyeSVG } from '@cloud-ru/ds-icons/interface/system';
6
+ import { InputPrivate, InputPrivateProps, TYPE, useButtonNavigation } from '@cloud-ru/ds-input-private';
7
+ import { Skeleton, WithSkeleton } from '@cloud-ru/ds-skeleton';
8
+ import { useValueControl } from '@cloud-ru/ds-utils';
9
+ import cn from 'classnames';
10
+ import mergeRefs from 'merge-refs';
11
+ import { FocusEvent, forwardRef, KeyboardEvent, ReactNode, useCallback, useMemo, useRef, useState } from 'react';
12
+
13
+ import { TEST_IDS } from '../../constants';
14
+ import { copyTextToClipboard, FieldElementButton, getAcrylicProps, toInputSize, useCopyButton } from '../shared';
15
+ import fieldStyles from '../shared/styles.module.scss';
16
+
17
+ type FieldSecureDecoratorProps = Omit<FieldDecoratorProps, 'children'>;
18
+
19
+ type FieldSecureOwnProps = {
20
+ /** CSS-класс корня `FieldDecorator` */
21
+ className?: string;
22
+ /** CSS-класс оболочки поля ввода */
23
+ fieldClassName?: string;
24
+ /**
25
+ * Фон поля (acrylic)
26
+ * @default true
27
+ */
28
+ background?: boolean;
29
+ /** Значение (controlled-режим) */
30
+ value?: string;
31
+ /** Начальное значение (uncontrolled-режим) */
32
+ defaultValue?: string;
33
+ /** Колбек смены значения */
34
+ onChange?(value: string): void;
35
+ /**
36
+ * Скрыто ли значение (controlled). Для uncontrolled-режима используйте `defaultHidden`.
37
+ */
38
+ hidden?: boolean;
39
+ /**
40
+ * Начальное состояние маскирования (uncontrolled-режим). Кнопка «глаз» переключает
41
+ * маскирование сама; `hidden` для этого передавать не нужно.
42
+ * @default true
43
+ */
44
+ defaultHidden?: boolean;
45
+ /** Колбек смены маскирования */
46
+ onHiddenChange?(hidden: boolean): void;
47
+ /**
48
+ * Показывать кнопку «глаз»
49
+ * @default true
50
+ */
51
+ showHideButton?: boolean;
52
+ /**
53
+ * Показывать кнопку копирования (только при `readonly = true` и непустом `value`)
54
+ * @default true
55
+ */
56
+ showCopyButton?: boolean;
57
+ /** Колбек после копирования значения в буфер */
58
+ onCopyButtonClick?(): void;
59
+ /**
60
+ * Разрешить ввод свыше `maxLength` символов.
61
+ * @default false
62
+ */
63
+ allowMoreThanMaxLength?: boolean;
64
+ /**
65
+ * Async-загрузчик значения. Вызывается перед раскрытием/копированием значения,
66
+ * результат передаётся через `onChange`. Во время запроса показывается Skeleton.
67
+ * После успешного запроса значение считается полученным и больше не запрашивается.
68
+ */
69
+ asyncValueGetter?: () => Promise<string>;
70
+ /**
71
+ * Ведущая иконка.
72
+ * @deprecated Используйте `iconBefore`.
73
+ */
74
+ prefixIcon?: ReactNode;
75
+ };
76
+
77
+ export type FieldSecureProps = FieldSecureDecoratorProps &
78
+ Omit<InputPrivateProps, 'className' | 'type' | 'value' | 'onChange'> &
79
+ FieldSecureOwnProps;
80
+
81
+ const isCursorAtEnd = (el: HTMLInputElement | null) =>
82
+ Boolean(el && el.selectionStart === el.value.length && el.selectionEnd === el.value.length);
83
+
84
+ export const FieldSecure = forwardRef<HTMLInputElement, FieldSecureProps>(function FieldSecure(
85
+ {
86
+ label = '',
87
+ labelTooltip,
88
+ caption,
89
+ hint,
90
+ error,
91
+ validationState = VALIDATION_STATE.Default,
92
+ showHintIcon,
93
+ length,
94
+ required,
95
+ size = SIZE.M,
96
+ className,
97
+ fieldClassName,
98
+ background = true,
99
+ value: valueProp,
100
+ defaultValue,
101
+ hidden: hiddenProp,
102
+ defaultHidden,
103
+ onHiddenChange,
104
+ showHideButton: showHideButtonProp = true,
105
+ showCopyButton: showCopyButtonProp = true,
106
+ onCopyButtonClick,
107
+ allowMoreThanMaxLength = false,
108
+ asyncValueGetter,
109
+ prefixIcon,
110
+ disabled,
111
+ readonly: readOnly,
112
+ onChange,
113
+ placeholder,
114
+ 'data-test-id': dataTestId,
115
+ ...inputProps
116
+ },
117
+ ref,
118
+ ) {
119
+ const {
120
+ onFocus: onFocusProp,
121
+ onBlur: onBlurProp,
122
+ onKeyDown: onKeyDownProp,
123
+ tabIndex: tabIndexProp,
124
+ maxLength,
125
+ ...restInputProps
126
+ } = inputProps;
127
+ const localRef = useRef<HTMLInputElement>(null);
128
+ const copyButtonRef = useRef<HTMLButtonElement>(null);
129
+ const hideButtonRef = useRef<HTMLButtonElement>(null);
130
+ const [focusVisible, setFocusVisible] = useState(false);
131
+ const [hover, setHover] = useState(false);
132
+ const [hiddenInner, setHiddenInner] = useState(defaultHidden ?? true);
133
+ const [isLoading, setIsLoading] = useState(false);
134
+ const [isAsyncLoaded, setIsAsyncLoaded] = useState(false);
135
+
136
+ const isHiddenControlled = hiddenProp !== undefined;
137
+ const hidden = isHiddenControlled ? hiddenProp : hiddenInner;
138
+
139
+ // controlled/uncontrolled: useValueControl держит значение при отсутствии `value`.
140
+ const [value = '', setValue] = useValueControl<string>({ value: valueProp, defaultValue });
141
+ const emitChange = useCallback(
142
+ (next: string) => {
143
+ setValue(next);
144
+ onChange?.(next);
145
+ },
146
+ [onChange, setValue],
147
+ );
148
+
149
+ const ensureAsyncValue = useCallback(async (): Promise<boolean> => {
150
+ if (!asyncValueGetter || isAsyncLoaded) {
151
+ return true;
152
+ }
153
+ setIsLoading(true);
154
+ try {
155
+ const next = await asyncValueGetter();
156
+ setIsAsyncLoaded(true);
157
+ emitChange(next);
158
+ return true;
159
+ } catch {
160
+ return false;
161
+ } finally {
162
+ setIsLoading(false);
163
+ }
164
+ }, [asyncValueGetter, emitChange, isAsyncLoaded]);
165
+
166
+ const toggleHidden = useCallback(() => {
167
+ ensureAsyncValue().then(success => {
168
+ if (!success) {
169
+ return;
170
+ }
171
+ const next = !hidden;
172
+ if (!isHiddenControlled) {
173
+ setHiddenInner(next);
174
+ }
175
+ onHiddenChange?.(next);
176
+ // Возврат фокуса в поле + каретка в конец после переключения (паритет с легаси FieldSecure).
177
+ if (!readOnly) {
178
+ setTimeout(() => {
179
+ const input = localRef.current;
180
+ if (input) {
181
+ input.focus();
182
+ const end = input.value.length;
183
+ input.setSelectionRange(end, end);
184
+ }
185
+ }, 0);
186
+ }
187
+ });
188
+ }, [ensureAsyncValue, hidden, isHiddenControlled, onHiddenChange, readOnly]);
189
+
190
+ const effectiveValidationState = useMemo(
191
+ () => (error ? VALIDATION_STATE.Error : validationState),
192
+ [error, validationState],
193
+ );
194
+
195
+ const stringValue = String(value ?? '');
196
+ const showCopyUi = Boolean(showCopyButtonProp && stringValue && !disabled && readOnly);
197
+ const showHideUi = Boolean(showHideButtonProp && !(readOnly && !stringValue));
198
+
199
+ const onCopy = useCallback(
200
+ () =>
201
+ ensureAsyncValue().then(async success => {
202
+ const copied = success && (await copyTextToClipboard(stringValue));
203
+ if (copied) {
204
+ onCopyButtonClick?.();
205
+ }
206
+ return copied;
207
+ }),
208
+ [ensureAsyncValue, onCopyButtonClick, stringValue],
209
+ );
210
+
211
+ const copyButtonSettings = useCopyButton({
212
+ copyButtonRef,
213
+ showCopyButton: showCopyUi,
214
+ size: toInputSize(size),
215
+ onCopy,
216
+ disabled: Boolean(disabled),
217
+ });
218
+
219
+ // ArrowRight с copy-кнопки уводит фокус на «глаз» (buttonFieldAfter), продолжая roving-цепочку.
220
+ const onPostfixKeyDown = useCallback(
221
+ (event: KeyboardEvent<HTMLButtonElement>) => {
222
+ if (event.key === 'ArrowRight' && showHideUi && hideButtonRef.current) {
223
+ event.preventDefault();
224
+ hideButtonRef.current.focus();
225
+ }
226
+ },
227
+ [showHideUi],
228
+ );
229
+
230
+ const { postfixButtons, inputTabIndex, onInputKeyDown } = useButtonNavigation({
231
+ inputRef: localRef,
232
+ postfixButtons: useMemo(() => [copyButtonSettings], [copyButtonSettings]),
233
+ onButtonKeyDown: onPostfixKeyDown,
234
+ readonly: Boolean(readOnly),
235
+ submitKeys: ['Enter', 'Space', 'Tab'],
236
+ });
237
+
238
+ const handleKeyDown = useCallback(
239
+ (event: KeyboardEvent<HTMLInputElement>) => {
240
+ onKeyDownProp?.(event);
241
+ onInputKeyDown(event);
242
+
243
+ // ArrowRight в конце поля уводит фокус на кнопку «глаз» (если рядом нет видимой copy).
244
+ const atEnd = Boolean(readOnly) || isCursorAtEnd(localRef.current);
245
+ if (showHideUi && event.key === 'ArrowRight' && atEnd && !showCopyUi && hideButtonRef.current) {
246
+ event.preventDefault();
247
+ hideButtonRef.current.focus();
248
+ }
249
+ },
250
+ [onInputKeyDown, onKeyDownProp, readOnly, showCopyUi, showHideUi],
251
+ );
252
+
253
+ // ArrowLeft с «глаза» возвращает фокус на copy (если видима) или в поле.
254
+ const onEyeKeyDown = useCallback(
255
+ (event: KeyboardEvent<HTMLButtonElement>) => {
256
+ if (event.key === 'ArrowLeft') {
257
+ event.preventDefault();
258
+ ((showCopyUi && copyButtonRef.current) || localRef.current)?.focus();
259
+ }
260
+ },
261
+ [showCopyUi],
262
+ );
263
+
264
+ const handleFocus = useCallback(
265
+ (event: FocusEvent<HTMLInputElement>) => {
266
+ setFocusVisible(event.target.matches(':focus-visible'));
267
+ onFocusProp?.(event);
268
+ },
269
+ [onFocusProp],
270
+ );
271
+
272
+ const handleBlur = useCallback(
273
+ (event: FocusEvent<HTMLInputElement>) => {
274
+ setFocusVisible(false);
275
+ onBlurProp?.(event);
276
+ },
277
+ [onBlurProp],
278
+ );
279
+
280
+ const handleMouseEnter = useCallback(() => {
281
+ if (!readOnly && !disabled) {
282
+ setHover(true);
283
+ }
284
+ }, [disabled, readOnly]);
285
+
286
+ const handleMouseLeave = useCallback(() => {
287
+ setHover(false);
288
+ }, []);
289
+
290
+ const shell = (
291
+ <div
292
+ className={cn(fieldStyles.fieldWrapper, fieldClassName)}
293
+ // Внутренняя оболочка несёт effectiveValidationState (error форсит 'error'); корень
294
+ // (FieldDecorator с публичным data-test-id) хранит RAW `validationState`.
295
+ data-test-id={TEST_IDS.fieldSecureShell}
296
+ data-size={size}
297
+ data-validation-state={effectiveValidationState}
298
+ data-disabled={disabled || undefined}
299
+ data-readonly={readOnly || undefined}
300
+ data-withbackground={background || undefined}
301
+ data-focusvisible={focusVisible || undefined}
302
+ data-hover={!readOnly && !disabled && hover ? true : undefined}
303
+ onMouseEnter={handleMouseEnter}
304
+ onMouseLeave={handleMouseLeave}
305
+ >
306
+ <div className={fieldStyles.backgroundWrapper}>
307
+ <div
308
+ className={fieldStyles.materialLayer}
309
+ {...getAcrylicProps({
310
+ validationState: effectiveValidationState,
311
+ disabled,
312
+ readonly: readOnly,
313
+ hover,
314
+ focusVisible,
315
+ })}
316
+ >
317
+ <div className={fieldStyles.acrylicBg} aria-hidden />
318
+ </div>
319
+ <div className={fieldStyles.borderStateLayer} data-state='borderOnBackground' />
320
+ <div className={fieldStyles.focusLayer} />
321
+ </div>
322
+ <div className={fieldStyles.fieldContainer}>
323
+ <div className={fieldStyles.contentWrapper}>
324
+ {prefixIcon && <div className={fieldStyles.iconSlot}>{prefixIcon}</div>}
325
+ <div className={fieldStyles.inputLine}>
326
+ <div className={fieldStyles.inputArea}>
327
+ <WithSkeleton
328
+ skeleton={<Skeleton width='100%' borderRadius={2} data-test-id={TEST_IDS.fieldSecureSkeleton} />}
329
+ loading={isLoading}
330
+ >
331
+ <InputPrivate
332
+ ref={mergeRefs(ref, localRef)}
333
+ className={fieldStyles.fieldInput}
334
+ value={value}
335
+ disabled={disabled}
336
+ readonly={readOnly}
337
+ onChange={emitChange}
338
+ placeholder={placeholder}
339
+ tabIndex={tabIndexProp ?? inputTabIndex}
340
+ onKeyDown={handleKeyDown}
341
+ onFocus={handleFocus}
342
+ onBlur={handleBlur}
343
+ type={hidden ? TYPE.Password : TYPE.Text}
344
+ maxLength={allowMoreThanMaxLength ? undefined : maxLength}
345
+ {...restInputProps}
346
+ data-test-id={TEST_IDS.fieldSecureInput}
347
+ />
348
+ </WithSkeleton>
349
+ {postfixButtons && <span className={fieldStyles.postfixButtonsSlot}>{postfixButtons}</span>}
350
+ </div>
351
+ </div>
352
+ </div>
353
+ </div>
354
+ {showHideUi && (
355
+ <div className={fieldStyles.elementWrapperAfter}>
356
+ <div className={fieldStyles.lineWrapper} data-outline={true}>
357
+ <Divider orientation='vertical' variant='regular' />
358
+ </div>
359
+ <FieldElementButton
360
+ ref={hideButtonRef}
361
+ variant='after'
362
+ size={size}
363
+ action={hidden ? <EyeSVG /> : <EyeClosedSVG />}
364
+ onClick={toggleHidden}
365
+ onKeyDown={onEyeKeyDown}
366
+ disabled={disabled}
367
+ // Roving-композит (легаси: обе кнопки в postfixButtons useButtonNavigation):
368
+ // Tab уходит из поля целиком, по кнопкам (copy → глаз) ходят стрелки.
369
+ tabIndex={-1}
370
+ data-test-id={TEST_IDS.fieldSecureHideButton}
371
+ />
372
+ </div>
373
+ )}
374
+ </div>
375
+ );
376
+
377
+ return (
378
+ <FieldDecorator
379
+ className={className}
380
+ label={label}
381
+ labelTooltip={labelTooltip}
382
+ caption={caption}
383
+ hint={hint}
384
+ error={error}
385
+ validationState={validationState}
386
+ showHintIcon={showHintIcon}
387
+ length={length ?? (maxLength ? { current: stringValue.length, max: maxLength } : undefined)}
388
+ required={required}
389
+ labelFor={inputProps.id}
390
+ disabled={disabled}
391
+ readonly={readOnly}
392
+ size={size}
393
+ data-test-id={dataTestId}
394
+ >
395
+ {shell}
396
+ </FieldDecorator>
397
+ );
398
+ });
@@ -0,0 +1 @@
1
+ export * from './FieldSecure';