@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,95 @@
1
+ import { FieldDecoratorProps } from '@cloud-ru/ds-field-decorator';
2
+ import { ChangeEvent, FocusEvent, HTMLAttributes, KeyboardEvent, ReactNode } from 'react';
3
+ import { FieldLayoutPresets } from '../../hooks';
4
+ type FieldTextAreaDecoratorProps = Omit<FieldDecoratorProps, 'children'>;
5
+ type FieldTextAreaOwnProps = {
6
+ /** CSS-класс корня `FieldDecorator` */
7
+ className?: string;
8
+ /** CSS-класс оболочки поля */
9
+ fieldClassName?: string;
10
+ /** Значение (controlled-режим) */
11
+ value?: string;
12
+ /** Начальное значение (uncontrolled-режим) */
13
+ defaultValue?: string;
14
+ /** Колбек смены значения */
15
+ onChange?(value: string, event?: ChangeEvent<HTMLTextAreaElement>): void;
16
+ /** Плейсхолдер */
17
+ placeholder?: string;
18
+ /** HTML id */
19
+ id?: string;
20
+ /** HTML name */
21
+ name?: string;
22
+ /** Максимальное количество символов */
23
+ maxLength?: number;
24
+ /** Поле выключено */
25
+ disabled?: boolean;
26
+ /** Только для чтения */
27
+ readonly?: boolean;
28
+ /** Автофокус. На mobile выключается адаптивно (см. `layoutPresets`) */
29
+ autoFocus?: boolean;
30
+ /**
31
+ * Переопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен
32
+ * (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`.
33
+ */
34
+ layoutPresets?: FieldLayoutPresets;
35
+ /** Режим виртуальной клавиатуры (`inputmode` нативного `<textarea>`) */
36
+ inputMode?: HTMLAttributes<HTMLTextAreaElement>['inputMode'];
37
+ /** Проверка орфографии */
38
+ spellCheck?: boolean;
39
+ /**
40
+ * Минимальное количество строк
41
+ * @default 3
42
+ */
43
+ minRows?: number;
44
+ /**
45
+ * Максимальное количество строк (после — появляется скролл)
46
+ * @default 1000
47
+ */
48
+ maxRows?: number;
49
+ /**
50
+ * Разрешить ввод свыше `maxLength` символов (счётчик продолжит расти).
51
+ * @default true
52
+ */
53
+ allowMoreThanMaxLength?: boolean;
54
+ /**
55
+ * Нода над textarea — ряд элементов до контента (Figma `elementWrapperBefore` /
56
+ * `slotBeforeContent`): тулбар с кнопками, чипами и т.п.
57
+ */
58
+ header?: ReactNode;
59
+ /**
60
+ * Нода под textarea — ряд элементов после контента (Figma `elementWrapperAfter` /
61
+ * `slotAfterContent`): действия, счётчик-плагин и т.п.
62
+ */
63
+ footer?: ReactNode;
64
+ /**
65
+ * Можно ли менять высоту мышкой за нижний угол. Игнорируется при `disabled` или `readonly`.
66
+ * @default false
67
+ */
68
+ resizable?: boolean;
69
+ /**
70
+ * Фон поля (acrylic)
71
+ * @default true
72
+ */
73
+ background?: boolean;
74
+ /**
75
+ * Кнопка очистки (видна при value && !readonly)
76
+ * @default true
77
+ */
78
+ showClearButton?: boolean;
79
+ /**
80
+ * Кнопка копирования (видна при value && !disabled, независимо от readonly)
81
+ * @default true
82
+ */
83
+ showCopyButton?: boolean;
84
+ /** Колбек после копирования */
85
+ onCopyButtonClick?(): void;
86
+ /** Колбек фокуса */
87
+ onFocus?(event: FocusEvent<HTMLTextAreaElement>): void;
88
+ /** Колбек блюра */
89
+ onBlur?(event: FocusEvent<HTMLTextAreaElement>): void;
90
+ /** Колбек нажатия клавиши */
91
+ onKeyDown?(event: KeyboardEvent<HTMLTextAreaElement>): void;
92
+ };
93
+ export type FieldTextAreaProps = FieldTextAreaDecoratorProps & FieldTextAreaOwnProps;
94
+ export declare const FieldTextArea: import("react").ForwardRefExoticComponent<FieldTextAreaDecoratorProps & FieldTextAreaOwnProps & import("react").RefAttributes<HTMLTextAreaElement>>;
95
+ export {};
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FieldTextArea = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const field_decorator_1 = require("@cloud-ru/ds-field-decorator");
9
+ const input_private_1 = require("@cloud-ru/ds-input-private");
10
+ const scroll_1 = require("@cloud-ru/ds-scroll");
11
+ const utils_1 = require("@cloud-ru/ds-utils");
12
+ const classnames_1 = __importDefault(require("classnames"));
13
+ const merge_refs_1 = __importDefault(require("merge-refs"));
14
+ const react_1 = require("react");
15
+ const react_textarea_autosize_1 = __importDefault(require("react-textarea-autosize"));
16
+ const constants_1 = require("../../constants");
17
+ const hooks_1 = require("../../hooks");
18
+ const shared_1 = require("../shared");
19
+ const styles_module_scss_1 = __importDefault(require('../shared/styles.module.css'));
20
+ const styles_module_scss_2 = __importDefault(require('./styles.module.css'));
21
+ exports.FieldTextArea = (0, react_1.forwardRef)(function FieldTextArea({ label = '', labelTooltip, caption, hint, error, validationState = field_decorator_1.VALIDATION_STATE.Default, showHintIcon, length, required, size = field_decorator_1.SIZE.M, className, fieldClassName, background = true, value: valueProp, defaultValue = '', onChange, placeholder, id, name, maxLength, disabled, readonly: readOnly, autoFocus, layoutPresets, inputMode, spellCheck, minRows = 3, maxRows = 1000, resizable = false, allowMoreThanMaxLength = true, header, footer, showClearButton: showClearButtonProp = true, showCopyButton: showCopyButtonProp = true, onCopyButtonClick, onFocus: onFocusProp, onBlur: onBlurProp, onKeyDown: onKeyDownProp, 'data-test-id': dataTestId, ...rest }, ref) {
22
+ const localRef = (0, react_1.useRef)(null);
23
+ const clearButtonRef = (0, react_1.useRef)(null);
24
+ const copyButtonRef = (0, react_1.useRef)(null);
25
+ const [focusVisible, setFocusVisible] = (0, react_1.useState)(false);
26
+ const [hover, setHover] = (0, react_1.useState)(false);
27
+ const resolvedAutoFocus = (0, hooks_1.useAdaptiveAutoFocus)(autoFocus, layoutPresets);
28
+ // controlled/uncontrolled: useValueControl держит внутреннее состояние при отсутствии `value`,
29
+ // событие в `onChange` пробрасываем сами (useValueControl передаёт только значение).
30
+ const [value = '', setValue] = (0, utils_1.useValueControl)({ value: valueProp, defaultValue });
31
+ const effectiveValidationState = (0, react_1.useMemo)(() => (error ? field_decorator_1.VALIDATION_STATE.Error : validationState), [error, validationState]);
32
+ const stringValue = String(value ?? '');
33
+ const isResizable = resizable && !disabled && !readOnly;
34
+ const showClearUi = Boolean(showClearButtonProp && stringValue && !readOnly && !disabled);
35
+ // Copy не завязан на readonly (паритет с snack-uikit master): виден при любом непустом значении.
36
+ // В editable-режиме показываются обе кнопки (clear + copy), в readonly — только copy.
37
+ const showCopyUi = Boolean(showCopyButtonProp && stringValue && !disabled);
38
+ const onClear = (0, react_1.useCallback)(() => {
39
+ setValue('');
40
+ onChange?.('');
41
+ localRef.current?.focus();
42
+ }, [onChange, setValue]);
43
+ const onCopy = (0, react_1.useCallback)(async () => {
44
+ const copied = await (0, shared_1.copyTextToClipboard)(stringValue);
45
+ if (copied) {
46
+ onCopyButtonClick?.();
47
+ }
48
+ return copied;
49
+ }, [onCopyButtonClick, stringValue]);
50
+ const clearButtonSettings = (0, input_private_1.useClearButton)({
51
+ clearButtonRef,
52
+ showClearButton: showClearUi,
53
+ size: (0, shared_1.toInputSize)(size),
54
+ onClear,
55
+ disabled: Boolean(disabled || readOnly),
56
+ });
57
+ const copyButtonSettings = (0, shared_1.useCopyButton)({
58
+ copyButtonRef,
59
+ showCopyButton: showCopyUi,
60
+ size: (0, shared_1.toInputSize)(size),
61
+ onCopy,
62
+ disabled: Boolean(disabled),
63
+ });
64
+ const { postfixButtons, inputTabIndex, onInputKeyDown } = (0, input_private_1.useButtonNavigation)({
65
+ inputRef: localRef,
66
+ postfixButtons: (0, react_1.useMemo)(() => [clearButtonSettings, copyButtonSettings], [clearButtonSettings, copyButtonSettings]),
67
+ readonly: Boolean(readOnly),
68
+ submitKeys: ['Tab'],
69
+ });
70
+ const handleKeyDown = (0, react_1.useCallback)((event) => {
71
+ onKeyDownProp?.(event);
72
+ onInputKeyDown(event);
73
+ }, [onInputKeyDown, onKeyDownProp]);
74
+ const handleChange = (event) => {
75
+ setValue(event.target.value);
76
+ onChange?.(event.target.value, event);
77
+ };
78
+ // Клик в «пустую» зону поля (под textarea при minRows-резерве, в правый резерв под кнопки)
79
+ // фокусит textarea и ставит курсор в конец — паритет со снеком, где попадание в любую область
80
+ // поля работает как клик по textarea. Намеренно `onClick`, а не `onMouseDown`+preventDefault:
81
+ // resize-ручка scroll-контейнера тоже работает через mousedown-drag, и preventDefault убивал бы
82
+ // нативный CSS-resize. Click после resize-drag не возникает, а клики по textarea, кнопкам
83
+ // clear/copy и DS-скроллбару отсеиваем по target.
84
+ const handleContentClick = (0, react_1.useCallback)((event) => {
85
+ const target = event.target;
86
+ if (disabled || target === localRef.current || target.closest('button, [class*="os-scrollbar"]')) {
87
+ return;
88
+ }
89
+ const textarea = localRef.current;
90
+ if (textarea) {
91
+ textarea.focus();
92
+ const end = textarea.value.length;
93
+ textarea.setSelectionRange(end, end);
94
+ }
95
+ }, [disabled]);
96
+ const handleFocus = (0, react_1.useCallback)((event) => {
97
+ setFocusVisible(event.target.matches(':focus-visible'));
98
+ onFocusProp?.(event);
99
+ }, [onFocusProp]);
100
+ const handleBlur = (0, react_1.useCallback)((event) => {
101
+ setFocusVisible(false);
102
+ onBlurProp?.(event);
103
+ }, [onBlurProp]);
104
+ const handleMouseEnter = (0, react_1.useCallback)(() => {
105
+ if (!readOnly) {
106
+ setHover(true);
107
+ }
108
+ }, [readOnly]);
109
+ const handleMouseLeave = (0, react_1.useCallback)(() => {
110
+ setHover(false);
111
+ }, []);
112
+ const shell = ((0, jsx_runtime_1.jsx)(shared_1.FieldShell, { "data-test-id": constants_1.TEST_IDS.fieldTextAreaShell, className: fieldClassName, size: size, validationState: effectiveValidationState, disabled: disabled, readonly: readOnly, background: background, focusVisible: focusVisible, hover: hover, header: header, footer: footer, style: { '--field-textarea-min-rows': minRows, '--field-textarea-max-rows': maxRows }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(styles_module_scss_1.default.contentWrapper, styles_module_scss_2.default.contentArea), onClick: handleContentClick, children: [(0, jsx_runtime_1.jsx)(scroll_1.Scroll, { className: (0, classnames_1.default)(styles_module_scss_2.default.scrollContainer, { [styles_module_scss_2.default.scrollContainerResizable]: isResizable }), size: scroll_1.SIZE.S, barHideStrategy: scroll_1.BAR_HIDE_STRATEGY.Never, resize: isResizable ? scroll_1.RESIZE.Vertical : scroll_1.RESIZE.None, overflow: { x: 'hidden' }, "data-test-id": constants_1.TEST_IDS.fieldTextAreaScrollArea, children: (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.inputLine, children: (0, jsx_runtime_1.jsx)(react_textarea_autosize_1.default, { ref: (0, merge_refs_1.default)(ref, localRef), className: styles_module_scss_2.default.textarea, value: value, onChange: handleChange, placeholder: placeholder, disabled: disabled, readOnly: readOnly, id: id, name: name, maxLength: allowMoreThanMaxLength ? undefined : maxLength, autoFocus: resolvedAutoFocus, inputMode: inputMode, spellCheck: spellCheck, minRows: minRows, tabIndex: inputTabIndex, "data-test-id": constants_1.TEST_IDS.fieldTextAreaInput, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, ...(0, utils_1.extractSupportProps)(rest) }) }) }), postfixButtons && (0, jsx_runtime_1.jsx)("span", { className: styles_module_scss_2.default.postfixColumn, children: postfixButtons })] }) }));
113
+ return ((0, jsx_runtime_1.jsx)(field_decorator_1.FieldDecorator, { className: className, label: label, labelTooltip: labelTooltip, caption: caption, hint: hint, error: error, validationState: validationState, showHintIcon: showHintIcon, length: length ?? (maxLength ? { current: stringValue.length, max: maxLength } : undefined), required: required, labelFor: id, disabled: disabled, readonly: readOnly, size: size, "data-test-id": dataTestId, children: shell }));
114
+ });
@@ -0,0 +1 @@
1
+ export * from './FieldTextArea';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./FieldTextArea"), exports);
@@ -0,0 +1,123 @@
1
+ .scrollContainer{
2
+ flex:1 1 auto;
3
+ min-width:0;
4
+ min-height:calc(var(--field-textarea-min-rows, 3) * var(--field-textarea-row-height));
5
+ max-height:calc(var(--field-textarea-max-rows, 1000) * var(--field-textarea-row-height));
6
+ }
7
+ [data-size=s] .scrollContainer{
8
+ --field-textarea-row-height:var(--sn-regular-body-s-lineHeight, var(--sn-density-typography-roleBody-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
9
+ }
10
+ [data-size=m] .scrollContainer{
11
+ --field-textarea-row-height:var(--sn-regular-body-m-lineHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)));
12
+ }
13
+ [data-size=l] .scrollContainer{
14
+ --field-textarea-row-height:var(--sn-regular-body-l-lineHeight, var(--sn-density-typography-roleBody-lineHeightL, var(--sn-primitive-font-lineHeight-by20, 28px)));
15
+ }
16
+
17
+ .scrollContainerResizable{
18
+ height:calc(var(--field-textarea-min-rows, 3) * var(--field-textarea-row-height));
19
+ }
20
+
21
+ .textarea{
22
+ resize:none;
23
+ overflow:hidden;
24
+ width:100%;
25
+ min-width:0;
26
+ padding:0;
27
+ border:none;
28
+ color:var(--sn-theme-color-available-version-textMain, var(--sn-brand-color-text-version-main, #41424e));
29
+ background:transparent;
30
+ outline:none;
31
+ }
32
+ .textarea::-moz-placeholder{
33
+ color:var(--sn-theme-color-available-version-textDisabled, var(--sn-brand-color-text-version-disabled, rgba(65, 66, 78, 0.3490196078)));
34
+ opacity:1;
35
+ }
36
+ .textarea::placeholder{
37
+ color:var(--sn-theme-color-available-version-textDisabled, var(--sn-brand-color-text-version-disabled, rgba(65, 66, 78, 0.3490196078)));
38
+ opacity:1;
39
+ }
40
+ .textarea:disabled::-moz-placeholder{
41
+ visibility:hidden;
42
+ }
43
+ .textarea:disabled::placeholder{
44
+ visibility:hidden;
45
+ }
46
+ .textarea:-moz-read-only{
47
+ color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
48
+ }
49
+ .textarea:read-only{
50
+ color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
51
+ }
52
+ [data-size=s] .textarea{
53
+ min-height:var(--sn-field-anatomy-size-s-fieldContainer-multiLine-minHeight, var(--sn-primitive-dimension-56, 56px));
54
+ padding-right:calc(var(--sn-field-anatomy-size-s-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px))) + var(--sn-scroll-anatomy-container-size-s-square, var(--sn-primitive-dimension-8, 8px)) + var(--sn-field-anatomy-size-s-fieldContainer-contentWrapper-inputLine-horizontalPadding, var(--sn-density-spacing-control-wrapper-horizontal-s, var(--sn-primitive-dimension-8, 8px))));
55
+ font-family:var(--sn-regular-body-s-fontFamily, var(--sn-brand-font-fontFamily-regular-body, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
56
+ font-weight:var(--sn-regular-body-s-fontWeight, var(--sn-theme-typography-fontWeight-regular-body-s, var(--sn-brand-font-fontWeight-light-regular-body-s, var(--sn-primitive-font-fontWeightValue-400, 400))));
57
+ line-height:var(--sn-regular-body-s-lineHeight, var(--sn-density-typography-roleBody-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
58
+ font-size:var(--sn-regular-body-s-fontSize, var(--sn-density-typography-roleBody-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
59
+ letter-spacing:var(--sn-regular-body-s-letterSpacing, var(--sn-primitive-font-letterSpacing-m, 0.1px));
60
+ paragraph-spacing:var(--sn-regular-body-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize12, 6px));
61
+ }
62
+ [data-size=m] .textarea{
63
+ min-height:var(--sn-field-anatomy-size-m-fieldContainer-multiLine-minHeight, var(--sn-primitive-dimension-68, 68px));
64
+ padding-right:calc(var(--sn-field-anatomy-size-m-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px))) + var(--sn-scroll-anatomy-container-size-s-square, var(--sn-primitive-dimension-8, 8px)) + var(--sn-field-anatomy-size-m-fieldContainer-contentWrapper-inputLine-horizontalPadding, var(--sn-density-spacing-control-wrapper-horizontal-m, var(--sn-primitive-dimension-8, 8px))));
65
+ font-family:var(--sn-regular-body-m-fontFamily, var(--sn-brand-font-fontFamily-regular-body, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
66
+ font-weight:var(--sn-regular-body-m-fontWeight, var(--sn-theme-typography-fontWeight-regular-body-m, var(--sn-brand-font-fontWeight-light-regular-body-m, var(--sn-primitive-font-fontWeightValue-400, 400))));
67
+ line-height:var(--sn-regular-body-m-lineHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)));
68
+ font-size:var(--sn-regular-body-m-fontSize, var(--sn-density-typography-roleBody-fontSizeM, var(--sn-primitive-font-fontSize-16, 16px)));
69
+ letter-spacing:var(--sn-regular-body-m-letterSpacing, var(--sn-primitive-font-letterSpacing-m, 0.1px));
70
+ paragraph-spacing:var(--sn-regular-body-m-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize14, 7px));
71
+ }
72
+ [data-size=l] .textarea{
73
+ min-height:var(--sn-field-anatomy-size-l-fieldContainer-multiLine-minHeight, var(--sn-primitive-dimension-88, 88px));
74
+ padding-right:calc(var(--sn-field-anatomy-size-l-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightL, var(--sn-primitive-font-lineHeight-by20, 28px))) + var(--sn-scroll-anatomy-container-size-s-square, var(--sn-primitive-dimension-8, 8px)) + var(--sn-field-anatomy-size-l-fieldContainer-contentWrapper-inputLine-horizontalPadding, var(--sn-density-spacing-control-wrapper-horizontal-l, var(--sn-primitive-dimension-12, 12px))));
75
+ font-family:var(--sn-regular-body-l-fontFamily, var(--sn-brand-font-fontFamily-regular-body, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
76
+ font-weight:var(--sn-regular-body-l-fontWeight, var(--sn-theme-typography-fontWeight-regular-body-l, var(--sn-brand-font-fontWeight-light-regular-body-l, var(--sn-primitive-font-fontWeightValue-400, 400))));
77
+ line-height:var(--sn-regular-body-l-lineHeight, var(--sn-density-typography-roleBody-lineHeightL, var(--sn-primitive-font-lineHeight-by20, 28px)));
78
+ font-size:var(--sn-regular-body-l-fontSize, var(--sn-density-typography-roleBody-fontSizeL, var(--sn-primitive-font-fontSize-20, 20px)));
79
+ letter-spacing:var(--sn-regular-body-l-letterSpacing, var(--sn-primitive-font-letterSpacing-m, 0.1px));
80
+ paragraph-spacing:var(--sn-regular-body-l-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize16, 8px));
81
+ }
82
+
83
+ .contentArea{
84
+ position:relative;
85
+ }
86
+ [data-size=s] .contentArea{
87
+ padding-top:var(--sn-field-anatomy-size-s-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-s, var(--sn-primitive-dimension-8, 8px)));
88
+ padding-bottom:var(--sn-field-anatomy-size-s-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-s, var(--sn-primitive-dimension-8, 8px)));
89
+ }
90
+ [data-size=m] .contentArea{
91
+ padding-top:var(--sn-field-anatomy-size-m-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-m, var(--sn-primitive-dimension-8, 8px)));
92
+ padding-bottom:var(--sn-field-anatomy-size-m-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-m, var(--sn-primitive-dimension-8, 8px)));
93
+ }
94
+ [data-size=l] .contentArea{
95
+ padding-top:var(--sn-field-anatomy-size-l-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-l, var(--sn-primitive-dimension-8, 8px)));
96
+ padding-bottom:var(--sn-field-anatomy-size-l-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-l, var(--sn-primitive-dimension-8, 8px)));
97
+ }
98
+
99
+ .postfixColumn{
100
+ position:absolute;
101
+ display:grid;
102
+ grid-template-columns:100%;
103
+ row-gap:var(--sn-primitive-dimension-2, 2px);
104
+ place-items:center center;
105
+ }
106
+ [data-size=s] .postfixColumn{
107
+ top:calc(var(--sn-field-anatomy-size-s-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-s, var(--sn-primitive-dimension-8, 8px))) + (var(--sn-regular-body-s-lineHeight, var(--sn-density-typography-roleBody-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px))) - var(--sn-field-anatomy-size-s-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)))) / 2);
108
+ right:calc(var(--sn-scroll-anatomy-container-size-s-square, var(--sn-primitive-dimension-8, 8px)) + var(--sn-field-anatomy-size-s-fieldContainer-contentWrapper-inputLine-horizontalPadding, var(--sn-density-spacing-control-wrapper-horizontal-s, var(--sn-primitive-dimension-8, 8px))));
109
+ grid-auto-rows:var(--sn-field-anatomy-size-s-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
110
+ width:var(--sn-field-anatomy-size-s-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
111
+ }
112
+ [data-size=m] .postfixColumn{
113
+ top:calc(var(--sn-field-anatomy-size-m-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-m, var(--sn-primitive-dimension-8, 8px))) + (var(--sn-regular-body-m-lineHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px))) - var(--sn-field-anatomy-size-m-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)))) / 2);
114
+ right:calc(var(--sn-scroll-anatomy-container-size-s-square, var(--sn-primitive-dimension-8, 8px)) + var(--sn-field-anatomy-size-m-fieldContainer-contentWrapper-inputLine-horizontalPadding, var(--sn-density-spacing-control-wrapper-horizontal-m, var(--sn-primitive-dimension-8, 8px))));
115
+ grid-auto-rows:var(--sn-field-anatomy-size-m-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)));
116
+ width:var(--sn-field-anatomy-size-m-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)));
117
+ }
118
+ [data-size=l] .postfixColumn{
119
+ top:calc(var(--sn-field-anatomy-size-l-fieldContainer-contentWrapper-verticalPadding, var(--sn-density-spacing-control-wrapper-vertical-l, var(--sn-primitive-dimension-8, 8px))) + (var(--sn-regular-body-l-lineHeight, var(--sn-density-typography-roleBody-lineHeightL, var(--sn-primitive-font-lineHeight-by20, 28px))) - var(--sn-field-anatomy-size-l-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightL, var(--sn-primitive-font-lineHeight-by20, 28px)))) / 2);
120
+ right:calc(var(--sn-scroll-anatomy-container-size-s-square, var(--sn-primitive-dimension-8, 8px)) + var(--sn-field-anatomy-size-l-fieldContainer-contentWrapper-inputLine-horizontalPadding, var(--sn-density-spacing-control-wrapper-horizontal-l, var(--sn-primitive-dimension-12, 12px))));
121
+ grid-auto-rows:var(--sn-field-anatomy-size-l-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightL, var(--sn-primitive-font-lineHeight-by20, 28px)));
122
+ width:var(--sn-field-anatomy-size-l-fieldContainer-centeredWrapper-maxHeight, var(--sn-density-typography-roleBody-lineHeightL, var(--sn-primitive-font-lineHeight-by20, 28px)));
123
+ }
@@ -0,0 +1,74 @@
1
+ import { TimeValue } from '@cloud-ru/ds-calendar';
2
+ import { FieldDecoratorProps } from '@cloud-ru/ds-field-decorator';
3
+ import { FocusEvent } from 'react';
4
+ import { FieldLayoutPresets } from '../../hooks';
5
+ type FieldTimeDecoratorProps = Omit<FieldDecoratorProps, 'children'>;
6
+ type FieldTimeOwnProps = {
7
+ /** CSS-класс корня `FieldDecorator` */
8
+ className?: string;
9
+ /** CSS-класс оболочки поля */
10
+ fieldClassName?: string;
11
+ /** Значение */
12
+ value?: TimeValue;
13
+ /** Дефолтное значение для uncontrolled-режима */
14
+ defaultValue?: TimeValue;
15
+ /** Колбек смены значения */
16
+ onChange?(value: TimeValue | undefined): void;
17
+ /** Плейсхолдер маски; по умолчанию `чч:мм:сс` или `чч:мм` в зависимости от `showSeconds`. */
18
+ placeholder?: string;
19
+ /** Открыт ли picker (controlled) */
20
+ open?: boolean;
21
+ /** Колбек смены состояния открытия */
22
+ onOpenChange?(open: boolean): void;
23
+ /**
24
+ * Показывать секунды в picker и в маске input.
25
+ * @default true
26
+ */
27
+ showSeconds?: boolean;
28
+ /**
29
+ * Закрыть picker после Apply.
30
+ * @default true
31
+ */
32
+ closeOnApply?: boolean;
33
+ /**
34
+ * Показывать кнопку очистки (видна при value && !readonly && !disabled).
35
+ * @default true
36
+ */
37
+ showClearButton?: boolean;
38
+ /** Колбек после клика по кнопке очистки. */
39
+ onClearButtonClick?(): void;
40
+ /**
41
+ * Показывать кнопку копирования (видна при readonly && value && !disabled).
42
+ * @default true
43
+ */
44
+ showCopyButton?: boolean;
45
+ /** Колбек после копирования значения. */
46
+ onCopyButtonClick?(): void;
47
+ /**
48
+ * Фон поля (acrylic).
49
+ * @default true
50
+ */
51
+ background?: boolean;
52
+ /** Отключено */
53
+ disabled?: boolean;
54
+ /** Только для чтения */
55
+ readonly?: boolean;
56
+ /** Автофокус. На mobile выключается адаптивно (см. `layoutPresets`) */
57
+ autoFocus?: boolean;
58
+ /**
59
+ * Переопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен
60
+ * (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`.
61
+ */
62
+ layoutPresets?: FieldLayoutPresets;
63
+ /** HTML id */
64
+ id?: string;
65
+ /** HTML name */
66
+ name?: string;
67
+ /** Колбек фокуса input */
68
+ onFocus?(event: FocusEvent<HTMLInputElement>): void;
69
+ /** Колбек блюра input */
70
+ onBlur?(event: FocusEvent<HTMLInputElement>): void;
71
+ };
72
+ export type FieldTimeProps = FieldTimeDecoratorProps & FieldTimeOwnProps;
73
+ export declare const FieldTime: import("react").ForwardRefExoticComponent<FieldTimeDecoratorProps & FieldTimeOwnProps & import("react").RefAttributes<HTMLInputElement>>;
74
+ export {};
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FieldTime = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const calendar_1 = require("@cloud-ru/ds-calendar");
9
+ const field_decorator_1 = require("@cloud-ru/ds-field-decorator");
10
+ const system_1 = require("@cloud-ru/ds-icons/interface/system");
11
+ const input_private_1 = require("@cloud-ru/ds-input-private");
12
+ const utils_1 = require("@cloud-ru/ds-utils");
13
+ const classnames_1 = __importDefault(require("classnames"));
14
+ const merge_refs_1 = __importDefault(require("merge-refs"));
15
+ const react_1 = require("react");
16
+ const constants_1 = require("../../constants");
17
+ const hooks_1 = require("../../hooks");
18
+ const segments_1 = require("../../segments");
19
+ const shared_1 = require("../shared");
20
+ const styles_module_scss_1 = __importDefault(require('../shared/styles.module.css'));
21
+ const mask_1 = require("./mask");
22
+ const styles_module_scss_2 = __importDefault(require('./styles.module.css'));
23
+ exports.FieldTime = (0, react_1.forwardRef)(function FieldTime({ label = '', labelTooltip, caption, hint, error, validationState = field_decorator_1.VALIDATION_STATE.Default, showHintIcon, length, required, size = field_decorator_1.SIZE.M, className, fieldClassName, background = true, value: valueProp, defaultValue, onChange, open: openProp, onOpenChange, showSeconds = true, closeOnApply = true, showClearButton: showClearButtonProp = true, onClearButtonClick, showCopyButton: showCopyButtonProp = true, onCopyButtonClick, disabled, readonly: readOnly, autoFocus, layoutPresets, id, name, placeholder, onFocus: onFocusProp, onBlur: onBlurProp, 'data-test-id': dataTestId = constants_1.TEST_IDS.fieldTime, ...rest }, ref) {
24
+ const localRef = (0, react_1.useRef)(null);
25
+ const clearButtonRef = (0, react_1.useRef)(null);
26
+ const copyButtonRef = (0, react_1.useRef)(null);
27
+ const navigationStartRef = (0, react_1.useRef)(null);
28
+ const [hover, setHover] = (0, react_1.useState)(false);
29
+ const [focusVisible, setFocusVisible] = (0, react_1.useState)(false);
30
+ const [openLocal, setOpenLocal] = (0, react_1.useState)(false);
31
+ const open = openProp ?? openLocal;
32
+ const [valueLocal, setValueLocal] = (0, react_1.useState)(defaultValue);
33
+ const value = valueProp ?? valueLocal;
34
+ const resolvedAutoFocus = (0, hooks_1.useAdaptiveAutoFocus)(autoFocus, layoutPresets);
35
+ const { mask: segMask, slots: segSlots } = (0, react_1.useMemo)(() => (0, segments_1.buildSegments)('time', showSeconds), [showSeconds]);
36
+ const placeholderMask = placeholder ?? segMask;
37
+ const effectiveValidationState = (0, react_1.useMemo)(() => (error ? field_decorator_1.VALIDATION_STATE.Error : validationState), [error, validationState]);
38
+ const [inputValue, setInputValue] = (0, react_1.useState)(value ? (0, mask_1.timeToMaskString)(value, showSeconds) : '');
39
+ (0, react_1.useEffect)(() => {
40
+ // Пока поле в фокусе — значением владеет сегментный движок (keydown), внешний sync пропускаем,
41
+ // иначе setInputValue из эффекта дерётся с движком и зацикливает рендер.
42
+ if (localRef.current && document.activeElement === localRef.current)
43
+ return;
44
+ setInputValue(value ? (0, mask_1.timeToMaskString)(value, showSeconds) : '');
45
+ }, [value, showSeconds]);
46
+ const emitChange = (0, react_1.useCallback)((next) => {
47
+ if (valueProp === undefined)
48
+ setValueLocal(next);
49
+ onChange?.(next);
50
+ }, [onChange, valueProp]);
51
+ const handleOpenChange = (0, react_1.useCallback)((next) => {
52
+ if (openProp === undefined)
53
+ setOpenLocal(next);
54
+ onOpenChange?.(next);
55
+ }, [openProp, onOpenChange]);
56
+ const timeSeg = (0, segments_1.useSegmentedMask)({
57
+ inputRef: localRef,
58
+ mask: segMask,
59
+ slots: segSlots,
60
+ readonly: readOnly,
61
+ disabled,
62
+ setValue: setInputValue,
63
+ onMaskedChange: masked => {
64
+ if (masked === '') {
65
+ emitChange(undefined);
66
+ return;
67
+ }
68
+ const parsed = (0, mask_1.parseTimeMask)(masked, showSeconds);
69
+ if (parsed)
70
+ emitChange(parsed);
71
+ },
72
+ onArrowDown: () => {
73
+ handleOpenChange(true);
74
+ // Клавиатурный handoff в picker (барабаны времени), паритет с легаси.
75
+ setTimeout(() => navigationStartRef.current?.focus(), 0);
76
+ },
77
+ // ArrowUp в поле закрывает открытый picker (фокус остаётся в input на текущем сегменте).
78
+ onArrowUp: () => handleOpenChange(false),
79
+ onEscape: () => handleOpenChange(false),
80
+ onEdit: () => handleOpenChange(false),
81
+ });
82
+ const onClear = (0, react_1.useCallback)(() => {
83
+ setInputValue('');
84
+ emitChange(undefined);
85
+ onClearButtonClick?.();
86
+ if (required) {
87
+ localRef.current?.focus();
88
+ handleOpenChange(true);
89
+ }
90
+ else {
91
+ localRef.current?.blur();
92
+ handleOpenChange(false);
93
+ }
94
+ }, [emitChange, handleOpenChange, onClearButtonClick, required]);
95
+ const onCopy = (0, react_1.useCallback)(async () => {
96
+ const copied = Boolean(inputValue) && (await (0, shared_1.copyTextToClipboard)(inputValue));
97
+ if (copied) {
98
+ onCopyButtonClick?.();
99
+ }
100
+ return copied;
101
+ }, [inputValue, onCopyButtonClick]);
102
+ const showClearUi = Boolean(showClearButtonProp && inputValue && !disabled && !readOnly);
103
+ const showCopyUi = Boolean(showCopyButtonProp && inputValue && !disabled && readOnly);
104
+ const clearButtonSettings = (0, input_private_1.useClearButton)({
105
+ clearButtonRef,
106
+ showClearButton: showClearUi,
107
+ size: (0, shared_1.toInputSize)(size),
108
+ onClear,
109
+ disabled: Boolean(disabled || readOnly),
110
+ });
111
+ const copyButtonSettings = (0, shared_1.useCopyButton)({
112
+ copyButtonRef,
113
+ showCopyButton: showCopyUi,
114
+ size: (0, shared_1.toInputSize)(size),
115
+ onCopy,
116
+ disabled: Boolean(disabled),
117
+ });
118
+ const { postfixButtons, inputTabIndex, onInputKeyDown } = (0, input_private_1.useButtonNavigation)({
119
+ inputRef: localRef,
120
+ postfixButtons: (0, react_1.useMemo)(() => [clearButtonSettings, copyButtonSettings], [clearButtonSettings, copyButtonSettings]),
121
+ readonly: Boolean(readOnly),
122
+ submitKeys: ['Enter', 'Space', 'Tab'],
123
+ });
124
+ const handleMouseEnter = (0, react_1.useCallback)(() => {
125
+ if (!readOnly && !disabled) {
126
+ setHover(true);
127
+ }
128
+ }, [readOnly, disabled]);
129
+ const handleMouseLeave = (0, react_1.useCallback)(() => {
130
+ setHover(false);
131
+ }, []);
132
+ const handleInputKeyDown = (0, react_1.useCallback)((event) => {
133
+ timeSeg.handleKeyDown(event);
134
+ // Нав-цепочка бежит безусловно ПОСЛЕ движка (легаси-порядок useHandlers): движок мутирует
135
+ // selection синхронно (ArrowRight на последнем сегменте ставит каретку в конец), nav читает
136
+ // её в том же keydown и забирает фокус на postfix-кнопки. Гейт по defaultPrevented оставлял
137
+ // clear/copy недостижимыми со стрелок — движок всегда делает preventDefault на ArrowRight.
138
+ onInputKeyDown(event);
139
+ }, [onInputKeyDown, timeSeg]);
140
+ // value ведёт сегментный движок (keydown); нативный onChange input'а игнорируем.
141
+ const handleInputChange = (0, react_1.useCallback)(() => undefined, []);
142
+ const handleInputFocus = (0, react_1.useCallback)((event) => {
143
+ setFocusVisible(event.target.matches(':focus-visible'));
144
+ timeSeg.handleFocus();
145
+ onFocusProp?.(event);
146
+ }, [onFocusProp, timeSeg]);
147
+ const handleInputBlur = (0, react_1.useCallback)((event) => {
148
+ setFocusVisible(false);
149
+ timeSeg.handleBlur();
150
+ onBlurProp?.(event);
151
+ }, [onBlurProp, timeSeg]);
152
+ const trigger = ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(styles_module_scss_1.default.fieldWrapper, styles_module_scss_2.default.trigger, fieldClassName), "data-size": size, "data-validation-state": effectiveValidationState, "data-disabled": disabled || undefined, "data-readonly": readOnly || undefined, "data-withbackground": background || undefined, "data-focusvisible": focusVisible || open || undefined, "data-hover": !readOnly && !disabled && hover ? true : undefined, "data-test-id": dataTestId, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.backgroundWrapper, children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.materialLayer, ...(0, shared_1.getAcrylicProps)({
153
+ validationState: effectiveValidationState,
154
+ disabled,
155
+ readonly: readOnly,
156
+ hover,
157
+ focusVisible: focusVisible || open,
158
+ }), children: (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.acrylicBg, "aria-hidden": true }) }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.borderStateLayer, "data-state": 'borderOnBackground' }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.focusLayer })] }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.fieldContainer, children: (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.contentWrapper, children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.inputLine, children: (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.inputArea, children: [(0, jsx_runtime_1.jsx)(input_private_1.InputPrivate, { ref: (0, merge_refs_1.default)(ref, localRef), className: styles_module_scss_1.default.fieldInput, value: inputValue, onChange: handleInputChange, disabled: disabled, readonly: readOnly, placeholder: placeholderMask, inputMode: input_private_1.INPUT_MODE.Numeric, tabIndex: inputTabIndex, onClick: timeSeg.handleClick, onPaste: timeSeg.handlePaste, onFocus: handleInputFocus, onBlur: handleInputBlur, onKeyDown: handleInputKeyDown, id: id, name: name, autoFocus: resolvedAutoFocus, "aria-haspopup": 'dialog', "aria-expanded": open, ...(0, utils_1.extractSupportProps)(rest), "data-test-id": constants_1.TEST_IDS.fieldTimeInput }), postfixButtons && (0, jsx_runtime_1.jsx)("span", { className: styles_module_scss_1.default.postfixButtonsSlot, children: postfixButtons })] }) }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.iconSlot, "data-test-id": constants_1.TEST_IDS.fieldTimeIcon, "aria-hidden": true, children: (0, jsx_runtime_1.jsx)(system_1.WatchSVG, {}) })] }) })] }));
159
+ return ((0, jsx_runtime_1.jsx)(field_decorator_1.FieldDecorator, { className: className, label: label, labelTooltip: labelTooltip, caption: caption, hint: hint, error: error, validationState: validationState, showHintIcon: showHintIcon, length: length, required: required, labelFor: id, disabled: disabled, readonly: readOnly, size: size, children: (0, jsx_runtime_1.jsx)(calendar_1.TimePickerDropdown
160
+ // Явный data-test-id на дропдауне → детерминированный id портального контента:
161
+ // `getTestIdBuilder` строит `content-${id}`, так контент адресуем для open-picker-снимка
162
+ // (без него контент рисуется без data-test-id, а в @cloud-ru/ds-fields::TEST_IDS такого слота нет).
163
+ , { "data-test-id": `${dataTestId}__picker`, size: size, value: value, onChangeValue: emitChange, showSeconds: showSeconds, closeOnApply: closeOnApply, open: open && !disabled && !readOnly, onOpenChange: handleOpenChange, trigger: 'click', placement: 'bottom-start', navigationStartRef: navigationStartRef, onFocusLeave: () => {
164
+ localRef.current?.focus();
165
+ handleOpenChange(false);
166
+ }, children: trigger }) }));
167
+ });
@@ -0,0 +1,2 @@
1
+ export * from './FieldTime';
2
+ export type { TimeValue } from '@cloud-ru/ds-calendar';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./FieldTime"), exports);
@@ -0,0 +1,3 @@
1
+ import { TimeValue } from '@cloud-ru/ds-calendar';
2
+ export declare function parseTimeMask(input: string, showSeconds: boolean): TimeValue | undefined;
3
+ export declare function timeToMaskString(value: TimeValue, showSeconds: boolean): string;