@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
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@cloud-ru/ds-fields",
3
+ "version": "1.0.0",
4
+ "description": "Поля ввода с единой обёрткой label/caption/hint/error и общими осями size/validationState — текст, пароль, число, ползунок, дата, время, выбор, цвет.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/cloud-ru-tech/snack-v2.git",
8
+ "directory": "packages/fields"
9
+ },
10
+ "homepage": "https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/fields",
11
+ "license": "Apache-2.0",
12
+ "author": "Nikita Ershov <niershov@cloud.ru>",
13
+ "type": "module",
14
+ "main": "./dist/cjs/index.js",
15
+ "module": "./dist/esm/index.js",
16
+ "types": "./dist/esm/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "source": "./src/index.ts",
20
+ "types": "./dist/esm/index.d.ts",
21
+ "import": "./dist/esm/index.js",
22
+ "require": "./dist/cjs/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src",
28
+ "./CHANGELOG.md",
29
+ "./LICENSE"
30
+ ],
31
+ "sideEffects": [
32
+ "*.css",
33
+ "**/*.css"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "dependencies": {
39
+ "classnames": "^2.5.1",
40
+ "merge-refs": "^2.0.0",
41
+ "react-textarea-autosize": "^8.5.9",
42
+ "@cloud-ru/ds-adaptive": "^1.0.0",
43
+ "@cloud-ru/ds-button": "^1.0.0",
44
+ "@cloud-ru/ds-calendar": "^1.0.0",
45
+ "@cloud-ru/ds-bottom-sheet": "^1.0.0",
46
+ "@cloud-ru/ds-divider": "^1.0.0",
47
+ "@cloud-ru/ds-dropdown": "^1.0.0",
48
+ "@cloud-ru/ds-field-decorator": "^1.0.0",
49
+ "@cloud-ru/ds-icons": "^1.0.0",
50
+ "@cloud-ru/ds-list": "^1.0.0",
51
+ "@cloud-ru/ds-loader": "^1.0.0",
52
+ "@cloud-ru/ds-materials": "^1.0.0",
53
+ "@cloud-ru/ds-color-picker": "^1.0.0",
54
+ "@cloud-ru/ds-skeleton": "^1.0.0",
55
+ "@cloud-ru/ds-tag": "^1.0.0",
56
+ "@cloud-ru/ds-slider": "^1.0.0",
57
+ "@cloud-ru/ds-input-private": "^1.0.0",
58
+ "@cloud-ru/ds-tooltip": "^1.0.0",
59
+ "@cloud-ru/ds-scroll": "^1.0.0",
60
+ "@cloud-ru/ds-utils": "^1.0.0"
61
+ }
62
+ }
@@ -0,0 +1,426 @@
1
+ import { isMobileLayout, useAdaptiveLayout } from '@cloud-ru/ds-adaptive';
2
+ import { NO_DRAG_ATTRIBUTE } from '@cloud-ru/ds-bottom-sheet';
3
+ import { APPEARANCE, Button, VIEW } from '@cloud-ru/ds-button';
4
+ import { ColorPicker, colorPickerLocale, ColorPickerProps, RawColor } from '@cloud-ru/ds-color-picker';
5
+ import { Dropdown } from '@cloud-ru/ds-dropdown';
6
+ import { FieldDecorator, FieldDecoratorProps, SIZE, VALIDATION_STATE } from '@cloud-ru/ds-field-decorator';
7
+ import { ChevronDownSVG, ChevronUpSVG } from '@cloud-ru/ds-icons/interface/system';
8
+ import { InputPrivate, InputPrivateProps, useButtonNavigation, useClearButton } from '@cloud-ru/ds-input-private';
9
+ import { useValueControl } from '@cloud-ru/ds-utils';
10
+ import cn from 'classnames';
11
+ import mergeRefs from 'merge-refs';
12
+ import {
13
+ CSSProperties,
14
+ FocusEvent,
15
+ forwardRef,
16
+ KeyboardEvent,
17
+ useCallback,
18
+ useEffect,
19
+ useMemo,
20
+ useRef,
21
+ useState,
22
+ } from 'react';
23
+
24
+ import { TEST_IDS } from '../../constants';
25
+ import { FieldLayoutPresets, useAdaptiveAutoFocus } from '../../hooks';
26
+ import { copyTextToClipboard, getAcrylicProps, toInputSize, useCopyButton } from '../shared';
27
+ import fieldStyles from '../shared/styles.module.scss';
28
+ import styles from './styles.module.scss';
29
+ import { normalizeHexInput } from './utils';
30
+
31
+ type FieldColorDecoratorProps = Omit<FieldDecoratorProps, 'children'>;
32
+
33
+ type FieldColorOwnProps = {
34
+ /** CSS-класс корня `FieldDecorator` */
35
+ className?: string;
36
+ /** CSS-класс оболочки поля */
37
+ fieldClassName?: string;
38
+ /** Текущее значение (hex/rgb/hsl-строка, controlled-режим). */
39
+ value?: string;
40
+ /** Начальное значение (uncontrolled-режим). */
41
+ defaultValue?: string;
42
+ /** Колбек смены значения. */
43
+ onChange?(value: string): void;
44
+ /** Открыт color-picker. */
45
+ open?: boolean;
46
+ /** Колбек смены состояния открытия. */
47
+ onOpenChange?(open: boolean): void;
48
+ /**
49
+ * Показывать кнопку очистки (видна при value && !readonly && !disabled).
50
+ * @default true
51
+ */
52
+ showClearButton?: boolean;
53
+ /** Колбек после клика по кнопке очистки. */
54
+ onClearButtonClick?(): void;
55
+ /**
56
+ * Показывать кнопку копирования (видна при readonly && value && !disabled).
57
+ * @default true
58
+ */
59
+ showCopyButton?: boolean;
60
+ /** Колбек после копирования значения. */
61
+ onCopyButtonClick?(): void;
62
+ /**
63
+ * Переопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен
64
+ * (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`.
65
+ */
66
+ layoutPresets?: FieldLayoutPresets;
67
+ /**
68
+ * Фон поля (acrylic).
69
+ * @default true
70
+ */
71
+ background?: boolean;
72
+ // Только desktop: `autoApply` действует на desktop-палитре; на mobile значение всегда коммитится
73
+ // по явному Apply в `BottomSheet` (autoApply форсится в `true`).
74
+ } & Pick<ColorPickerProps, 'withAlpha' | 'autoApply' | 'availableModes'>;
75
+
76
+ export type FieldColorProps = FieldColorDecoratorProps &
77
+ Omit<InputPrivateProps, 'className' | 'value' | 'onChange'> &
78
+ FieldColorOwnProps;
79
+
80
+ export const FieldColor = forwardRef<HTMLInputElement, FieldColorProps>(function FieldColor(
81
+ {
82
+ label = '',
83
+ labelTooltip,
84
+ caption,
85
+ hint,
86
+ error,
87
+ validationState = VALIDATION_STATE.Default,
88
+ showHintIcon,
89
+ length,
90
+ required,
91
+ size = SIZE.M,
92
+ className,
93
+ fieldClassName,
94
+ background = true,
95
+ value: valueProp,
96
+ defaultValue = '',
97
+ onChange: onChangeProp,
98
+ open: openProp,
99
+ onOpenChange,
100
+ showClearButton: showClearButtonProp = true,
101
+ onClearButtonClick,
102
+ showCopyButton: showCopyButtonProp = true,
103
+ onCopyButtonClick,
104
+ withAlpha,
105
+ autoApply,
106
+ availableModes,
107
+ layoutPresets,
108
+ disabled,
109
+ readonly: readOnly,
110
+ placeholder,
111
+ 'data-test-id': dataTestId = TEST_IDS.fieldColor,
112
+ ...inputProps
113
+ },
114
+ ref,
115
+ ) {
116
+ const {
117
+ onFocus: onFocusProp,
118
+ onBlur: onBlurProp,
119
+ onKeyDown: onKeyDownProp,
120
+ tabIndex: tabIndexProp,
121
+ autoFocus,
122
+ ...restInputProps
123
+ } = inputProps;
124
+ const localRef = useRef<HTMLInputElement>(null);
125
+ const clearButtonRef = useRef<HTMLButtonElement>(null);
126
+ const copyButtonRef = useRef<HTMLButtonElement>(null);
127
+ const [focusVisible, setFocusVisible] = useState(false);
128
+ const [hover, setHover] = useState(false);
129
+ const [openLocal, setOpenLocal] = useState(false);
130
+ const open = openProp ?? openLocal;
131
+ const { layoutType } = useAdaptiveLayout();
132
+ const mobile = isMobileLayout(layoutType);
133
+
134
+ const resolvedAutoFocus = useAdaptiveAutoFocus(autoFocus, layoutPresets);
135
+
136
+ const [value = '', onChange] = useValueControl<string>({
137
+ value: valueProp,
138
+ defaultValue,
139
+ onChange: onChangeProp,
140
+ });
141
+ const effectiveValidationState = useMemo(
142
+ () => (error ? VALIDATION_STATE.Error : validationState),
143
+ [error, validationState],
144
+ );
145
+
146
+ const showOpen = open && !disabled && !readOnly;
147
+ const showClearUi = Boolean(showClearButtonProp && value && !readOnly && !disabled);
148
+ const showCopyUi = Boolean(showCopyButtonProp && value && !disabled && readOnly);
149
+
150
+ const handleOpenChange = useCallback(
151
+ (next: boolean) => {
152
+ if (openProp === undefined) setOpenLocal(next);
153
+ onOpenChange?.(next);
154
+ },
155
+ [openProp, onOpenChange],
156
+ );
157
+
158
+ // Фокус в поле при открытии пикера (паритет с легаси `@snack-uikit/fields`). На mobile пикер
159
+ // открывается в `BottomSheet` поверх поля — фокус на скрытый под ним input не уводим.
160
+ useEffect(() => {
161
+ if (open && !mobile) {
162
+ localRef.current?.focus();
163
+ }
164
+ }, [open, mobile]);
165
+
166
+ const onClear = useCallback(() => {
167
+ onChange?.('');
168
+ onClearButtonClick?.();
169
+ if (required) {
170
+ localRef.current?.focus();
171
+ }
172
+ }, [onChange, onClearButtonClick, required]);
173
+
174
+ const onCopy = useCallback(async () => {
175
+ const copied = await copyTextToClipboard(value);
176
+ if (copied) {
177
+ onCopyButtonClick?.();
178
+ }
179
+ return copied;
180
+ }, [onCopyButtonClick, value]);
181
+
182
+ const clearButtonSettings = useClearButton({
183
+ clearButtonRef,
184
+ showClearButton: showClearUi,
185
+ size: toInputSize(size),
186
+ onClear,
187
+ disabled: Boolean(disabled || readOnly),
188
+ });
189
+
190
+ const copyButtonSettings = useCopyButton({
191
+ copyButtonRef,
192
+ showCopyButton: showCopyUi,
193
+ size: toInputSize(size),
194
+ onCopy,
195
+ disabled: Boolean(disabled),
196
+ });
197
+
198
+ const { postfixButtons, inputTabIndex, onInputKeyDown } = useButtonNavigation({
199
+ inputRef: localRef,
200
+ postfixButtons: useMemo(() => [clearButtonSettings, copyButtonSettings], [clearButtonSettings, copyButtonSettings]),
201
+ readonly: Boolean(readOnly),
202
+ submitKeys: ['Enter', 'Space', 'Tab'],
203
+ });
204
+
205
+ const handleKeyDown = useCallback(
206
+ (event: KeyboardEvent<HTMLInputElement>) => {
207
+ onInputKeyDown(event);
208
+ onKeyDownProp?.(event);
209
+ },
210
+ [onInputKeyDown, onKeyDownProp],
211
+ );
212
+
213
+ const handleInputChange = useCallback(
214
+ (next: string) => {
215
+ onChange?.(normalizeHexInput(next, withAlpha));
216
+ },
217
+ [onChange, withAlpha],
218
+ );
219
+
220
+ const handlePickerChange = useCallback(
221
+ (raw: RawColor) => {
222
+ onChange?.(raw.hex);
223
+ },
224
+ [onChange],
225
+ );
226
+
227
+ const { t } = colorPickerLocale.useTranslations();
228
+
229
+ // Mobile: палитра в BottomSheet с явным Apply — правки в черновик, коммит в поле по Apply.
230
+ const [draft, setDraft] = useState(value);
231
+ const prevOpenRef = useRef(open);
232
+ useEffect(() => {
233
+ if (open && !prevOpenRef.current && mobile) {
234
+ setDraft(value);
235
+ }
236
+ prevOpenRef.current = open;
237
+ }, [open, mobile, value]);
238
+
239
+ const handleMobileApply = useCallback(() => {
240
+ onChange?.(draft ?? '');
241
+ handleOpenChange(false);
242
+ }, [onChange, draft, handleOpenChange]);
243
+
244
+ const handleMobileCancel = useCallback(() => {
245
+ handleOpenChange(false);
246
+ }, [handleOpenChange]);
247
+
248
+ const handleMouseEnter = useCallback(() => {
249
+ if (!readOnly && !disabled) {
250
+ setHover(true);
251
+ }
252
+ }, [readOnly, disabled]);
253
+
254
+ const handleMouseLeave = useCallback(() => {
255
+ setHover(false);
256
+ }, []);
257
+
258
+ const handleInputFocus = useCallback(
259
+ (event: FocusEvent<HTMLInputElement>) => {
260
+ setFocusVisible(event.target.matches(':focus-visible'));
261
+ onFocusProp?.(event);
262
+ },
263
+ [onFocusProp],
264
+ );
265
+
266
+ const handleInputBlur = useCallback(
267
+ (event: FocusEvent<HTMLInputElement>) => {
268
+ setFocusVisible(false);
269
+ onBlurProp?.(event);
270
+ },
271
+ [onBlurProp],
272
+ );
273
+
274
+ const trigger = (
275
+ <div
276
+ className={cn(fieldStyles.fieldWrapper, styles.trigger, fieldClassName)}
277
+ data-size={size}
278
+ data-validation-state={effectiveValidationState}
279
+ data-disabled={disabled || undefined}
280
+ data-readonly={readOnly || undefined}
281
+ data-withbackground={background || undefined}
282
+ data-focusvisible={focusVisible || showOpen || undefined}
283
+ data-hover={!readOnly && !disabled && hover ? true : undefined}
284
+ data-test-id={dataTestId}
285
+ onMouseEnter={handleMouseEnter}
286
+ onMouseLeave={handleMouseLeave}
287
+ >
288
+ <div className={fieldStyles.backgroundWrapper}>
289
+ <div
290
+ className={fieldStyles.materialLayer}
291
+ {...getAcrylicProps({
292
+ validationState: effectiveValidationState,
293
+ disabled,
294
+ readonly: readOnly,
295
+ hover,
296
+ focusVisible: focusVisible || showOpen,
297
+ })}
298
+ >
299
+ <div className={fieldStyles.acrylicBg} aria-hidden />
300
+ </div>
301
+ <div className={fieldStyles.borderStateLayer} data-state='borderOnBackground' />
302
+ <div className={fieldStyles.focusLayer} />
303
+ </div>
304
+ <div className={fieldStyles.fieldContainer}>
305
+ <div className={fieldStyles.contentWrapper}>
306
+ <div className={fieldStyles.iconSlot}>
307
+ <span
308
+ className={styles.swatch}
309
+ data-test-id={TEST_IDS.fieldColorSwatch}
310
+ style={{ '--field-color-swatch-color': value || 'transparent' } as CSSProperties}
311
+ aria-hidden
312
+ />
313
+ </div>
314
+ <div className={fieldStyles.inputLine}>
315
+ <div className={fieldStyles.inputArea}>
316
+ <InputPrivate
317
+ ref={mergeRefs(ref, localRef)}
318
+ className={fieldStyles.fieldInput}
319
+ value={value}
320
+ onChange={handleInputChange}
321
+ disabled={disabled}
322
+ readonly={readOnly}
323
+ placeholder={placeholder}
324
+ autoFocus={resolvedAutoFocus}
325
+ tabIndex={tabIndexProp ?? inputTabIndex}
326
+ onKeyDown={handleKeyDown}
327
+ onFocus={handleInputFocus}
328
+ onBlur={handleInputBlur}
329
+ {...restInputProps}
330
+ data-test-id={TEST_IDS.fieldColorInput}
331
+ />
332
+ {postfixButtons && <span className={fieldStyles.postfixButtonsSlot}>{postfixButtons}</span>}
333
+ </div>
334
+ </div>
335
+ {/* Chevron присутствует во всех состояниях, включая readonly — паритет с Figma
336
+ readonly-варианты тоже показывают chevron-down рядом с copy). */}
337
+ <div className={fieldStyles.iconSlot}>
338
+ <span className={styles.chevron} data-test-id={TEST_IDS.fieldColorChevron} aria-hidden>
339
+ {showOpen ? <ChevronUpSVG /> : <ChevronDownSVG />}
340
+ </span>
341
+ </div>
342
+ </div>
343
+ </div>
344
+ </div>
345
+ );
346
+
347
+ return (
348
+ <FieldDecorator
349
+ className={className}
350
+ label={label}
351
+ labelTooltip={labelTooltip}
352
+ caption={caption}
353
+ hint={hint}
354
+ error={error}
355
+ validationState={validationState}
356
+ showHintIcon={showHintIcon}
357
+ length={length}
358
+ required={required}
359
+ labelFor={inputProps.id}
360
+ disabled={disabled}
361
+ readonly={readOnly}
362
+ size={size}
363
+ >
364
+ <Dropdown
365
+ trigger='click'
366
+ widthStrategy='auto'
367
+ open={showOpen}
368
+ onOpenChange={handleOpenChange}
369
+ headerDivider={mobile}
370
+ footerDivider={mobile}
371
+ title={
372
+ mobile ? (
373
+ <span className={styles.sheetTitle} data-test-id={TEST_IDS.fieldColorSheetTitle}>
374
+ {(draft || '').toUpperCase()}
375
+ <span
376
+ className={styles.sheetSwatch}
377
+ style={{ '--field-color-swatch-color': draft || 'transparent' } as CSSProperties}
378
+ aria-hidden
379
+ />
380
+ </span>
381
+ ) : undefined
382
+ }
383
+ footer={
384
+ mobile ? (
385
+ <div className={styles.sheetFooter}>
386
+ <Button
387
+ label={t('cancel')}
388
+ size={size}
389
+ view={VIEW.Function}
390
+ appearance={APPEARANCE.Neutral}
391
+ onClick={handleMobileCancel}
392
+ data-test-id={TEST_IDS.fieldColorCancel}
393
+ />
394
+ <Button
395
+ label={t('apply')}
396
+ size={size}
397
+ view={VIEW.Filled}
398
+ appearance={APPEARANCE.Primary}
399
+ onClick={handleMobileApply}
400
+ data-test-id={TEST_IDS.fieldColorApply}
401
+ />
402
+ </div>
403
+ ) : undefined
404
+ }
405
+ content={
406
+ // На mobile палитра живёт в `BottomSheet`: помечаем её no-drag, иначе drag по слайдеру/области
407
+ // цвета одновременно потащил бы sheet к закрытию (свайп-дисмисс перехватывал бы жест контрола).
408
+ <div className={styles.pickerHost} {...(mobile ? { [NO_DRAG_ATTRIBUTE]: '' } : {})}>
409
+ <ColorPicker
410
+ value={(mobile ? draft : value) || undefined}
411
+ size={size}
412
+ withAlpha={withAlpha}
413
+ withColorArea={mobile ? false : undefined}
414
+ autoApply={mobile ? true : autoApply}
415
+ availableModes={availableModes}
416
+ onChange={mobile ? raw => setDraft(raw.hex) : handlePickerChange}
417
+ data-test-id={TEST_IDS.fieldColorPicker}
418
+ />
419
+ </div>
420
+ }
421
+ >
422
+ {trigger}
423
+ </Dropdown>
424
+ </FieldDecorator>
425
+ );
426
+ });
@@ -0,0 +1 @@
1
+ export * from './FieldColor';
@@ -0,0 +1,120 @@
1
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
2
+ @use '@cloud-ru/ds-figma-variables/build/scss/components/colorPicker.module' as colorPicker;
3
+
4
+ // FieldColor size → colorPicker previewColor size (Figma fieldSelectColor):
5
+ // s → colorPicker s (16px / radius 4), m → colorPicker m (24px / radius 8),
6
+ // l → colorPicker m (24px / radius 8) — в макете L-поле референсит m-токен previewColor,
7
+ // swatch не увеличивается до 32.
8
+ $swatch-sizes: (
9
+ 's': 's',
10
+ 'm': 'm',
11
+ 'l': 'm',
12
+ );
13
+
14
+ .trigger {
15
+ cursor: pointer;
16
+ }
17
+
18
+ .swatch {
19
+ position: relative;
20
+
21
+ flex: 0 0 auto;
22
+
23
+ background-color: var(--field-color-swatch-color, transparent);
24
+
25
+ // Шахматка прозрачности — визуальная конвенция alpha-канала, у геометрии клеток нет
26
+ // дизайн-токена; литералы 8px/4px намеренные (паритет с легаси color-picker swatch).
27
+ background-image:
28
+ linear-gradient(45deg, base.$sn-theme-color-available-borderColor 25%, transparent 25%),
29
+ linear-gradient(-45deg, base.$sn-theme-color-available-borderColor 25%, transparent 25%),
30
+ linear-gradient(45deg, transparent 75%, base.$sn-theme-color-available-borderColor 75%),
31
+ linear-gradient(-45deg, transparent 75%, base.$sn-theme-color-available-borderColor 75%);
32
+ background-position:
33
+ 0 0,
34
+ 0 4px,
35
+ 4px -4px,
36
+ -4px 0;
37
+ background-size: 8px 8px;
38
+
39
+ &::after {
40
+ content: '';
41
+
42
+ position: absolute;
43
+ inset: 0;
44
+
45
+ border-radius: inherit;
46
+
47
+ background-color: var(--field-color-swatch-color, transparent);
48
+ }
49
+ }
50
+
51
+ .chevron {
52
+ display: inline-flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ color: base.$sn-theme-color-available-version-textTertiary;
56
+ }
57
+
58
+ @each $size, $tokenSize in $swatch-sizes {
59
+ .trigger[data-size='#{$size}'] .swatch {
60
+ width: base.simple-var(colorPicker.$colorPicker, 'anatomy', 'size', $tokenSize, 'previewColor', 'width');
61
+ height: base.simple-var(colorPicker.$colorPicker, 'anatomy', 'size', $tokenSize, 'previewColor', 'height');
62
+ border-radius: base.simple-var(colorPicker.$colorPicker, 'anatomy', 'size', $tokenSize, 'previewColor', 'border-radius');
63
+ }
64
+ }
65
+
66
+ // Mobile: заголовок sheet'а — текущий цвет (hex + круглый swatch).
67
+ .sheetTitle {
68
+ display: inline-flex;
69
+ gap: base.$sn-primitive-dimension-8;
70
+ align-items: center;
71
+ }
72
+
73
+ .sheetSwatch {
74
+ position: relative;
75
+
76
+ flex: 0 0 auto;
77
+
78
+ width: base.$sn-primitive-dimension-24;
79
+ height: base.$sn-primitive-dimension-24;
80
+ border-radius: 50%;
81
+
82
+ background-color: var(--field-color-swatch-color, transparent);
83
+
84
+ // Шахматка прозрачности — та же конвенция, что у `.swatch` (литералы 8px/4px намеренные).
85
+ background-image:
86
+ linear-gradient(45deg, base.$sn-theme-color-available-borderColor 25%, transparent 25%),
87
+ linear-gradient(-45deg, base.$sn-theme-color-available-borderColor 25%, transparent 25%),
88
+ linear-gradient(45deg, transparent 75%, base.$sn-theme-color-available-borderColor 75%),
89
+ linear-gradient(-45deg, transparent 75%, base.$sn-theme-color-available-borderColor 75%);
90
+ background-position:
91
+ 0 0,
92
+ 0 4px,
93
+ 4px -4px,
94
+ -4px 0;
95
+ background-size: 8px 8px;
96
+
97
+ &::after {
98
+ content: '';
99
+
100
+ position: absolute;
101
+ inset: 0;
102
+
103
+ border-radius: inherit;
104
+
105
+ background-color: var(--field-color-swatch-color, transparent);
106
+ }
107
+ }
108
+
109
+ .sheetFooter {
110
+ display: flex;
111
+ gap: base.$sn-primitive-dimension-8;
112
+ justify-content: space-between;
113
+ }
114
+
115
+ // Прозрачная для layout обёртка палитры (несёт только `data-bottom-sheet-no-drag`): не должна влиять
116
+ // на раскладку контента sheet'а / popover'а — `display: contents` убирает её из box-дерева, но не из DOM,
117
+ // поэтому `closest()` drag-движка её по-прежнему находит.
118
+ .pickerHost {
119
+ display: contents;
120
+ }
@@ -0,0 +1,17 @@
1
+ /** Всё, что не hex-цифра. */
2
+ const NON_HEX_CHARS = /[^0-9a-fA-F]/g;
3
+ /** Hex-цифр с альфой: `rrggbbaa` (8); без альфы: `rrggbb` (6). `#` не считается. */
4
+ const HEX_DIGITS_WITH_ALPHA = 8;
5
+ const HEX_DIGITS_NO_ALPHA = 6;
6
+
7
+ /**
8
+ * Нормализует пользовательский ввод цвета в потенциально валидную hex-строку:
9
+ * при наличии hex-цифр ведущая `#` обязательна (добавляется всегда), за ней — не более
10
+ * 8 hex-цифр (`rrggbbaa`) при `withAlpha`, иначе 6 (`rrggbb`). Лишние/внутренние `#` и
11
+ * любые не-hex символы отбрасываются. Пустой ввод (очистка поля) остаётся пустым.
12
+ */
13
+ export function normalizeHexInput(raw: string, withAlpha = true): string {
14
+ const maxDigits = withAlpha ? HEX_DIGITS_WITH_ALPHA : HEX_DIGITS_NO_ALPHA;
15
+ const digits = raw.replace(NON_HEX_CHARS, '').slice(0, maxDigits);
16
+ return digits ? `#${digits}` : '';
17
+ }