@skbkontur/react-ui 6.1.4-05b51.0 → 6.1.4-ff219.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 (274) hide show
  1. package/components/Autocomplete/Autocomplete.js +3 -2
  2. package/components/Autocomplete/Autocomplete.js.map +1 -1
  3. package/components/FxInput/FxInput.js +2 -2
  4. package/components/FxInput/FxInput.js.map +1 -1
  5. package/components/Group/Group.js +2 -3
  6. package/components/Group/Group.js.map +1 -1
  7. package/components/Input/Input.d.ts +1 -1
  8. package/components/Input/Input.js.map +1 -1
  9. package/components/MaskedInput/MaskedInput.d.ts +2 -0
  10. package/components/MaskedInput/MaskedInput.js +6 -0
  11. package/components/MaskedInput/MaskedInput.js.map +1 -1
  12. package/components/MaskedInputV2/MaskedInputV2.d.ts +57 -0
  13. package/components/MaskedInputV2/MaskedInputV2.helpers.d.ts +9 -0
  14. package/components/MaskedInputV2/MaskedInputV2.helpers.js +17 -0
  15. package/components/MaskedInputV2/MaskedInputV2.helpers.js.map +1 -0
  16. package/components/MaskedInputV2/MaskedInputV2.js +234 -0
  17. package/components/MaskedInputV2/MaskedInputV2.js.map +1 -0
  18. package/{internal/TimeInput/TimeInput.styles.d.ts → components/MaskedInputV2/MaskedInputV2.styles.d.ts} +4 -3
  19. package/components/MaskedInputV2/MaskedInputV2.styles.js +19 -0
  20. package/components/MaskedInputV2/MaskedInputV2.styles.js.map +1 -0
  21. package/components/MaskedInputV2/index.d.ts +1 -0
  22. package/components/MaskedInputV2/index.js +2 -0
  23. package/components/MaskedInputV2/index.js.map +1 -0
  24. package/components/MaskedInputV2/internal/MaskOverlay.d.ts +19 -0
  25. package/components/MaskedInputV2/internal/MaskOverlay.js +54 -0
  26. package/components/MaskedInputV2/internal/MaskOverlay.js.map +1 -0
  27. package/components/MaskedInputV2/internal/MaskedCore.d.ts +8 -0
  28. package/components/MaskedInputV2/internal/MaskedCore.js +101 -0
  29. package/components/MaskedInputV2/internal/MaskedCore.js.map +1 -0
  30. package/components/MaskedInputV2/internal/MaskedCore.types.d.ts +30 -0
  31. package/components/MaskedInputV2/internal/MaskedCore.types.js +2 -0
  32. package/components/MaskedInputV2/internal/MaskedCore.types.js.map +1 -0
  33. package/components/MaskedInputV2/internal/MaskedInternal.styles.d.ts +15 -0
  34. package/components/MaskedInputV2/internal/MaskedInternal.styles.js +34 -0
  35. package/components/MaskedInputV2/internal/MaskedInternal.styles.js.map +1 -0
  36. package/components/MaskedInputV2/internal/buildSlotMap.d.ts +11 -0
  37. package/components/MaskedInputV2/internal/buildSlotMap.js +37 -0
  38. package/components/MaskedInputV2/internal/buildSlotMap.js.map +1 -0
  39. package/components/MaskedInputV2/internal/extractRaw.d.ts +10 -0
  40. package/components/MaskedInputV2/internal/extractRaw.js +16 -0
  41. package/components/MaskedInputV2/internal/extractRaw.js.map +1 -0
  42. package/components/MaskedInputV2/internal/findNearestRawLeft.d.ts +10 -0
  43. package/components/MaskedInputV2/internal/findNearestRawLeft.js +18 -0
  44. package/components/MaskedInputV2/internal/findNearestRawLeft.js.map +1 -0
  45. package/components/MaskedInputV2/internal/helpers.d.ts +5 -0
  46. package/components/MaskedInputV2/internal/helpers.js +6 -0
  47. package/components/MaskedInputV2/internal/helpers.js.map +1 -0
  48. package/components/MaskedInputV2/internal/maskedCoreClipboard.d.ts +25 -0
  49. package/components/MaskedInputV2/internal/maskedCoreClipboard.js +30 -0
  50. package/components/MaskedInputV2/internal/maskedCoreClipboard.js.map +1 -0
  51. package/components/MaskedInputV2/internal/maskedCoreDeletion.d.ts +28 -0
  52. package/components/MaskedInputV2/internal/maskedCoreDeletion.js +70 -0
  53. package/components/MaskedInputV2/internal/maskedCoreDeletion.js.map +1 -0
  54. package/components/MaskedInputV2/internal/maskedCoreInputChange.d.ts +35 -0
  55. package/components/MaskedInputV2/internal/maskedCoreInputChange.js +31 -0
  56. package/components/MaskedInputV2/internal/maskedCoreInputChange.js.map +1 -0
  57. package/components/MaskedInputV2/internal/maskedCoreNavigation.d.ts +13 -0
  58. package/components/MaskedInputV2/internal/maskedCoreNavigation.js +79 -0
  59. package/components/MaskedInputV2/internal/maskedCoreNavigation.js.map +1 -0
  60. package/components/MaskedInputV2/internal/stripMaskChars.d.ts +11 -0
  61. package/components/MaskedInputV2/internal/stripMaskChars.js +20 -0
  62. package/components/MaskedInputV2/internal/stripMaskChars.js.map +1 -0
  63. package/components/MaskedInputV2/internal/types.d.ts +74 -0
  64. package/components/MaskedInputV2/internal/types.js.map +1 -0
  65. package/components/MaskedInputV2/internal/useMaskEngine.d.ts +42 -0
  66. package/components/MaskedInputV2/internal/useMaskEngine.js +82 -0
  67. package/components/MaskedInputV2/internal/useMaskEngine.js.map +1 -0
  68. package/components/MaskedInputV2/internal/useMaskedCoreHandlers.d.ts +28 -0
  69. package/components/MaskedInputV2/internal/useMaskedCoreHandlers.js +190 -0
  70. package/components/MaskedInputV2/internal/useMaskedCoreHandlers.js.map +1 -0
  71. package/components/MaskedInputV2/react-imask/imask/controls/html-input-mask-element.d.ts +16 -0
  72. package/components/MaskedInputV2/react-imask/imask/controls/html-input-mask-element.js +59 -0
  73. package/components/MaskedInputV2/react-imask/imask/controls/html-input-mask-element.js.map +1 -0
  74. package/components/MaskedInputV2/react-imask/imask/controls/html-mask-element.d.ts +20 -0
  75. package/components/MaskedInputV2/react-imask/imask/controls/html-mask-element.js +106 -0
  76. package/components/MaskedInputV2/react-imask/imask/controls/html-mask-element.js.map +1 -0
  77. package/components/MaskedInputV2/react-imask/imask/controls/input-history.d.ts +17 -0
  78. package/components/MaskedInputV2/react-imask/imask/controls/input-history.js +49 -0
  79. package/components/MaskedInputV2/react-imask/imask/controls/input-history.js.map +1 -0
  80. package/components/MaskedInputV2/react-imask/imask/controls/input.d.ts +95 -0
  81. package/components/MaskedInputV2/react-imask/imask/controls/input.js +420 -0
  82. package/components/MaskedInputV2/react-imask/imask/controls/input.js.map +1 -0
  83. package/components/MaskedInputV2/react-imask/imask/controls/mask-element.d.ts +30 -0
  84. package/components/MaskedInputV2/react-imask/imask/controls/mask-element.js +59 -0
  85. package/components/MaskedInputV2/react-imask/imask/controls/mask-element.js.map +1 -0
  86. package/components/MaskedInputV2/react-imask/imask/core/action-details.d.ts +30 -0
  87. package/components/MaskedInputV2/react-imask/imask/core/action-details.js +100 -0
  88. package/components/MaskedInputV2/react-imask/imask/core/action-details.js.map +1 -0
  89. package/components/MaskedInputV2/react-imask/imask/core/change-details.d.ts +20 -0
  90. package/components/MaskedInputV2/react-imask/imask/core/change-details.js +46 -0
  91. package/components/MaskedInputV2/react-imask/imask/core/change-details.js.map +1 -0
  92. package/components/MaskedInputV2/react-imask/imask/core/continuous-tail-details.d.ts +21 -0
  93. package/components/MaskedInputV2/react-imask/imask/core/continuous-tail-details.js +52 -0
  94. package/components/MaskedInputV2/react-imask/imask/core/continuous-tail-details.js.map +1 -0
  95. package/components/MaskedInputV2/react-imask/imask/core/holder.d.ts +34 -0
  96. package/components/MaskedInputV2/react-imask/imask/core/holder.js +38 -0
  97. package/components/MaskedInputV2/react-imask/imask/core/holder.js.map +1 -0
  98. package/components/MaskedInputV2/react-imask/imask/core/tail-details.d.ts +20 -0
  99. package/components/MaskedInputV2/react-imask/imask/core/tail-details.js +2 -0
  100. package/components/MaskedInputV2/react-imask/imask/core/tail-details.js.map +1 -0
  101. package/components/MaskedInputV2/react-imask/imask/core/utils.d.ts +24 -0
  102. package/components/MaskedInputV2/react-imask/imask/core/utils.js +100 -0
  103. package/components/MaskedInputV2/react-imask/imask/core/utils.js.map +1 -0
  104. package/components/MaskedInputV2/react-imask/imask/imask.d.ts +5 -0
  105. package/components/MaskedInputV2/react-imask/imask/imask.js +7 -0
  106. package/components/MaskedInputV2/react-imask/imask/imask.js.map +1 -0
  107. package/components/MaskedInputV2/react-imask/imask/index.d.ts +17 -0
  108. package/components/MaskedInputV2/react-imask/imask/index.js +16 -0
  109. package/components/MaskedInputV2/react-imask/imask/index.js.map +1 -0
  110. package/components/MaskedInputV2/react-imask/imask/masked/base.d.ts +114 -0
  111. package/components/MaskedInputV2/react-imask/imask/masked/base.js +411 -0
  112. package/components/MaskedInputV2/react-imask/imask/masked/base.js.map +1 -0
  113. package/components/MaskedInputV2/react-imask/imask/masked/factory.d.ts +62 -0
  114. package/components/MaskedInputV2/react-imask/imask/masked/factory.js +96 -0
  115. package/components/MaskedInputV2/react-imask/imask/masked/factory.js.map +1 -0
  116. package/components/MaskedInputV2/react-imask/imask/masked/pattern.d.ts +101 -0
  117. package/components/MaskedInputV2/react-imask/imask/masked/pattern.js +543 -0
  118. package/components/MaskedInputV2/react-imask/imask/masked/pattern.js.map +1 -0
  119. package/components/MaskedInputV2/react-imask/imask/masked/patterns/block.d.ts +30 -0
  120. package/components/MaskedInputV2/react-imask/imask/masked/patterns/block.js +2 -0
  121. package/components/MaskedInputV2/react-imask/imask/masked/patterns/block.js.map +1 -0
  122. package/components/MaskedInputV2/react-imask/imask/masked/patterns/chunk-tail-details.d.ts +21 -0
  123. package/components/MaskedInputV2/react-imask/imask/masked/patterns/chunk-tail-details.js +180 -0
  124. package/components/MaskedInputV2/react-imask/imask/masked/patterns/chunk-tail-details.js.map +1 -0
  125. package/components/MaskedInputV2/react-imask/imask/masked/patterns/cursor.d.ts +31 -0
  126. package/components/MaskedInputV2/react-imask/imask/masked/patterns/cursor.js +163 -0
  127. package/components/MaskedInputV2/react-imask/imask/masked/patterns/cursor.js.map +1 -0
  128. package/components/MaskedInputV2/react-imask/imask/masked/patterns/fixed-definition.d.ts +42 -0
  129. package/components/MaskedInputV2/react-imask/imask/masked/patterns/fixed-definition.js +158 -0
  130. package/components/MaskedInputV2/react-imask/imask/masked/patterns/fixed-definition.js.map +1 -0
  131. package/components/MaskedInputV2/react-imask/imask/masked/patterns/input-definition.d.ts +56 -0
  132. package/components/MaskedInputV2/react-imask/imask/masked/patterns/input-definition.js +185 -0
  133. package/components/MaskedInputV2/react-imask/imask/masked/patterns/input-definition.js.map +1 -0
  134. package/components/MaskedInputV2/react-imask/imask/masked/regexp.d.ts +17 -0
  135. package/components/MaskedInputV2/react-imask/imask/masked/regexp.js +36 -0
  136. package/components/MaskedInputV2/react-imask/imask/masked/regexp.js.map +1 -0
  137. package/components/MaskedInputV2/react-imask/index.d.ts +3 -0
  138. package/components/MaskedInputV2/react-imask/index.js +4 -0
  139. package/components/MaskedInputV2/react-imask/index.js.map +1 -0
  140. package/components/MaskedInputV2/react-imask/input.d.ts +8 -0
  141. package/components/MaskedInputV2/react-imask/input.js +35 -0
  142. package/components/MaskedInputV2/react-imask/input.js.map +1 -0
  143. package/components/MaskedInputV2/react-imask/mixin.d.ts +31 -0
  144. package/components/MaskedInputV2/react-imask/mixin.js +246 -0
  145. package/components/MaskedInputV2/react-imask/mixin.js.map +1 -0
  146. package/index.d.ts +1 -1
  147. package/index.js +1 -1
  148. package/index.js.map +1 -1
  149. package/internal/CustomComboBox/ComboBoxView.js +2 -2
  150. package/internal/CustomComboBox/ComboBoxView.js.map +1 -1
  151. package/internal/FeaturedMaskedInput/FeaturedMaskedInput.d.ts +4 -0
  152. package/internal/FeaturedMaskedInput/FeaturedMaskedInput.js +24 -0
  153. package/internal/FeaturedMaskedInput/FeaturedMaskedInput.js.map +1 -0
  154. package/internal/themes/BasicTheme.d.ts +0 -34
  155. package/internal/themes/BasicTheme.js +0 -96
  156. package/internal/themes/BasicTheme.js.map +1 -1
  157. package/lib/events/keyboard/KeyboardEventCodes.d.ts +2 -0
  158. package/lib/events/keyboard/KeyboardEventCodes.js +2 -0
  159. package/lib/events/keyboard/KeyboardEventCodes.js.map +1 -1
  160. package/lib/events/keyboard/KeyboardMapKeys.js +2 -0
  161. package/lib/events/keyboard/KeyboardMapKeys.js.map +1 -1
  162. package/lib/events/keyboard/identifiers.d.ts +2 -0
  163. package/lib/events/keyboard/identifiers.js +6 -0
  164. package/lib/events/keyboard/identifiers.js.map +1 -1
  165. package/lib/featureFlagsContext/ReactUIFeatureFlagsContext.d.ts +2 -0
  166. package/lib/featureFlagsContext/ReactUIFeatureFlagsContext.js +1 -0
  167. package/lib/featureFlagsContext/ReactUIFeatureFlagsContext.js.map +1 -1
  168. package/lib/locale/types.d.ts +0 -2
  169. package/lib/locale/types.js.map +1 -1
  170. package/lib/utils.d.ts +0 -2
  171. package/lib/utils.js +0 -1
  172. package/lib/utils.js.map +1 -1
  173. package/package.json +4 -9
  174. package/components/TimePicker/TimeClockIcon.d.ts +0 -3
  175. package/components/TimePicker/TimeClockIcon.js +0 -11
  176. package/components/TimePicker/TimeClockIcon.js.map +0 -1
  177. package/components/TimePicker/TimePicker.d.ts +0 -79
  178. package/components/TimePicker/TimePicker.js +0 -513
  179. package/components/TimePicker/TimePicker.js.map +0 -1
  180. package/components/TimePicker/TimePicker.styles.d.ts +0 -11
  181. package/components/TimePicker/TimePicker.styles.js +0 -36
  182. package/components/TimePicker/TimePicker.styles.js.map +0 -1
  183. package/components/TimePicker/TimePickerItems.d.ts +0 -17
  184. package/components/TimePicker/TimePickerItems.js +0 -80
  185. package/components/TimePicker/TimePickerItems.js.map +0 -1
  186. package/components/TimePicker/TimePickerMobilePopup.d.ts +0 -38
  187. package/components/TimePicker/TimePickerMobilePopup.js +0 -21
  188. package/components/TimePicker/TimePickerMobilePopup.js.map +0 -1
  189. package/components/TimePicker/TimePickerPopup.d.ts +0 -20
  190. package/components/TimePicker/TimePickerPopup.js +0 -18
  191. package/components/TimePicker/TimePickerPopup.js.map +0 -1
  192. package/components/TimePicker/helpers/TimePicker.constants.d.ts +0 -22
  193. package/components/TimePicker/helpers/TimePicker.constants.js +0 -31
  194. package/components/TimePicker/helpers/TimePicker.constants.js.map +0 -1
  195. package/components/TimePicker/helpers/TimePicker.editing.d.ts +0 -23
  196. package/components/TimePicker/helpers/TimePicker.editing.js +0 -101
  197. package/components/TimePicker/helpers/TimePicker.editing.js.map +0 -1
  198. package/components/TimePicker/helpers/TimePicker.layout.d.ts +0 -6
  199. package/components/TimePicker/helpers/TimePicker.layout.js +0 -49
  200. package/components/TimePicker/helpers/TimePicker.layout.js.map +0 -1
  201. package/components/TimePicker/helpers/TimePicker.selection.d.ts +0 -5
  202. package/components/TimePicker/helpers/TimePicker.selection.js +0 -23
  203. package/components/TimePicker/helpers/TimePicker.selection.js.map +0 -1
  204. package/components/TimePicker/helpers/TimePicker.shared.d.ts +0 -47
  205. package/components/TimePicker/helpers/TimePicker.shared.js +0 -70
  206. package/components/TimePicker/helpers/TimePicker.shared.js.map +0 -1
  207. package/components/TimePicker/helpers/TimePicker.value.d.ts +0 -30
  208. package/components/TimePicker/helpers/TimePicker.value.js +0 -96
  209. package/components/TimePicker/helpers/TimePicker.value.js.map +0 -1
  210. package/components/TimePicker/helpers/scrollSelectedItemIntoView.d.ts +0 -4
  211. package/components/TimePicker/helpers/scrollSelectedItemIntoView.js +0 -24
  212. package/components/TimePicker/helpers/scrollSelectedItemIntoView.js.map +0 -1
  213. package/components/TimePicker/helpers/validateTimePicker.d.ts +0 -8
  214. package/components/TimePicker/helpers/validateTimePicker.js +0 -16
  215. package/components/TimePicker/helpers/validateTimePicker.js.map +0 -1
  216. package/components/TimePicker/hooks/useTimePickerDropdown.d.ts +0 -17
  217. package/components/TimePicker/hooks/useTimePickerDropdown.js +0 -62
  218. package/components/TimePicker/hooks/useTimePickerDropdown.js.map +0 -1
  219. package/components/TimePicker/hooks/useTimePickerSelection.d.ts +0 -18
  220. package/components/TimePicker/hooks/useTimePickerSelection.js +0 -66
  221. package/components/TimePicker/hooks/useTimePickerSelection.js.map +0 -1
  222. package/components/TimePicker/hooks/useTimePickerValue.d.ts +0 -18
  223. package/components/TimePicker/hooks/useTimePickerValue.js +0 -59
  224. package/components/TimePicker/hooks/useTimePickerValue.js.map +0 -1
  225. package/components/TimePicker/index.d.ts +0 -2
  226. package/components/TimePicker/index.js +0 -2
  227. package/components/TimePicker/index.js.map +0 -1
  228. package/components/TimePicker/locale/index.d.ts +0 -4
  229. package/components/TimePicker/locale/index.js +0 -9
  230. package/components/TimePicker/locale/index.js.map +0 -1
  231. package/components/TimePicker/locale/locales/en.d.ts +0 -2
  232. package/components/TimePicker/locale/locales/en.js +0 -5
  233. package/components/TimePicker/locale/locales/en.js.map +0 -1
  234. package/components/TimePicker/locale/locales/ru.d.ts +0 -2
  235. package/components/TimePicker/locale/locales/ru.js +0 -5
  236. package/components/TimePicker/locale/locales/ru.js.map +0 -1
  237. package/components/TimePicker/locale/types.d.ts +0 -4
  238. package/components/TimePicker/locale/types.js.map +0 -1
  239. package/internal/NativeTimeInput/NativeTimeInput.d.ts +0 -16
  240. package/internal/NativeTimeInput/NativeTimeInput.js +0 -25
  241. package/internal/NativeTimeInput/NativeTimeInput.js.map +0 -1
  242. package/internal/NativeTimeInput/NativeTimeInput.styles.d.ts +0 -3
  243. package/internal/NativeTimeInput/NativeTimeInput.styles.js +0 -15
  244. package/internal/NativeTimeInput/NativeTimeInput.styles.js.map +0 -1
  245. package/internal/NativeTimeInput/NativeTimeInput.utils.d.ts +0 -7
  246. package/internal/NativeTimeInput/NativeTimeInput.utils.js +0 -28
  247. package/internal/NativeTimeInput/NativeTimeInput.utils.js.map +0 -1
  248. package/internal/NativeTimeInput/index.d.ts +0 -1
  249. package/internal/NativeTimeInput/index.js +0 -2
  250. package/internal/NativeTimeInput/index.js.map +0 -1
  251. package/internal/TimeInput/TimeFragments.d.ts +0 -15
  252. package/internal/TimeInput/TimeFragments.js +0 -72
  253. package/internal/TimeInput/TimeFragments.js.map +0 -1
  254. package/internal/TimeInput/TimeFragments.styles.d.ts +0 -12
  255. package/internal/TimeInput/TimeFragments.styles.js +0 -43
  256. package/internal/TimeInput/TimeFragments.styles.js.map +0 -1
  257. package/internal/TimeInput/TimeInput.d.ts +0 -22
  258. package/internal/TimeInput/TimeInput.js +0 -103
  259. package/internal/TimeInput/TimeInput.js.map +0 -1
  260. package/internal/TimeInput/TimeInput.styles.js +0 -21
  261. package/internal/TimeInput/TimeInput.styles.js.map +0 -1
  262. package/internal/TimeInput/index.d.ts +0 -1
  263. package/internal/TimeInput/index.js +0 -2
  264. package/internal/TimeInput/index.js.map +0 -1
  265. package/internal/icons2022/TimeClockIcon/TimeClockIcon16Light.d.ts +0 -2
  266. package/internal/icons2022/TimeClockIcon/TimeClockIcon16Light.js +0 -20
  267. package/internal/icons2022/TimeClockIcon/TimeClockIcon16Light.js.map +0 -1
  268. package/internal/icons2022/TimeClockIcon/TimeClockIcon20Light.d.ts +0 -2
  269. package/internal/icons2022/TimeClockIcon/TimeClockIcon20Light.js +0 -20
  270. package/internal/icons2022/TimeClockIcon/TimeClockIcon20Light.js.map +0 -1
  271. package/internal/icons2022/TimeClockIcon/TimeClockIcon24Regular.d.ts +0 -2
  272. package/internal/icons2022/TimeClockIcon/TimeClockIcon24Regular.js +0 -20
  273. package/internal/icons2022/TimeClockIcon/TimeClockIcon24Regular.js.map +0 -1
  274. /package/components/{TimePicker/locale → MaskedInputV2/internal}/types.js +0 -0
@@ -0,0 +1,31 @@
1
+ import { ActionDetails } from '../react-imask/imask/core/action-details.js';
2
+ import { DIRECTION } from '../react-imask/imask/core/utils.js';
3
+ /**
4
+ * Применяет пользовательский ввод к IMask через `splice` и вычисляет новый raw с позицией курсора.
5
+ *
6
+ * @param params — состояние input до/после изменения.
7
+ * @returns новое raw, позицию курсора и флаг отклонённого ввода.
8
+ */
9
+ export function applyMaskedInputChange(params) {
10
+ var browserDraft = params.browserDraft, cursorPos = params.cursorPos, typedValue = params.typedValue, currentRaw = params.currentRaw, oldSelection = params.oldSelection, engine = params.engine;
11
+ var details = new ActionDetails({
12
+ value: browserDraft,
13
+ cursorPos: cursorPos,
14
+ oldValue: typedValue,
15
+ oldSelection: oldSelection,
16
+ });
17
+ var oldRawValue = engine.imask.unmaskedValue;
18
+ var spliceResult = engine.imask.splice(details.startChangePos, details.removed.length, details.inserted, details.removeDirection, { input: true, raw: true });
19
+ var removeDirection = oldRawValue === engine.imask.unmaskedValue ? details.removeDirection : DIRECTION.NONE;
20
+ var newCursorPos = engine.imask.nearestInputPos(details.startChangePos + spliceResult.offset, removeDirection);
21
+ if (removeDirection !== DIRECTION.NONE) {
22
+ newCursorPos = engine.imask.nearestInputPos(newCursorPos, DIRECTION.NONE);
23
+ }
24
+ var newRaw = engine.imask.rawInputValue;
25
+ return {
26
+ newRaw: newRaw,
27
+ cursorPos: newCursorPos,
28
+ rejected: newRaw === currentRaw,
29
+ };
30
+ }
31
+ //# sourceMappingURL=maskedCoreInputChange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maskedCoreInputChange.js","sourceRoot":"","sources":["maskedCoreInputChange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AA6B/D;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA+B;IAC5D,IAAA,YAAY,GAA8D,MAAM,aAApE,EAAE,SAAS,GAAmD,MAAM,UAAzD,EAAE,UAAU,GAAuC,MAAM,WAA7C,EAAE,UAAU,GAA2B,MAAM,WAAjC,EAAE,YAAY,GAAa,MAAM,aAAnB,EAAE,MAAM,GAAK,MAAM,OAAX,CAAY;IAEzF,IAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,KAAK,EAAE,YAAY;QACnB,SAAS,WAAA;QACT,QAAQ,EAAE,UAAU;QACpB,YAAY,cAAA;KACb,CAAC,CAAC;IAEH,IAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;IAE/C,IAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CACtC,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,OAAO,CAAC,MAAM,EACtB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,eAAe,EACvB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAC3B,CAAC;IAEF,IAAM,eAAe,GAAG,WAAW,KAAK,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;IAE9G,IAAI,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,cAAc,GAAG,YAAY,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/G,IAAI,eAAe,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;QACvC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC;IAED,IAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;IAE1C,OAAO;QACL,MAAM,QAAA;QACN,SAAS,EAAE,YAAY;QACvB,QAAQ,EAAE,MAAM,KAAK,UAAU;KAChC,CAAC;AACJ,CAAC","sourcesContent":["import { ActionDetails } from '../react-imask/imask/core/action-details.js';\nimport { DIRECTION } from '../react-imask/imask/core/utils.js';\nimport type { MaskEngine } from './types.js';\n\n/** Параметры обработки нативного `change` от `<input>`. */\nexport interface MaskedInputChangeParams {\n /** Черновик value, который браузер записал в input. */\n browserDraft: string;\n /** Позиция курсора после изменения. */\n cursorPos: number;\n /** Текущее typedValue из MaskState. */\n typedValue: string;\n /** Текущее raw-значение (источник истины). */\n currentRaw: string;\n /** Предыдущее выделение до изменения. */\n oldSelection: { start: number; end: number };\n /** IMask-движок. */\n engine: Pick<MaskEngine, 'imask'>;\n}\n\n/** Результат применения пользовательского ввода через IMask. */\nexport interface MaskedInputChangeResult {\n /** Новое raw после splice. */\n newRaw: string;\n /** Позиция курсора, которую нужно установить. */\n cursorPos: number;\n /** `true`, если символ не был принят (raw не изменился). */\n rejected: boolean;\n}\n\n/**\n * Применяет пользовательский ввод к IMask через `splice` и вычисляет новый raw с позицией курсора.\n *\n * @param params — состояние input до/после изменения.\n * @returns новое raw, позицию курсора и флаг отклонённого ввода.\n */\nexport function applyMaskedInputChange(params: MaskedInputChangeParams): MaskedInputChangeResult {\n const { browserDraft, cursorPos, typedValue, currentRaw, oldSelection, engine } = params;\n\n const details = new ActionDetails({\n value: browserDraft,\n cursorPos,\n oldValue: typedValue,\n oldSelection,\n });\n\n const oldRawValue = engine.imask.unmaskedValue;\n\n const spliceResult = engine.imask.splice(\n details.startChangePos,\n details.removed.length,\n details.inserted,\n details.removeDirection,\n { input: true, raw: true },\n );\n\n const removeDirection = oldRawValue === engine.imask.unmaskedValue ? details.removeDirection : DIRECTION.NONE;\n\n let newCursorPos = engine.imask.nearestInputPos(details.startChangePos + spliceResult.offset, removeDirection);\n if (removeDirection !== DIRECTION.NONE) {\n newCursorPos = engine.imask.nearestInputPos(newCursorPos, DIRECTION.NONE);\n }\n\n const newRaw = engine.imask.rawInputValue;\n\n return {\n newRaw,\n cursorPos: newCursorPos,\n rejected: newRaw === currentRaw,\n };\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type React from 'react';
2
+ type SelectionDirection = 'forward' | 'backward' | 'none';
3
+ /**
4
+ * Вычисляет новое выделение при навигации стрелками, Home/End и Ctrl/Alt+стрелками.
5
+ * Логика перенесена из FixedIMaskInput v1.
6
+ *
7
+ * @param e — keyboard event.
8
+ * @param maxPos — максимальная позиция курсора (typedLength).
9
+ * @param el — DOM input с текущим selection.
10
+ * @returns кортеж `[start, end, direction]` для `setSelectionRange`.
11
+ */
12
+ export declare function calcNavigationSelection(e: React.KeyboardEvent<HTMLInputElement>, maxPos: number, el: HTMLInputElement | null): [number, number, SelectionDirection];
13
+ export {};
@@ -0,0 +1,79 @@
1
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
+ if (ar || !(i in from)) {
4
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
+ ar[i] = from[i];
6
+ }
7
+ }
8
+ return to.concat(ar || Array.prototype.slice.call(from));
9
+ };
10
+ import { isKeyArrowHorizontal, isKeyArrowLeft, isKeyArrowUp, isKeyHome, isModShift, isShortcutJumpCaret, someKeys, } from '../../../lib/events/keyboard/identifiers.js';
11
+ /**
12
+ * Вычисляет новое выделение при навигации стрелками, Home/End и Ctrl/Alt+стрелками.
13
+ * Логика перенесена из FixedIMaskInput v1.
14
+ *
15
+ * @param e — keyboard event.
16
+ * @param maxPos — максимальная позиция курсора (typedLength).
17
+ * @param el — DOM input с текущим selection.
18
+ * @returns кортеж `[start, end, direction]` для `setSelectionRange`.
19
+ */
20
+ export function calcNavigationSelection(e, maxPos, el) {
21
+ var _a, _b, _c;
22
+ if (!el) {
23
+ return [0, 0, 'none'];
24
+ }
25
+ var start = (_a = el.selectionStart) !== null && _a !== void 0 ? _a : 0;
26
+ var end = (_b = el.selectionEnd) !== null && _b !== void 0 ? _b : 0;
27
+ var direction = ((_c = el.selectionDirection) !== null && _c !== void 0 ? _c : 'none');
28
+ var isSelectionMode = isModShift()(e);
29
+ var tail = start !== end && direction === 'backward' ? end : start;
30
+ var head = start !== end && direction === 'backward' ? start : end;
31
+ var headDirection = someKeys(isKeyArrowLeft, isKeyArrowUp, isKeyHome)(e) ? 'left' : 'right';
32
+ var step = isKeyArrowHorizontal(e) ? 1 : Infinity;
33
+ var increment = headDirection === 'left' ? -step : step;
34
+ var normalized = function (v) { return Math.min(maxPos, Math.max(0, v)); };
35
+ if (isShortcutJumpCaret(e)) {
36
+ head = jumpCaret(head, headDirection, el.value, maxPos);
37
+ }
38
+ else if (head !== tail && !isSelectionMode && isKeyArrowHorizontal(e)) {
39
+ head = headDirection === 'right' ? Math.max(tail, head) : Math.min(tail, head);
40
+ }
41
+ else {
42
+ head = head + increment;
43
+ }
44
+ if (isSelectionMode) {
45
+ var s = Math.min(tail, head);
46
+ var e2 = Math.max(tail, head);
47
+ return [normalized(s), normalized(e2), e2 === head ? 'forward' : 'backward'];
48
+ }
49
+ tail = head;
50
+ return [normalized(tail), normalized(head), 'none'];
51
+ }
52
+ /**
53
+ * Перемещает курсор к началу/концу следующего «слова» при Ctrl/Alt+стрелка.
54
+ *
55
+ * @param prev — текущая позиция курсора.
56
+ * @param headDirection — направление прыжка.
57
+ * @param value — текущее value input.
58
+ * @param maxPos — верхняя граница позиции курсора.
59
+ */
60
+ function jumpCaret(prev, headDirection, value, maxPos) {
61
+ var _a;
62
+ // CODE-1 fix: используем .source вместо .valueOf() — иначе "/" попадает в символы слова
63
+ var word = /а-яa-z0-9_/.source;
64
+ var wordRegExp = new RegExp("([".concat(word, "])+[\\s]*|([^").concat(word, "])+"), 'gi');
65
+ var normalized = function (v) { return Math.min(maxPos, Math.max(0, v)); };
66
+ var next = headDirection === 'right' ? prev : 0;
67
+ (_a = value.match(wordRegExp)) === null || _a === void 0 ? void 0 : _a.reduce(function (s, a) {
68
+ var pos = a.length + (s.slice(-1)[0] || 0);
69
+ if (headDirection === 'right' && next === prev && next < pos) {
70
+ next = normalized(pos);
71
+ }
72
+ else if (headDirection === 'left' && prev > pos) {
73
+ next = normalized(pos);
74
+ }
75
+ return __spreadArray(__spreadArray([], s, true), [pos], false);
76
+ }, []);
77
+ return next;
78
+ }
79
+ //# sourceMappingURL=maskedCoreNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maskedCoreNavigation.js","sourceRoot":"","sources":["maskedCoreNavigation.ts"],"names":[],"mappings":"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","sourcesContent":["import type React from 'react';\n\nimport {\n isKeyArrowHorizontal,\n isKeyArrowLeft,\n isKeyArrowUp,\n isKeyHome,\n isModShift,\n isShortcutJumpCaret,\n someKeys,\n} from '../../../lib/events/keyboard/identifiers.js';\n\ntype HeadDirection = 'left' | 'right';\ntype SelectionDirection = 'forward' | 'backward' | 'none';\n\n/**\n * Вычисляет новое выделение при навигации стрелками, Home/End и Ctrl/Alt+стрелками.\n * Логика перенесена из FixedIMaskInput v1.\n *\n * @param e — keyboard event.\n * @param maxPos — максимальная позиция курсора (typedLength).\n * @param el — DOM input с текущим selection.\n * @returns кортеж `[start, end, direction]` для `setSelectionRange`.\n */\nexport function calcNavigationSelection(\n e: React.KeyboardEvent<HTMLInputElement>,\n maxPos: number,\n el: HTMLInputElement | null,\n): [number, number, SelectionDirection] {\n if (!el) {\n return [0, 0, 'none'];\n }\n\n const start = el.selectionStart ?? 0;\n const end = el.selectionEnd ?? 0;\n const direction = (el.selectionDirection ?? 'none') as SelectionDirection;\n\n const isSelectionMode = isModShift()(e);\n let tail = start !== end && direction === 'backward' ? end : start;\n let head = start !== end && direction === 'backward' ? start : end;\n\n const headDirection: HeadDirection = someKeys(isKeyArrowLeft, isKeyArrowUp, isKeyHome)(e) ? 'left' : 'right';\n const step = isKeyArrowHorizontal(e) ? 1 : Infinity;\n const increment = headDirection === 'left' ? -step : step;\n\n const normalized = (v: number) => Math.min(maxPos, Math.max(0, v));\n\n if (isShortcutJumpCaret(e)) {\n head = jumpCaret(head, headDirection, el.value, maxPos);\n } else if (head !== tail && !isSelectionMode && isKeyArrowHorizontal(e)) {\n head = headDirection === 'right' ? Math.max(tail, head) : Math.min(tail, head);\n } else {\n head = head + increment;\n }\n\n if (isSelectionMode) {\n const s = Math.min(tail, head);\n const e2 = Math.max(tail, head);\n return [normalized(s), normalized(e2), e2 === head ? 'forward' : 'backward'];\n }\n\n tail = head;\n return [normalized(tail), normalized(head), 'none'];\n}\n\n/**\n * Перемещает курсор к началу/концу следующего «слова» при Ctrl/Alt+стрелка.\n *\n * @param prev — текущая позиция курсора.\n * @param headDirection — направление прыжка.\n * @param value — текущее value input.\n * @param maxPos — верхняя граница позиции курсора.\n */\nfunction jumpCaret(prev: number, headDirection: HeadDirection, value: string, maxPos: number): number {\n // CODE-1 fix: используем .source вместо .valueOf() — иначе \"/\" попадает в символы слова\n const word = /а-яa-z0-9_/.source;\n const wordRegExp = new RegExp(`([${word}])+[\\\\s]*|([^${word}])+`, 'gi');\n const normalized = (v: number) => Math.min(maxPos, Math.max(0, v));\n\n let next = headDirection === 'right' ? prev : 0;\n value.match(wordRegExp)?.reduce<number[]>((s, a) => {\n const pos = a.length + (s.slice(-1)[0] || 0);\n if (headDirection === 'right' && next === prev && next < pos) {\n next = normalized(pos);\n } else if (headDirection === 'left' && prev > pos) {\n next = normalized(pos);\n }\n return [...s, pos];\n }, []);\n\n return next;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { SlotMap } from './types.js';
2
+ /**
3
+ * Из выделенного диапазона displayValue убирает фиксированные символы маски,
4
+ * оставляя только пользовательские символы.
5
+ *
6
+ * @param selected — подстрока displayValue.
7
+ * @param slotMap — карта соответствия позиций маски и raw-слотов.
8
+ * @param startOffset — позиция начала выделения в displayValue.
9
+ * @returns строка без литералов маски.
10
+ */
11
+ export declare function stripMaskChars(selected: string, slotMap: SlotMap, startOffset: number): string;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Из выделенного диапазона displayValue убирает фиксированные символы маски,
3
+ * оставляя только пользовательские символы.
4
+ *
5
+ * @param selected — подстрока displayValue.
6
+ * @param slotMap — карта соответствия позиций маски и raw-слотов.
7
+ * @param startOffset — позиция начала выделения в displayValue.
8
+ * @returns строка без литералов маски.
9
+ */
10
+ export function stripMaskChars(selected, slotMap, startOffset) {
11
+ var result = '';
12
+ for (var i = 0; i < selected.length; i++) {
13
+ var maskedPos = startOffset + i;
14
+ if (slotMap.maskedToRaw[maskedPos] !== null && slotMap.maskedToRaw[maskedPos] !== undefined) {
15
+ result += selected[i];
16
+ }
17
+ }
18
+ return result;
19
+ }
20
+ //# sourceMappingURL=stripMaskChars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripMaskChars.js","sourceRoot":"","sources":["stripMaskChars.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,OAAgB,EAAE,WAAmB;IACpF,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAM,SAAS,GAAG,WAAW,GAAG,CAAC,CAAC;QAClC,IAAI,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5F,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { SlotMap } from './types.js';\n\n/**\n * Из выделенного диапазона displayValue убирает фиксированные символы маски,\n * оставляя только пользовательские символы.\n *\n * @param selected — подстрока displayValue.\n * @param slotMap — карта соответствия позиций маски и raw-слотов.\n * @param startOffset — позиция начала выделения в displayValue.\n * @returns строка без литералов маски.\n */\nexport function stripMaskChars(selected: string, slotMap: SlotMap, startOffset: number): string {\n let result = '';\n for (let i = 0; i < selected.length; i++) {\n const maskedPos = startOffset + i;\n if (slotMap.maskedToRaw[maskedPos] !== null && slotMap.maskedToRaw[maskedPos] !== undefined) {\n result += selected[i];\n }\n }\n return result;\n}\n"]}
@@ -0,0 +1,74 @@
1
+ import type { MaskedPattern } from '../react-imask/imask/index.js';
2
+ export interface MaskEngine {
3
+ compute(raw: string, focused: boolean): MaskState;
4
+ applyPaste(currentRaw: string, rawCursorPos: number, pasted: string): PasteResult;
5
+ slotMap: SlotMap;
6
+ imask: MaskedPattern;
7
+ }
8
+ export interface PasteResult {
9
+ raw: string;
10
+ overflow: boolean;
11
+ }
12
+ export interface MaskState {
13
+ /**
14
+ * Значение для <input value=...>.
15
+ * focused=true, alwaysShowMask=false: "12__" (с плейсхолдерами)
16
+ * focused=false, alwaysShowMask=false: "12" (lazy, без плейсхолдеров)
17
+ * alwaysShowMask=true: "12__" всегда
18
+ */
19
+ displayValue: string;
20
+ /**
21
+ * Подстрока displayValue от начала до конца последнего введённого символа
22
+ * (включая разделители маски внутри введённой части).
23
+ *
24
+ * mask="99.99", typed="12": displayValue="12.34" (нет — мы в данном примере typed="1234")
25
+ * mask="99.99", typed="12": displayValue="12.__", typedValue="12." ^^^
26
+ */
27
+ typedValue: string;
28
+ /**
29
+ * Длина typedValue в символах.
30
+ * typedValue="12." → typedLength=3
31
+ */
32
+ typedLength: number;
33
+ /**
34
+ * Значение для onValueChange.
35
+ * unmask=false: imask.value ("12.")
36
+ * unmask=true: imask.unmaskedValue ("12")
37
+ */
38
+ outputValue: string;
39
+ /**
40
+ * Маска заполнена полностью.
41
+ */
42
+ isComplete: boolean;
43
+ /**
44
+ * Количество принятых IMask пользовательских символов.
45
+ * raw="12345" для mask="999" → acceptedLength=3 ("123").
46
+ */
47
+ acceptedLength: number;
48
+ }
49
+ export interface HistoryState {
50
+ raw: string;
51
+ cursorPos: number;
52
+ }
53
+ export interface SlotMap {
54
+ /**
55
+ * Позиции пользовательских слотов в displayValue (при lazy=false, все плейсхолдеры видны).
56
+ * mask="99.99" → userSlots=[0, 1, 3, 4]
57
+ * displayValue="_._._" (пустое поле, alwaysShowMask)
58
+ */
59
+ userSlots: number[];
60
+ /**
61
+ * maskedToRaw[maskedPos] → rawPos | null
62
+ * null означает: позиция принадлежит фиксированному символу маски.
63
+ *
64
+ * mask="99.99": displayValue="_._._"
65
+ * maskedToRaw = [0, 1, null, 2, 3]
66
+ */
67
+ maskedToRaw: Array<number | null>;
68
+ /**
69
+ * rawToMasked[rawPos] → maskedPos
70
+ * Обратный maskedToRaw, только для пользовательских позиций.
71
+ * mask="99.99": rawToMasked = [0, 1, 3, 4]
72
+ */
73
+ rawToMasked: number[];
74
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MaskedPattern } from '../react-imask/imask/index.js';\n\nexport interface MaskEngine {\n compute(raw: string, focused: boolean): MaskState;\n applyPaste(currentRaw: string, rawCursorPos: number, pasted: string): PasteResult;\n slotMap: SlotMap;\n imask: MaskedPattern;\n}\n\nexport interface PasteResult {\n raw: string;\n overflow: boolean;\n}\n\nexport interface MaskState {\n /**\n * Значение для <input value=...>.\n * focused=true, alwaysShowMask=false: \"12__\" (с плейсхолдерами)\n * focused=false, alwaysShowMask=false: \"12\" (lazy, без плейсхолдеров)\n * alwaysShowMask=true: \"12__\" всегда\n */\n displayValue: string;\n\n /**\n * Подстрока displayValue от начала до конца последнего введённого символа\n * (включая разделители маски внутри введённой части).\n *\n * mask=\"99.99\", typed=\"12\": displayValue=\"12.34\" (нет — мы в данном примере typed=\"1234\")\n * mask=\"99.99\", typed=\"12\": displayValue=\"12.__\", typedValue=\"12.\" ^^^\n */\n typedValue: string;\n\n /**\n * Длина typedValue в символах.\n * typedValue=\"12.\" → typedLength=3\n */\n typedLength: number;\n\n /**\n * Значение для onValueChange.\n * unmask=false: imask.value (\"12.\")\n * unmask=true: imask.unmaskedValue (\"12\")\n */\n outputValue: string;\n\n /**\n * Маска заполнена полностью.\n */\n isComplete: boolean;\n\n /**\n * Количество принятых IMask пользовательских символов.\n * raw=\"12345\" для mask=\"999\" → acceptedLength=3 (\"123\").\n */\n acceptedLength: number;\n}\n\nexport interface HistoryState {\n raw: string;\n cursorPos: number;\n}\n\nexport interface SlotMap {\n /**\n * Позиции пользовательских слотов в displayValue (при lazy=false, все плейсхолдеры видны).\n * mask=\"99.99\" → userSlots=[0, 1, 3, 4]\n * displayValue=\"_._._\" (пустое поле, alwaysShowMask)\n */\n userSlots: number[];\n\n /**\n * maskedToRaw[maskedPos] → rawPos | null\n * null означает: позиция принадлежит фиксированному символу маски.\n *\n * mask=\"99.99\": displayValue=\"_._._\"\n * maskedToRaw = [0, 1, null, 2, 3]\n */\n maskedToRaw: Array<number | null>;\n\n /**\n * rawToMasked[rawPos] → maskedPos\n * Обратный maskedToRaw, только для пользовательских позиций.\n * mask=\"99.99\": rawToMasked = [0, 1, 3, 4]\n */\n rawToMasked: number[];\n}\n"]}
@@ -0,0 +1,42 @@
1
+ import type { MaskedPattern, MaskedPatternOptions } from '../react-imask/imask/index.js';
2
+ import type { IMaskInputProps } from '../react-imask/index.js';
3
+ import type { MaskState, SlotMap } from './types.js';
4
+ export interface MaskEngine {
5
+ /**
6
+ * Применить raw-ввод, получить MaskState.
7
+ * Чистая функция (без побочных эффектов на внешний стейт).
8
+ */
9
+ compute(raw: string, focused: boolean): MaskState;
10
+ /**
11
+ * Применить вставку с учётом текущего курсора.
12
+ * Возвращает новый raw и флаг переполнения.
13
+ */
14
+ applyPaste(currentRaw: string, rawCursorPos: number, pasted: string): PasteResult;
15
+ /** Карта слотов. Пересчитывается только при смене маски. */
16
+ slotMap: SlotMap;
17
+ /** Доступ к IMask-инстансу для edge cases (imaskProps escape hatch). */
18
+ imask: MaskedPattern;
19
+ }
20
+ interface PasteResult {
21
+ raw: string;
22
+ overflow: boolean;
23
+ }
24
+ export type MaskEager = NonNullable<MaskedPatternOptions['eager']>;
25
+ /** Пропсы хука {@link useMaskEngine}. */
26
+ interface UseMaskEngineProps {
27
+ mask: string;
28
+ maskChar?: string;
29
+ formatChars?: Record<string, string>;
30
+ unmask: boolean;
31
+ alwaysShowMask: boolean;
32
+ imaskProps?: IMaskInputProps<HTMLInputElement>;
33
+ }
34
+ /**
35
+ * Создаёт headless IMask-движок для MaskedInputV2.
36
+ * IMask используется как калькулятор состояния, без привязки к DOM.
37
+ *
38
+ * @param props — настройки маски и поведения отображения.
39
+ * @returns объект {@link MaskEngine} с методами `compute`, `applyPaste`, `slotMap` и `imask`.
40
+ */
41
+ export declare function useMaskEngine(props: UseMaskEngineProps): MaskEngine;
42
+ export {};
@@ -0,0 +1,82 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { useMemo } from 'react';
13
+ import { getDefinitions, getMaskChar } from '../MaskedInputV2.helpers.js';
14
+ import { createMask } from '../react-imask/imask/index.js';
15
+ import { buildSlotMap, extractRaw } from './helpers.js';
16
+ /**
17
+ * Создаёт headless IMask-движок для MaskedInputV2.
18
+ * IMask используется как калькулятор состояния, без привязки к DOM.
19
+ *
20
+ * @param props — настройки маски и поведения отображения.
21
+ * @returns объект {@link MaskEngine} с методами `compute`, `applyPaste`, `slotMap` и `imask`.
22
+ */
23
+ export function useMaskEngine(props) {
24
+ var _a, _b;
25
+ var mask = (_a = props.mask) !== null && _a !== void 0 ? _a : '';
26
+ var eager = (_b = props.imaskProps) === null || _b === void 0 ? void 0 : _b.eager;
27
+ var imask = useMemo(function () {
28
+ return createMask(__assign({ mask: mask.replace(/0/g, '{\\0}'), placeholderChar: getMaskChar(props.maskChar), definitions: getDefinitions(props.formatChars), eager: eager !== null && eager !== void 0 ? eager : 'append', overwrite: 'shift', lazy: true }, props.imaskProps));
29
+ },
30
+ // Пересоздавать только при изменении структуры маски:
31
+ [mask, props.imaskProps, props.maskChar, eager, JSON.stringify(props.formatChars)]);
32
+ // SlotMap пересчитывается при смене маски
33
+ var slotMap = useMemo(function () { return buildSlotMap(imask); }, [imask]);
34
+ function compute(raw, focused) {
35
+ var lazy = !props.alwaysShowMask && !focused;
36
+ // input: true → триггерит _appendEager, чтобы trailing fixed chars
37
+ // добавлялись и сохранялись при blur
38
+ imask.updateOptions({ lazy: true });
39
+ imask.resolve(raw, { input: true });
40
+ // При пустом raw _appendEager не вызывается автоматически (str пустой).
41
+ // Заполняем leading fixed chars только при фокусе (lazy=false),
42
+ // при blur (lazy=true) с пустым raw поле должно быть пустым.
43
+ if (focused && !raw && (imask.eager === 'append' || imask.eager === true)) {
44
+ imask._appendEager();
45
+ }
46
+ var lazyValue = imask.value;
47
+ var displayValue = lazyValue;
48
+ var typedValue = lazyValue;
49
+ // Для focused/alwaysShowMask пересчитываем с lazy=false,
50
+ // чтобы получить placeholders в displayValue
51
+ if (!lazy) {
52
+ imask.updateOptions({ lazy: false });
53
+ imask.resolve(raw, { input: true });
54
+ displayValue = imask.displayValue;
55
+ }
56
+ var outValue = raw === '' ? '' : imask.unmaskedValue;
57
+ return {
58
+ displayValue: displayValue,
59
+ typedValue: typedValue,
60
+ typedLength: typedValue.length,
61
+ outputValue: props.unmask ? outValue : lazyValue,
62
+ isComplete: imask.isComplete,
63
+ acceptedLength: imask.unmaskedValue.length,
64
+ };
65
+ }
66
+ function applyPaste(currentRaw, rawCursorPos, pasted) {
67
+ // Позиция вставки в raw: вставляем после rawCursorPos символов
68
+ var before = currentRaw.slice(0, rawCursorPos);
69
+ var after = currentRaw.slice(rawCursorPos);
70
+ // pasted может быть отформатированным (с литералами маски) — извлекаем raw
71
+ var pastedRaw = extractRaw(pasted, { imask: imask });
72
+ var candidate = before + pastedRaw + after;
73
+ imask.unmaskedValue = candidate;
74
+ var accepted = imask.rawInputValue;
75
+ return {
76
+ raw: accepted,
77
+ overflow: accepted.length < candidate.length,
78
+ };
79
+ }
80
+ return { compute: compute, applyPaste: applyPaste, slotMap: slotMap, imask: imask };
81
+ }
82
+ //# sourceMappingURL=useMaskEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMaskEngine.js","sourceRoot":"","sources":["useMaskEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\n\nimport { getDefinitions, getMaskChar } from '../MaskedInputV2.helpers.js';\nimport type { MaskedPattern, MaskedPatternOptions } from '../react-imask/imask/index.js';\nimport { createMask } from '../react-imask/imask/index.js';\nimport type { IMaskInputProps } from '../react-imask/index.js';\nimport { buildSlotMap, extractRaw } from './helpers.js';\nimport type { MaskState, SlotMap } from './types.js';\n\nexport interface MaskEngine {\n /**\n * Применить raw-ввод, получить MaskState.\n * Чистая функция (без побочных эффектов на внешний стейт).\n */\n compute(raw: string, focused: boolean): MaskState;\n\n /**\n * Применить вставку с учётом текущего курсора.\n * Возвращает новый raw и флаг переполнения.\n */\n applyPaste(currentRaw: string, rawCursorPos: number, pasted: string): PasteResult;\n\n /** Карта слотов. Пересчитывается только при смене маски. */\n slotMap: SlotMap;\n\n /** Доступ к IMask-инстансу для edge cases (imaskProps escape hatch). */\n imask: MaskedPattern;\n}\n\ninterface PasteResult {\n raw: string;\n overflow: boolean; // pasted содержал символы, которые IMask не принял\n}\n\nexport type MaskEager = NonNullable<MaskedPatternOptions['eager']>;\n\n/** Пропсы хука {@link useMaskEngine}. */\ninterface UseMaskEngineProps {\n mask: string;\n maskChar?: string;\n formatChars?: Record<string, string>;\n unmask: boolean;\n alwaysShowMask: boolean;\n imaskProps?: IMaskInputProps<HTMLInputElement>;\n}\n\n/**\n * Создаёт headless IMask-движок для MaskedInputV2.\n * IMask используется как калькулятор состояния, без привязки к DOM.\n *\n * @param props — настройки маски и поведения отображения.\n * @returns объект {@link MaskEngine} с методами `compute`, `applyPaste`, `slotMap` и `imask`.\n */\nexport function useMaskEngine(props: UseMaskEngineProps): MaskEngine {\n const mask = props.mask ?? '';\n const eager = props.imaskProps?.eager;\n const imask = useMemo(\n () =>\n createMask({\n mask: mask.replace(/0/g, '{\\\\0}') as any,\n placeholderChar: getMaskChar(props.maskChar),\n definitions: getDefinitions(props.formatChars),\n eager: eager ?? 'append', // TODO: 'remove' or 'append'\n overwrite: 'shift',\n lazy: true,\n ...(props.imaskProps as object),\n }) as unknown as MaskedPattern,\n // Пересоздавать только при изменении структуры маски:\n [mask, props.imaskProps, props.maskChar, eager, JSON.stringify(props.formatChars)],\n );\n\n // SlotMap пересчитывается при смене маски\n const slotMap = useMemo(() => buildSlotMap(imask), [imask]);\n\n function compute(raw: string, focused: boolean): MaskState {\n const lazy = !props.alwaysShowMask && !focused;\n\n // input: true → триггерит _appendEager, чтобы trailing fixed chars\n // добавлялись и сохранялись при blur\n imask.updateOptions({ lazy: true });\n imask.resolve(raw, { input: true });\n // При пустом raw _appendEager не вызывается автоматически (str пустой).\n // Заполняем leading fixed chars только при фокусе (lazy=false),\n // при blur (lazy=true) с пустым raw поле должно быть пустым.\n if (focused && !raw && (imask.eager === 'append' || imask.eager === true)) {\n imask._appendEager();\n }\n const lazyValue = imask.value;\n\n let displayValue = lazyValue;\n let typedValue = lazyValue;\n\n // Для focused/alwaysShowMask пересчитываем с lazy=false,\n // чтобы получить placeholders в displayValue\n if (!lazy) {\n imask.updateOptions({ lazy: false });\n imask.resolve(raw, { input: true });\n displayValue = imask.displayValue;\n }\n\n const outValue = raw === '' ? '' : imask.unmaskedValue;\n return {\n displayValue,\n typedValue,\n typedLength: typedValue.length,\n outputValue: props.unmask ? outValue : lazyValue,\n isComplete: imask.isComplete,\n acceptedLength: imask.unmaskedValue.length,\n };\n }\n\n function applyPaste(currentRaw: string, rawCursorPos: number, pasted: string): PasteResult {\n // Позиция вставки в raw: вставляем после rawCursorPos символов\n const before = currentRaw.slice(0, rawCursorPos);\n const after = currentRaw.slice(rawCursorPos);\n // pasted может быть отформатированным (с литералами маски) — извлекаем raw\n const pastedRaw = extractRaw(pasted, { imask });\n const candidate = before + pastedRaw + after;\n\n imask.unmaskedValue = candidate;\n const accepted = imask.rawInputValue;\n\n return {\n raw: accepted,\n overflow: accepted.length < candidate.length,\n };\n }\n\n return { compute, applyPaste, slotMap, imask };\n}\n"]}
@@ -0,0 +1,28 @@
1
+ import type React from 'react';
2
+ import type { MaskedCoreProps } from './MaskedCore.types.js';
3
+ type MaskedCoreHandlerProps = Pick<MaskedCoreProps, 'maskState' | 'slotMap' | 'engine' | 'currentRaw' | 'onRawChange' | 'onUnexpectedInput' | 'onUndo' | 'onRedo' | 'coreInputRef' | 'onKeyDown' | 'onMouseUp' | 'onInput' | 'onSelect' | 'onFocus' | 'onPaste'>;
4
+ /**
5
+ * Собирает обработчики DOM-событий для {@link MaskedCore}.
6
+ * Инкапсулирует логику ввода, навигации, clipboard и undo/redo.
7
+ *
8
+ * @param props — состояние маски, движок и колбэки от MaskedInputV2.
9
+ * @returns refs и обработчики для прямого `<input>`.
10
+ */
11
+ export declare function useMaskedCoreHandlers(props: MaskedCoreHandlerProps): {
12
+ pendingCursorRef: React.RefObject<number | null>;
13
+ selectionRange: {
14
+ start: number;
15
+ end: number;
16
+ };
17
+ syncSelection: (el: HTMLInputElement) => void;
18
+ handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
19
+ handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
20
+ handleSelect: (e?: React.SyntheticEvent<HTMLInputElement>) => void;
21
+ handlePaste: (e: React.ClipboardEvent<HTMLInputElement>) => void;
22
+ handleCopy: (e: React.ClipboardEvent<HTMLInputElement>) => void;
23
+ handleCut: (e: React.ClipboardEvent<HTMLInputElement>) => void;
24
+ handleInput: (e: React.ChangeEvent<HTMLInputElement>) => void;
25
+ handleMouseUp: (e: React.MouseEvent<HTMLInputElement>) => void;
26
+ handleFocus: (e: React.FocusEvent<HTMLInputElement>) => void;
27
+ };
28
+ export {};
@@ -0,0 +1,190 @@
1
+ import { useCallback, useRef, useState } from 'react';
2
+ import { isKeyArrow, isKeyBackspace, isKeyDelete, isKeyEnd, isKeyHome, isShortcutRedo, isShortcutSelectAll, isShortcutUndo, } from '../../../lib/events/keyboard/identifiers.js';
3
+ import { scrollInputCaretIntoView } from '../../../lib/scrollInputCaretIntoView.js';
4
+ import { extractRaw } from './extractRaw.js';
5
+ import { computeMaskedCut, getMaskedCopyText } from './maskedCoreClipboard.js';
6
+ import { computeMaskedDeletion } from './maskedCoreDeletion.js';
7
+ import { applyMaskedInputChange } from './maskedCoreInputChange.js';
8
+ import { calcNavigationSelection } from './maskedCoreNavigation.js';
9
+ /**
10
+ * Собирает обработчики DOM-событий для {@link MaskedCore}.
11
+ * Инкапсулирует логику ввода, навигации, clipboard и undo/redo.
12
+ *
13
+ * @param props — состояние маски, движок и колбэки от MaskedInputV2.
14
+ * @returns refs и обработчики для прямого `<input>`.
15
+ */
16
+ export function useMaskedCoreHandlers(props) {
17
+ var maskState = props.maskState, slotMap = props.slotMap, engine = props.engine, currentRaw = props.currentRaw, onRawChange = props.onRawChange, onUnexpectedInput = props.onUnexpectedInput, onUndo = props.onUndo, onRedo = props.onRedo, coreInputRef = props.coreInputRef, inputOnKeyDown = props.onKeyDown, inputOnMouseUp = props.onMouseUp, inputOnInput = props.onInput, inputOnSelect = props.onSelect, inputOnFocus = props.onFocus, inputOnPaste = props.onPaste;
18
+ var pendingCursorRef = useRef(null);
19
+ var lastSelectionRef = useRef({ start: 0, end: 0 });
20
+ var _a = useState({ start: 0, end: 0 }), selectionRange = _a[0], setSelectionRange = _a[1];
21
+ var syncSelection = useCallback(function (el) {
22
+ var _a, _b;
23
+ var start = (_a = el.selectionStart) !== null && _a !== void 0 ? _a : 0;
24
+ var end = (_b = el.selectionEnd) !== null && _b !== void 0 ? _b : 0;
25
+ lastSelectionRef.current = { start: start, end: end };
26
+ setSelectionRange(function (prev) { return (prev.start === start && prev.end === end ? prev : { start: start, end: end }); });
27
+ }, []);
28
+ function setPendingCursor(pos) {
29
+ var _a;
30
+ pendingCursorRef.current = pos;
31
+ (_a = coreInputRef.current) === null || _a === void 0 ? void 0 : _a.setSelectionRange(pos, pos);
32
+ }
33
+ function handleChange(e) {
34
+ var _a;
35
+ var _b = applyMaskedInputChange({
36
+ browserDraft: e.target.value,
37
+ cursorPos: (_a = e.target.selectionStart) !== null && _a !== void 0 ? _a : 0,
38
+ typedValue: maskState.typedValue,
39
+ currentRaw: currentRaw,
40
+ oldSelection: lastSelectionRef.current,
41
+ engine: engine,
42
+ }), newRaw = _b.newRaw, cursorPos = _b.cursorPos, rejected = _b.rejected;
43
+ setPendingCursor(cursorPos);
44
+ if (rejected) {
45
+ onUnexpectedInput();
46
+ return;
47
+ }
48
+ onRawChange(newRaw, 'input', cursorPos);
49
+ }
50
+ function handleKeyDown(e) {
51
+ var el = coreInputRef.current;
52
+ if (isShortcutSelectAll(e) || isKeyArrow(e) || isKeyEnd(e) || isKeyHome(e) || isKeyBackspace(e) || isKeyDelete(e)) {
53
+ pendingCursorRef.current = null;
54
+ }
55
+ if (isShortcutSelectAll(e)) {
56
+ e.preventDefault();
57
+ el === null || el === void 0 ? void 0 : el.setSelectionRange(0, maskState.typedLength);
58
+ if (el) {
59
+ scrollInputCaretIntoView(el);
60
+ syncSelection(el);
61
+ }
62
+ }
63
+ else if (isKeyArrow(e) || isKeyEnd(e) || isKeyHome(e)) {
64
+ e.preventDefault();
65
+ var _a = calcNavigationSelection(e, maskState.typedLength, el), start = _a[0], end = _a[1], dir = _a[2];
66
+ el === null || el === void 0 ? void 0 : el.setSelectionRange(start, end, dir);
67
+ if (el) {
68
+ scrollInputCaretIntoView(el);
69
+ syncSelection(el);
70
+ }
71
+ }
72
+ else if (isKeyBackspace(e) || isKeyDelete(e)) {
73
+ e.preventDefault();
74
+ if (el) {
75
+ handleDeletion(isKeyBackspace(e), el);
76
+ }
77
+ }
78
+ else if (isShortcutUndo(e)) {
79
+ e.preventDefault();
80
+ onUndo === null || onUndo === void 0 ? void 0 : onUndo();
81
+ }
82
+ else if (isShortcutRedo(e)) {
83
+ e.preventDefault();
84
+ onRedo === null || onRedo === void 0 ? void 0 : onRedo();
85
+ }
86
+ inputOnKeyDown === null || inputOnKeyDown === void 0 ? void 0 : inputOnKeyDown(e);
87
+ }
88
+ function handleDeletion(isBackspace, el) {
89
+ var _a, _b;
90
+ var result = computeMaskedDeletion({
91
+ isBackspace: isBackspace,
92
+ selStart: (_a = el.selectionStart) !== null && _a !== void 0 ? _a : 0,
93
+ selEnd: (_b = el.selectionEnd) !== null && _b !== void 0 ? _b : 0,
94
+ currentRaw: currentRaw,
95
+ slotMap: slotMap,
96
+ });
97
+ if (!result) {
98
+ onUnexpectedInput();
99
+ return;
100
+ }
101
+ pendingCursorRef.current = result.cursorPos;
102
+ onRawChange(result.newRaw, 'input', result.cursorPos);
103
+ }
104
+ function handleSelect(e) {
105
+ var _a, _b, _c;
106
+ var el = coreInputRef.current;
107
+ if (!el) {
108
+ return;
109
+ }
110
+ var max = maskState.typedLength;
111
+ var start = (_a = el.selectionStart) !== null && _a !== void 0 ? _a : 0;
112
+ var end = (_b = el.selectionEnd) !== null && _b !== void 0 ? _b : 0;
113
+ lastSelectionRef.current = { start: start, end: end };
114
+ if (end > max) {
115
+ el.setSelectionRange(Math.min(start, max), max, (_c = el.selectionDirection) !== null && _c !== void 0 ? _c : 'none');
116
+ }
117
+ syncSelection(el);
118
+ if (e) {
119
+ inputOnSelect === null || inputOnSelect === void 0 ? void 0 : inputOnSelect(e);
120
+ }
121
+ }
122
+ function handlePaste(e) {
123
+ inputOnPaste === null || inputOnPaste === void 0 ? void 0 : inputOnPaste(e);
124
+ e.preventDefault();
125
+ if (!e.clipboardData) {
126
+ return;
127
+ }
128
+ onRawChange(e.clipboardData.getData('text/plain'), 'paste');
129
+ }
130
+ function handleCopy(e) {
131
+ var _a, _b;
132
+ var el = coreInputRef.current;
133
+ if (!el) {
134
+ return;
135
+ }
136
+ var start = (_a = el.selectionStart) !== null && _a !== void 0 ? _a : 0;
137
+ var end = (_b = el.selectionEnd) !== null && _b !== void 0 ? _b : 0;
138
+ e.clipboardData.setData('text/plain', getMaskedCopyText(maskState.displayValue, start, end));
139
+ e.preventDefault();
140
+ }
141
+ function handleCut(e) {
142
+ var _a, _b;
143
+ handleCopy(e);
144
+ var el = coreInputRef.current;
145
+ if (!el) {
146
+ return;
147
+ }
148
+ var start = (_a = el.selectionStart) !== null && _a !== void 0 ? _a : 0;
149
+ var end = (_b = el.selectionEnd) !== null && _b !== void 0 ? _b : 0;
150
+ var _c = computeMaskedCut(start, end, currentRaw, slotMap), newRaw = _c.newRaw, cursorPos = _c.cursorPos;
151
+ pendingCursorRef.current = cursorPos;
152
+ onRawChange(newRaw, 'input', cursorPos);
153
+ }
154
+ function handleInput(e) {
155
+ inputOnInput === null || inputOnInput === void 0 ? void 0 : inputOnInput(e);
156
+ }
157
+ function handleMouseUp(e) {
158
+ handleSelect();
159
+ inputOnMouseUp === null || inputOnMouseUp === void 0 ? void 0 : inputOnMouseUp(e);
160
+ }
161
+ function handleFocus(e) {
162
+ var _a;
163
+ var domValue = e.currentTarget.value;
164
+ if (domValue !== maskState.typedValue) {
165
+ var syncedRaw = extractRaw(domValue, engine);
166
+ if (syncedRaw !== currentRaw) {
167
+ onRawChange(syncedRaw, 'input');
168
+ }
169
+ }
170
+ var clickedPos = (_a = e.target.selectionStart) !== null && _a !== void 0 ? _a : 0;
171
+ pendingCursorRef.current = Math.min(clickedPos, maskState.typedLength);
172
+ inputOnFocus === null || inputOnFocus === void 0 ? void 0 : inputOnFocus(e);
173
+ syncSelection(e.currentTarget);
174
+ }
175
+ return {
176
+ pendingCursorRef: pendingCursorRef,
177
+ selectionRange: selectionRange,
178
+ syncSelection: syncSelection,
179
+ handleChange: handleChange,
180
+ handleKeyDown: handleKeyDown,
181
+ handleSelect: handleSelect,
182
+ handlePaste: handlePaste,
183
+ handleCopy: handleCopy,
184
+ handleCut: handleCut,
185
+ handleInput: handleInput,
186
+ handleMouseUp: handleMouseUp,
187
+ handleFocus: handleFocus,
188
+ };
189
+ }
190
+ //# sourceMappingURL=useMaskedCoreHandlers.js.map