@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,457 @@
1
+ import { Button } from '@cloud-ru/ds-button';
2
+ import { Divider } from '@cloud-ru/ds-divider';
3
+ import { FieldDecorator, FieldDecoratorProps, SIZE, VALIDATION_STATE } from '@cloud-ru/ds-field-decorator';
4
+ import { CheckSVG, CopySVG, MinusSVG, PlusSVG } from '@cloud-ru/ds-icons/interface/system';
5
+ import { BUTTON_SIZE_MAP, InputPrivate, TYPE } from '@cloud-ru/ds-input-private';
6
+ import { Tooltip, TooltipProps } from '@cloud-ru/ds-tooltip';
7
+ import { extractSupportProps, useValueControl } from '@cloud-ru/ds-utils';
8
+ import cn from 'classnames';
9
+ import mergeRefs from 'merge-refs';
10
+ import {
11
+ ChangeEvent,
12
+ CSSProperties,
13
+ FocusEvent,
14
+ forwardRef,
15
+ KeyboardEvent,
16
+ MouseEvent,
17
+ ReactNode,
18
+ useCallback,
19
+ useEffect,
20
+ useMemo,
21
+ useRef,
22
+ useState,
23
+ } from 'react';
24
+
25
+ import { TEST_IDS } from '../../constants';
26
+ import { FieldLayoutPresets, useAdaptiveAutoFocus } from '../../hooks';
27
+ import { copyTextToClipboard, FieldElementButton, getAcrylicProps, VARIANT } from '../shared';
28
+ import fieldStyles from '../shared/styles.module.scss';
29
+ import styles from './styles.module.scss';
30
+ import { applyStep, clamp, defaultClampMaxText, defaultClampMinText, getDefaultValue } from './utils';
31
+
32
+ type FieldStepperDecoratorProps = Omit<FieldDecoratorProps, 'children'>;
33
+
34
+ type FieldStepperOwnProps = {
35
+ /** CSS-класс корня `FieldDecorator` */
36
+ className?: string;
37
+ /** CSS-класс оболочки поля */
38
+ fieldClassName?: string;
39
+ /** Значение (controlled-режим) */
40
+ value?: number;
41
+ /** Начальное значение (uncontrolled-режим). По умолчанию выводится из `min`/`max`. */
42
+ defaultValue?: number;
43
+ /** Колбек смены значения. Второй аргумент — событие, если изменение пришло из ручного ввода. */
44
+ onChange?(value: number, event?: ChangeEvent<HTMLInputElement>): void;
45
+ /** Минимум */
46
+ min?: number;
47
+ /** Максимум */
48
+ max?: number;
49
+ /**
50
+ * Шаг приращения
51
+ * @default 1
52
+ */
53
+ step?: number;
54
+ /**
55
+ * Разрешить ввод значений вне `min`/`max`. Если `false`, на blur значение клампится.
56
+ * @default true
57
+ */
58
+ allowMoreThanLimits?: boolean;
59
+ /** Поле выключено */
60
+ disabled?: boolean;
61
+ /** Только для чтения */
62
+ readonly?: boolean;
63
+ /** HTML id */
64
+ id?: string;
65
+ /** HTML name */
66
+ name?: string;
67
+ /** Автофокус. На mobile выключается адаптивно (см. `layoutPresets`) */
68
+ autoFocus?: boolean;
69
+ /**
70
+ * Переопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен
71
+ * (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`.
72
+ */
73
+ layoutPresets?: FieldLayoutPresets;
74
+ /**
75
+ * Фон поля (acrylic)
76
+ * @default true
77
+ */
78
+ background?: boolean;
79
+ /**
80
+ * Показывать кнопку копирования значения (видна в readonly, при `!disabled`).
81
+ * @default true
82
+ */
83
+ showCopyButton?: boolean;
84
+ /** Колбек после успешного копирования значения. */
85
+ onCopyButtonClick?(): void;
86
+ /** Префикс — текст или иконка слева от значения */
87
+ prefix?: ReactNode;
88
+ /** Постфикс — текст или иконка справа от значения (например, единица измерения) */
89
+ postfix?: ReactNode;
90
+ /** Тултип над кнопкой `+` */
91
+ plusButtonTooltip?: TooltipProps;
92
+ /** Тултип над кнопкой `−` */
93
+ minusButtonTooltip?: TooltipProps;
94
+ /**
95
+ * Тексты тултипа клампа (показывается на 2с после blur с выходом за `min`/`max`).
96
+ * @default { min: 'Значение должно быть больше либо равно {value}', max: 'Значение должно быть меньше либо равно {value}' }
97
+ */
98
+ clampTooltipText?: {
99
+ min?: (value: number) => string;
100
+ max?: (value: number) => string;
101
+ };
102
+ /** Колбек фокуса */
103
+ onFocus?(event: FocusEvent<HTMLInputElement>): void;
104
+ /** Колбек блюра */
105
+ onBlur?(event: FocusEvent<HTMLInputElement>): void;
106
+ };
107
+
108
+ export type FieldStepperProps = FieldStepperDecoratorProps & FieldStepperOwnProps;
109
+
110
+ export const FieldStepper = forwardRef<HTMLInputElement, FieldStepperProps>(function FieldStepper(
111
+ {
112
+ label = '',
113
+ labelTooltip,
114
+ caption,
115
+ hint,
116
+ error,
117
+ validationState = VALIDATION_STATE.Default,
118
+ showHintIcon,
119
+ length,
120
+ required,
121
+ size = SIZE.M,
122
+ className,
123
+ fieldClassName,
124
+ background = true,
125
+ showCopyButton = true,
126
+ onCopyButtonClick,
127
+ value: valueProp,
128
+ defaultValue,
129
+ onChange,
130
+ min,
131
+ max,
132
+ step = 1,
133
+ allowMoreThanLimits = true,
134
+ disabled,
135
+ readonly: readOnly,
136
+ id,
137
+ name,
138
+ autoFocus,
139
+ layoutPresets,
140
+ prefix,
141
+ postfix,
142
+ plusButtonTooltip,
143
+ minusButtonTooltip,
144
+ clampTooltipText,
145
+ onFocus,
146
+ onBlur,
147
+ 'data-test-id': dataTestId,
148
+ ...rest
149
+ },
150
+ ref,
151
+ ) {
152
+ const localRef = useRef<HTMLInputElement>(null);
153
+ const copyButtonRef = useRef<HTMLButtonElement>(null);
154
+ const [focusVisible, setFocusVisible] = useState(false);
155
+ const [hover, setHover] = useState(false);
156
+ const [clampTooltip, setClampTooltip] = useState<string | null>(null);
157
+ const [copied, setCopied] = useState(false);
158
+ const clampTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
159
+ const copiedTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
160
+
161
+ const resolvedAutoFocus = useAdaptiveAutoFocus(autoFocus, layoutPresets);
162
+
163
+ useEffect(
164
+ () => () => {
165
+ if (clampTimerRef.current) {
166
+ clearTimeout(clampTimerRef.current);
167
+ }
168
+ if (copiedTimerRef.current) {
169
+ clearTimeout(copiedTimerRef.current);
170
+ }
171
+ },
172
+ [],
173
+ );
174
+
175
+ // controlled/uncontrolled: внутреннее состояние при отсутствии `value`; событие в `onChange`
176
+ // (ручной ввод) пробрасываем сами, useValueControl передаёт только значение.
177
+ const [value = getDefaultValue(min, max), setValue] = useValueControl<number>({ value: valueProp, defaultValue });
178
+
179
+ const effectiveValidationState = useMemo(
180
+ () => (error ? VALIDATION_STATE.Error : validationState),
181
+ [error, validationState],
182
+ );
183
+
184
+ const isMinusDisabled = (typeof min === 'number' && value <= min) || disabled || readOnly;
185
+ const isPlusDisabled = (typeof max === 'number' && value >= max) || disabled || readOnly;
186
+
187
+ // Кнопки −/+ и ручной ввод приводятся к единой модели относительно `allowMoreThanLimits`:
188
+ // при `false` значение клампится сразу, при `true` остаётся как есть (кламп откладывается до blur).
189
+ const emitValue = useCallback(
190
+ (next: number, event?: ChangeEvent<HTMLInputElement>) => {
191
+ const resolved = allowMoreThanLimits ? next : clamp(next, min, max);
192
+ setValue(resolved);
193
+ onChange?.(resolved, event);
194
+ },
195
+ [allowMoreThanLimits, max, min, onChange, setValue],
196
+ );
197
+
198
+ const handleMinus = useCallback(() => {
199
+ emitValue(applyStep(value, -step));
200
+ }, [emitValue, step, value]);
201
+
202
+ const handlePlus = useCallback(() => {
203
+ emitValue(applyStep(value, step));
204
+ }, [emitValue, step, value]);
205
+
206
+ const handleInputChange = useCallback(
207
+ (raw: string, event?: ChangeEvent<HTMLInputElement>) => {
208
+ if (raw === '' || raw === '-') {
209
+ return;
210
+ }
211
+ const parsed = Number(raw);
212
+ if (Number.isNaN(parsed)) {
213
+ return;
214
+ }
215
+ // Во время набора значение не клампим даже при allowMoreThanLimits=false —
216
+ // кламп откладывается до blur (паритет с легаси), там же показывается clampTooltip.
217
+ setValue(parsed);
218
+ onChange?.(parsed, event);
219
+ },
220
+ [onChange, setValue],
221
+ );
222
+
223
+ const showClampTooltip = useCallback((message: string) => {
224
+ setClampTooltip(message);
225
+ if (clampTimerRef.current) {
226
+ clearTimeout(clampTimerRef.current);
227
+ }
228
+ clampTimerRef.current = setTimeout(() => setClampTooltip(null), 2000);
229
+ }, []);
230
+
231
+ const handleBlur = useCallback(
232
+ (event: FocusEvent<HTMLInputElement>) => {
233
+ if (!allowMoreThanLimits) {
234
+ if (typeof max === 'number' && value > max) {
235
+ setValue(max);
236
+ onChange?.(max);
237
+ showClampTooltip((clampTooltipText?.max ?? defaultClampMaxText)(max));
238
+ } else if (typeof min === 'number' && value < min) {
239
+ setValue(min);
240
+ onChange?.(min);
241
+ showClampTooltip((clampTooltipText?.min ?? defaultClampMinText)(min));
242
+ }
243
+ }
244
+ onBlur?.(event);
245
+ },
246
+ [allowMoreThanLimits, clampTooltipText, max, min, onBlur, onChange, setValue, showClampTooltip, value],
247
+ );
248
+
249
+ const handleFocus = useCallback(
250
+ (event: FocusEvent<HTMLInputElement>) => {
251
+ setFocusVisible(event.target.matches(':focus-visible'));
252
+ if (clampTimerRef.current) {
253
+ clearTimeout(clampTimerRef.current);
254
+ }
255
+ setClampTooltip(null);
256
+ onFocus?.(event);
257
+ },
258
+ [onFocus],
259
+ );
260
+
261
+ // Ширина инпута по числу символов значения (минимум 2ch), задаётся через `ch`-юниты в CSS-переменной —
262
+ // без px-хардкода и подгонки под ширину глифа.
263
+ const inputWidthCh = Math.max(2, String(value).length);
264
+
265
+ const handleMouseEnter = useCallback(() => {
266
+ if (!readOnly) {
267
+ setHover(true);
268
+ }
269
+ }, [readOnly]);
270
+
271
+ const handleMouseLeave = useCallback(() => {
272
+ setHover(false);
273
+ }, []);
274
+
275
+ const showCopyUi = Boolean(showCopyButton && readOnly && !disabled);
276
+
277
+ const handleCopy = useCallback(
278
+ (event: MouseEvent<HTMLButtonElement>) => {
279
+ event.preventDefault();
280
+ event.stopPropagation();
281
+ copyTextToClipboard(String(value)).then(copied => {
282
+ if (!copied) {
283
+ return;
284
+ }
285
+ onCopyButtonClick?.();
286
+ setCopied(true);
287
+ if (copiedTimerRef.current) {
288
+ clearTimeout(copiedTimerRef.current);
289
+ }
290
+ copiedTimerRef.current = setTimeout(() => setCopied(false), 2000);
291
+ });
292
+ },
293
+ [onCopyButtonClick, value],
294
+ );
295
+
296
+ // Клавиатурный путь к copy в readonly (кнопка с tabIndex −1 недостижима по Tab): ArrowRight из
297
+ // инпута → copy, ArrowLeft с copy → назад. input type=number не даёт selection API — гейт только
298
+ // по readonly. Кнопки −/+ остаются вне пути (tabIndex −1, паритет с легаси ButtonFunction).
299
+ const handleInputKeyDown = useCallback(
300
+ (event: KeyboardEvent<HTMLInputElement>) => {
301
+ if (event.key === 'ArrowRight' && readOnly && showCopyUi && copyButtonRef.current) {
302
+ event.preventDefault();
303
+ copyButtonRef.current.focus();
304
+ }
305
+ },
306
+ [readOnly, showCopyUi],
307
+ );
308
+
309
+ const handleCopyButtonKeyDown = useCallback((event: KeyboardEvent<HTMLButtonElement>) => {
310
+ if (event.key === 'ArrowLeft') {
311
+ event.preventDefault();
312
+ localRef.current?.focus();
313
+ }
314
+ }, []);
315
+
316
+ const renderStepButton = (variant: 'minus' | 'plus') => {
317
+ const isMinus = variant === 'minus';
318
+ const tooltip = isMinus ? minusButtonTooltip : plusButtonTooltip;
319
+ const button = (
320
+ <FieldElementButton
321
+ variant={isMinus ? VARIANT.Before : VARIANT.After}
322
+ size={size}
323
+ action={isMinus ? <MinusSVG /> : <PlusSVG />}
324
+ onClick={isMinus ? handleMinus : handlePlus}
325
+ disabled={isMinus ? isMinusDisabled : isPlusDisabled}
326
+ tabIndex={-1}
327
+ data-test-id={isMinus ? TEST_IDS.fieldStepperMinus : TEST_IDS.fieldStepperPlus}
328
+ />
329
+ );
330
+
331
+ return tooltip ? (
332
+ <Tooltip {...tooltip} triggerClassName={styles.stepButtonTrigger}>
333
+ {button}
334
+ </Tooltip>
335
+ ) : (
336
+ button
337
+ );
338
+ };
339
+
340
+ const shell = (
341
+ <div
342
+ className={cn(fieldStyles.fieldWrapper, fieldClassName)}
343
+ data-size={size}
344
+ data-validation-state={effectiveValidationState}
345
+ data-disabled={disabled || undefined}
346
+ data-readonly={readOnly || undefined}
347
+ data-withbackground={background || undefined}
348
+ data-focusvisible={focusVisible || undefined}
349
+ data-hover={!readOnly && hover ? true : undefined}
350
+ onMouseEnter={handleMouseEnter}
351
+ onMouseLeave={handleMouseLeave}
352
+ >
353
+ <div className={fieldStyles.backgroundWrapper}>
354
+ <div
355
+ className={fieldStyles.materialLayer}
356
+ {...getAcrylicProps({
357
+ validationState: effectiveValidationState,
358
+ disabled,
359
+ readonly: readOnly,
360
+ hover,
361
+ focusVisible,
362
+ })}
363
+ >
364
+ <div className={fieldStyles.acrylicBg} aria-hidden />
365
+ </div>
366
+ <div className={fieldStyles.borderStateLayer} data-state='borderOnBackground' />
367
+ <div className={fieldStyles.focusLayer} />
368
+ </div>
369
+ <div className={fieldStyles.elementWrapperBefore}>
370
+ {renderStepButton('minus')}
371
+ <div className={fieldStyles.lineWrapper} data-outline={background || undefined}>
372
+ <Divider orientation='vertical' variant='regular' />
373
+ </div>
374
+ </div>
375
+ <div className={fieldStyles.fieldContainer}>
376
+ <div className={fieldStyles.contentWrapper}>
377
+ <div className={styles.valueArea}>
378
+ {prefix && <span className={styles.affix}>{prefix}</span>}
379
+ <div className={styles.inputWrapper} style={{ '--field-stepper-input-ch': inputWidthCh } as CSSProperties}>
380
+ <InputPrivate
381
+ ref={mergeRefs(ref, localRef)}
382
+ className={cn(fieldStyles.fieldInput, styles.input)}
383
+ value={String(value)}
384
+ type={TYPE.Number}
385
+ disabled={disabled}
386
+ readonly={readOnly}
387
+ onChange={handleInputChange}
388
+ onFocus={handleFocus}
389
+ onBlur={handleBlur}
390
+ onKeyDown={handleInputKeyDown}
391
+ id={id}
392
+ name={name}
393
+ min={min}
394
+ max={max}
395
+ step={step}
396
+ autoFocus={resolvedAutoFocus}
397
+ data-test-id={TEST_IDS.fieldStepperInput}
398
+ {...extractSupportProps(rest)}
399
+ />
400
+ </div>
401
+ {postfix && <span className={styles.affix}>{postfix}</span>}
402
+ </div>
403
+ </div>
404
+ </div>
405
+ <div className={fieldStyles.elementWrapperAfter}>
406
+ {showCopyUi && (
407
+ <span className={styles.copyButton}>
408
+ <Button
409
+ innerRef={copyButtonRef}
410
+ type='button'
411
+ view='function'
412
+ appearance='neutral'
413
+ size={BUTTON_SIZE_MAP[size]}
414
+ icon={copied ? <CheckSVG /> : <CopySVG />}
415
+ onClick={handleCopy}
416
+ onKeyDown={handleCopyButtonKeyDown}
417
+ tabIndex={-1}
418
+ data-test-id={TEST_IDS.fieldStepperCopyButton}
419
+ />
420
+ </span>
421
+ )}
422
+ <div className={fieldStyles.lineWrapper} data-outline={background || undefined}>
423
+ <Divider orientation='vertical' variant='regular' />
424
+ </div>
425
+ {renderStepButton('plus')}
426
+ </div>
427
+ </div>
428
+ );
429
+
430
+ return (
431
+ <FieldDecorator
432
+ className={className}
433
+ label={label}
434
+ labelTooltip={labelTooltip}
435
+ caption={caption}
436
+ hint={hint}
437
+ error={error}
438
+ validationState={effectiveValidationState}
439
+ showHintIcon={showHintIcon}
440
+ length={length}
441
+ required={required}
442
+ labelFor={id}
443
+ disabled={disabled}
444
+ readonly={readOnly}
445
+ size={size}
446
+ data-test-id={dataTestId}
447
+ >
448
+ {clampTooltip ? (
449
+ <Tooltip tip={clampTooltip} open data-test-id={TEST_IDS.fieldStepperLimitTooltip}>
450
+ {shell}
451
+ </Tooltip>
452
+ ) : (
453
+ shell
454
+ )}
455
+ </FieldDecorator>
456
+ );
457
+ });
@@ -0,0 +1 @@
1
+ export * from './FieldStepper';
@@ -0,0 +1,98 @@
1
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
2
+ @use '@cloud-ru/ds-figma-variables/build/scss/components/field.module' as field;
3
+
4
+ $sizes: 's', 'm', 'l';
5
+
6
+ // Figma-typo-мост: stepper inputLine.gap для size=m ссылается на токен size=s (=2px),
7
+ // а не на size=m (=4px). s→s(2), m→s(2), l→l(6).
8
+ $inputLineGapSizes: (
9
+ 's': 's',
10
+ 'm': 's',
11
+ 'l': 'l',
12
+ );
13
+
14
+ // Tooltip оборачивает −/+ в block-триггер: растягиваем его на всю высоту слота,
15
+ // чтобы buttonField-кнопка внутри занимала полную высоту поля (как в FieldText).
16
+ .stepButtonTrigger {
17
+ display: flex;
18
+ align-items: stretch;
19
+ height: 100%;
20
+ }
21
+
22
+ // Copy-кнопка (readonly) центрируется во всю высоту слота, как и step-триггеры.
23
+ .copyButton {
24
+ display: flex;
25
+ align-items: center;
26
+ height: 100%;
27
+ }
28
+
29
+ .valueArea {
30
+ display: flex;
31
+ flex: 1 1 auto;
32
+ align-items: baseline;
33
+ justify-content: center;
34
+
35
+ min-width: 0;
36
+
37
+ color: base.$sn-theme-color-available-version-textMain;
38
+ text-align: center;
39
+
40
+ @each $size, $tokenSize in $inputLineGapSizes {
41
+ [data-size='#{$size}'] & {
42
+ gap: base.simple-var(
43
+ field.$field,
44
+ 'anatomy',
45
+ 'size',
46
+ $tokenSize,
47
+ 'fieldContainer',
48
+ 'contentWrapper',
49
+ 'inputLine',
50
+ 'gap'
51
+ );
52
+ }
53
+ }
54
+ }
55
+
56
+ .inputWrapper {
57
+ display: flex;
58
+ flex: 0 0 auto;
59
+
60
+ // ширина по числу символов значения (var выставляется компонентом), минимум 2ch.
61
+ // +1ch — запас под каретку и субпиксельное округление: без него значение шириной ровно
62
+ // N символов (напр. «100» = 3ch) обрезается ellipsis'ом инпута до «1…».
63
+ width: calc((var(--field-stepper-input-ch, 2) + 1) * 1ch);
64
+ max-width: 100%;
65
+ }
66
+
67
+ .input {
68
+ flex: 0 0 auto;
69
+
70
+ width: 100%;
71
+ min-width: 1ch;
72
+
73
+ text-align: center;
74
+
75
+ /* stylelint-disable-next-line property-no-vendor-prefix */
76
+ -moz-appearance: textfield;
77
+
78
+ &::-webkit-outer-spin-button,
79
+ &::-webkit-inner-spin-button {
80
+ margin: 0;
81
+
82
+ /* stylelint-disable-next-line property-no-vendor-prefix */
83
+ -webkit-appearance: none;
84
+ }
85
+ }
86
+
87
+ .affix {
88
+ flex-shrink: 0;
89
+ color: base.$sn-theme-color-available-version-textTertiary;
90
+
91
+ // DS-типографика по size из корневого fieldWrapper. Без этого фолбэк на Nunito Sans 16/24
92
+ // визуально не сходится с инпутом.
93
+ @each $size in $sizes {
94
+ [data-size='#{$size}'] & {
95
+ @include base.composite-var(base.$sn-regular, 'body', $size);
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,44 @@
1
+ /** Начальное значение для uncontrolled-режима: выводится из `min`/`max`, иначе `0`. */
2
+ export function getDefaultValue(min?: number, max?: number): number {
3
+ if (typeof min === 'number' && min > 0) {
4
+ return min;
5
+ }
6
+
7
+ if (typeof max === 'number' && max < 0) {
8
+ return max;
9
+ }
10
+
11
+ return 0;
12
+ }
13
+
14
+ /** Зажимает значение в диапазон `[min, max]` (границы опциональны). */
15
+ export function clamp(value: number, min?: number, max?: number): number {
16
+ let next = value;
17
+ if (typeof min === 'number') {
18
+ next = Math.max(next, min);
19
+ }
20
+ if (typeof max === 'number') {
21
+ next = Math.min(next, max);
22
+ }
23
+ return next;
24
+ }
25
+
26
+ /** Приращение значения на `step` с компенсацией погрешности float (округление до 10 знаков). */
27
+ export function applyStep(value: number, step: number): number {
28
+ const sum = value + step;
29
+ return Number(sum.toFixed(10));
30
+ }
31
+
32
+ /**
33
+ * Дефолтный текст тултипа клампа для нижней границы.
34
+ */
35
+ export function defaultClampMinText(value: number): string {
36
+ return `Значение должно быть больше либо равно ${value}`;
37
+ }
38
+
39
+ /**
40
+ * Дефолтный текст тултипа клампа для верхней границы.
41
+ */
42
+ export function defaultClampMaxText(value: number): string {
43
+ return `Значение должно быть меньше либо равно ${value}`;
44
+ }
@@ -0,0 +1,27 @@
1
+ import { forwardRef } from 'react';
2
+
3
+ import { TEST_IDS } from '../../constants';
4
+ import { FieldCombo, FieldComboProps } from '../FieldCombo';
5
+
6
+ /**
7
+ * Пропсы простого текстового поля. От `FieldCombo` отличается отсутствием слотов:
8
+ * префикса, постфикса, иконок и кнопок-сегментов. Нужен слот — берите `FieldCombo`.
9
+ */
10
+ export type FieldTextProps = Omit<
11
+ FieldComboProps,
12
+ 'prefix' | 'postfix' | 'iconBefore' | 'iconAfter' | 'prefixIcon' | 'elementBefore' | 'elementAfter' | 'innerTestIds'
13
+ >;
14
+
15
+ /**
16
+ * Текстовое поле: заголовок, подсказка, плейсхолдер, значение и кнопки очистки и копирования.
17
+ * Слоты вокруг строки ввода не поддерживает — для них есть `FieldCombo`.
18
+ */
19
+ export const FieldText = forwardRef<HTMLInputElement, FieldTextProps>(function FieldText(props, ref) {
20
+ return (
21
+ <FieldCombo
22
+ {...props}
23
+ ref={ref}
24
+ innerTestIds={{ shell: TEST_IDS.fieldTextShell, input: TEST_IDS.fieldTextInput }}
25
+ />
26
+ );
27
+ });
@@ -0,0 +1 @@
1
+ export * from './FieldText';