@composy/keyboard-core 0.0.1

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 (337) hide show
  1. package/README.md +37 -0
  2. package/dist/index.js +3605 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.min.js +1 -0
  5. package/es/icons.d.ts +58 -0
  6. package/es/icons.d.ts.map +1 -0
  7. package/es/icons.js +34 -0
  8. package/es/icons.js.map +1 -0
  9. package/es/index.d.ts +12 -0
  10. package/es/index.d.ts.map +1 -0
  11. package/es/index.js +36 -0
  12. package/es/layouts/amount.d.ts +14 -0
  13. package/es/layouts/amount.d.ts.map +1 -0
  14. package/es/layouts/amount.js +175 -0
  15. package/es/layouts/amount.js.map +1 -0
  16. package/es/layouts/bankcard.d.ts +15 -0
  17. package/es/layouts/bankcard.d.ts.map +1 -0
  18. package/es/layouts/bankcard.js +99 -0
  19. package/es/layouts/bankcard.js.map +1 -0
  20. package/es/layouts/email.d.ts +11 -0
  21. package/es/layouts/email.d.ts.map +1 -0
  22. package/es/layouts/email.js +126 -0
  23. package/es/layouts/email.js.map +1 -0
  24. package/es/layouts/idcard.d.ts +16 -0
  25. package/es/layouts/idcard.d.ts.map +1 -0
  26. package/es/layouts/idcard.js +99 -0
  27. package/es/layouts/idcard.js.map +1 -0
  28. package/es/layouts/index.d.ts +54 -0
  29. package/es/layouts/index.d.ts.map +1 -0
  30. package/es/layouts/index.js +78 -0
  31. package/es/layouts/index.js.map +1 -0
  32. package/es/layouts/license-plate.d.ts +35 -0
  33. package/es/layouts/license-plate.d.ts.map +1 -0
  34. package/es/layouts/license-plate.js +290 -0
  35. package/es/layouts/license-plate.js.map +1 -0
  36. package/es/layouts/number.d.ts +14 -0
  37. package/es/layouts/number.d.ts.map +1 -0
  38. package/es/layouts/number.js +168 -0
  39. package/es/layouts/number.js.map +1 -0
  40. package/es/layouts/phone.d.ts +15 -0
  41. package/es/layouts/phone.d.ts.map +1 -0
  42. package/es/layouts/phone.js +175 -0
  43. package/es/layouts/phone.js.map +1 -0
  44. package/es/layouts/punct.d.ts +7 -0
  45. package/es/layouts/punct.d.ts.map +1 -0
  46. package/es/layouts/punct.js +112 -0
  47. package/es/layouts/punct.js.map +1 -0
  48. package/es/layouts/qwerty.d.ts +10 -0
  49. package/es/layouts/qwerty.d.ts.map +1 -0
  50. package/es/layouts/qwerty.js +116 -0
  51. package/es/layouts/qwerty.js.map +1 -0
  52. package/es/layouts/search.d.ts +7 -0
  53. package/es/layouts/search.d.ts.map +1 -0
  54. package/es/layouts/search.js +101 -0
  55. package/es/layouts/search.js.map +1 -0
  56. package/es/layouts/symbol.d.ts +14 -0
  57. package/es/layouts/symbol.d.ts.map +1 -0
  58. package/es/layouts/symbol.js +194 -0
  59. package/es/layouts/symbol.js.map +1 -0
  60. package/es/layouts/url.d.ts +7 -0
  61. package/es/layouts/url.d.ts.map +1 -0
  62. package/es/layouts/url.js +99 -0
  63. package/es/layouts/url.js.map +1 -0
  64. package/es/layouts/verifycode.d.ts +15 -0
  65. package/es/layouts/verifycode.d.ts.map +1 -0
  66. package/es/layouts/verifycode.js +100 -0
  67. package/es/layouts/verifycode.js.map +1 -0
  68. package/es/managers/index.d.ts +8 -0
  69. package/es/managers/index.d.ts.map +1 -0
  70. package/es/managers/index.js +14 -0
  71. package/es/managers/keyboard-manager.d.ts +130 -0
  72. package/es/managers/keyboard-manager.d.ts.map +1 -0
  73. package/es/managers/keyboard-manager.js +374 -0
  74. package/es/managers/keyboard-manager.js.map +1 -0
  75. package/es/managers/keyboard-renderer.d.ts +115 -0
  76. package/es/managers/keyboard-renderer.d.ts.map +1 -0
  77. package/es/managers/keyboard-renderer.js +283 -0
  78. package/es/managers/keyboard-renderer.js.map +1 -0
  79. package/es/managers/position-manager.d.ts +72 -0
  80. package/es/managers/position-manager.d.ts.map +1 -0
  81. package/es/managers/position-manager.js +199 -0
  82. package/es/managers/position-manager.js.map +1 -0
  83. package/es/themes/index.d.ts +70 -0
  84. package/es/themes/index.d.ts.map +1 -0
  85. package/es/themes/index.js +99 -0
  86. package/es/themes/index.js.map +1 -0
  87. package/es/themes/presets.d.ts +39 -0
  88. package/es/themes/presets.d.ts.map +1 -0
  89. package/es/themes/presets.js +207 -0
  90. package/es/themes/presets.js.map +1 -0
  91. package/es/themes/types.d.ts +118 -0
  92. package/es/themes/types.d.ts.map +1 -0
  93. package/es/themes/types.js +10 -0
  94. package/es/types/index.d.ts +7 -0
  95. package/es/types/index.d.ts.map +1 -0
  96. package/es/types/index.js +10 -0
  97. package/es/types/keyboard.d.ts +253 -0
  98. package/es/types/keyboard.d.ts.map +1 -0
  99. package/es/types/keyboard.js +10 -0
  100. package/es/types/position.d.ts +139 -0
  101. package/es/types/position.d.ts.map +1 -0
  102. package/es/types/position.js +10 -0
  103. package/es/utils/device.d.ts +45 -0
  104. package/es/utils/device.d.ts.map +1 -0
  105. package/es/utils/device.js +111 -0
  106. package/es/utils/device.js.map +1 -0
  107. package/es/utils/dom.d.ts +69 -0
  108. package/es/utils/dom.d.ts.map +1 -0
  109. package/es/utils/dom.js +134 -0
  110. package/es/utils/dom.js.map +1 -0
  111. package/es/utils/event-emitter.d.ts +52 -0
  112. package/es/utils/event-emitter.d.ts.map +1 -0
  113. package/es/utils/event-emitter.js +99 -0
  114. package/es/utils/event-emitter.js.map +1 -0
  115. package/es/utils/formatters.d.ts +51 -0
  116. package/es/utils/formatters.d.ts.map +1 -0
  117. package/es/utils/formatters.js +57 -0
  118. package/es/utils/formatters.js.map +1 -0
  119. package/es/utils/index.d.ts +10 -0
  120. package/es/utils/index.d.ts.map +1 -0
  121. package/es/utils/index.js +16 -0
  122. package/es/utils/random.d.ts +71 -0
  123. package/es/utils/random.d.ts.map +1 -0
  124. package/es/utils/random.js +292 -0
  125. package/es/utils/random.js.map +1 -0
  126. package/esm/icons.d.ts +58 -0
  127. package/esm/icons.d.ts.map +1 -0
  128. package/esm/icons.js +34 -0
  129. package/esm/icons.js.map +1 -0
  130. package/esm/index.d.ts +12 -0
  131. package/esm/index.d.ts.map +1 -0
  132. package/esm/index.js +37 -0
  133. package/esm/layouts/amount.d.ts +14 -0
  134. package/esm/layouts/amount.d.ts.map +1 -0
  135. package/esm/layouts/amount.js +175 -0
  136. package/esm/layouts/amount.js.map +1 -0
  137. package/esm/layouts/bankcard.d.ts +15 -0
  138. package/esm/layouts/bankcard.d.ts.map +1 -0
  139. package/esm/layouts/bankcard.js +99 -0
  140. package/esm/layouts/bankcard.js.map +1 -0
  141. package/esm/layouts/email.d.ts +11 -0
  142. package/esm/layouts/email.d.ts.map +1 -0
  143. package/esm/layouts/email.js +126 -0
  144. package/esm/layouts/email.js.map +1 -0
  145. package/esm/layouts/idcard.d.ts +16 -0
  146. package/esm/layouts/idcard.d.ts.map +1 -0
  147. package/esm/layouts/idcard.js +99 -0
  148. package/esm/layouts/idcard.js.map +1 -0
  149. package/esm/layouts/index.d.ts +54 -0
  150. package/esm/layouts/index.d.ts.map +1 -0
  151. package/esm/layouts/index.js +78 -0
  152. package/esm/layouts/index.js.map +1 -0
  153. package/esm/layouts/license-plate.d.ts +35 -0
  154. package/esm/layouts/license-plate.d.ts.map +1 -0
  155. package/esm/layouts/license-plate.js +290 -0
  156. package/esm/layouts/license-plate.js.map +1 -0
  157. package/esm/layouts/number.d.ts +14 -0
  158. package/esm/layouts/number.d.ts.map +1 -0
  159. package/esm/layouts/number.js +168 -0
  160. package/esm/layouts/number.js.map +1 -0
  161. package/esm/layouts/phone.d.ts +15 -0
  162. package/esm/layouts/phone.d.ts.map +1 -0
  163. package/esm/layouts/phone.js +175 -0
  164. package/esm/layouts/phone.js.map +1 -0
  165. package/esm/layouts/punct.d.ts +7 -0
  166. package/esm/layouts/punct.d.ts.map +1 -0
  167. package/esm/layouts/punct.js +112 -0
  168. package/esm/layouts/punct.js.map +1 -0
  169. package/esm/layouts/qwerty.d.ts +10 -0
  170. package/esm/layouts/qwerty.d.ts.map +1 -0
  171. package/esm/layouts/qwerty.js +116 -0
  172. package/esm/layouts/qwerty.js.map +1 -0
  173. package/esm/layouts/search.d.ts +7 -0
  174. package/esm/layouts/search.d.ts.map +1 -0
  175. package/esm/layouts/search.js +101 -0
  176. package/esm/layouts/search.js.map +1 -0
  177. package/esm/layouts/symbol.d.ts +14 -0
  178. package/esm/layouts/symbol.d.ts.map +1 -0
  179. package/esm/layouts/symbol.js +194 -0
  180. package/esm/layouts/symbol.js.map +1 -0
  181. package/esm/layouts/url.d.ts +7 -0
  182. package/esm/layouts/url.d.ts.map +1 -0
  183. package/esm/layouts/url.js +99 -0
  184. package/esm/layouts/url.js.map +1 -0
  185. package/esm/layouts/verifycode.d.ts +15 -0
  186. package/esm/layouts/verifycode.d.ts.map +1 -0
  187. package/esm/layouts/verifycode.js +100 -0
  188. package/esm/layouts/verifycode.js.map +1 -0
  189. package/esm/managers/index.d.ts +8 -0
  190. package/esm/managers/index.d.ts.map +1 -0
  191. package/esm/managers/index.js +14 -0
  192. package/esm/managers/keyboard-manager.d.ts +130 -0
  193. package/esm/managers/keyboard-manager.d.ts.map +1 -0
  194. package/esm/managers/keyboard-manager.js +374 -0
  195. package/esm/managers/keyboard-manager.js.map +1 -0
  196. package/esm/managers/keyboard-renderer.d.ts +115 -0
  197. package/esm/managers/keyboard-renderer.d.ts.map +1 -0
  198. package/esm/managers/keyboard-renderer.js +283 -0
  199. package/esm/managers/keyboard-renderer.js.map +1 -0
  200. package/esm/managers/position-manager.d.ts +72 -0
  201. package/esm/managers/position-manager.d.ts.map +1 -0
  202. package/esm/managers/position-manager.js +199 -0
  203. package/esm/managers/position-manager.js.map +1 -0
  204. package/esm/themes/index.d.ts +70 -0
  205. package/esm/themes/index.d.ts.map +1 -0
  206. package/esm/themes/index.js +99 -0
  207. package/esm/themes/index.js.map +1 -0
  208. package/esm/themes/presets.d.ts +39 -0
  209. package/esm/themes/presets.d.ts.map +1 -0
  210. package/esm/themes/presets.js +207 -0
  211. package/esm/themes/presets.js.map +1 -0
  212. package/esm/themes/types.d.ts +118 -0
  213. package/esm/themes/types.d.ts.map +1 -0
  214. package/esm/themes/types.js +10 -0
  215. package/esm/types/index.d.ts +7 -0
  216. package/esm/types/index.d.ts.map +1 -0
  217. package/esm/types/index.js +10 -0
  218. package/esm/types/keyboard.d.ts +253 -0
  219. package/esm/types/keyboard.d.ts.map +1 -0
  220. package/esm/types/keyboard.js +10 -0
  221. package/esm/types/position.d.ts +139 -0
  222. package/esm/types/position.d.ts.map +1 -0
  223. package/esm/types/position.js +10 -0
  224. package/esm/utils/device.d.ts +45 -0
  225. package/esm/utils/device.d.ts.map +1 -0
  226. package/esm/utils/device.js +111 -0
  227. package/esm/utils/device.js.map +1 -0
  228. package/esm/utils/dom.d.ts +69 -0
  229. package/esm/utils/dom.d.ts.map +1 -0
  230. package/esm/utils/dom.js +134 -0
  231. package/esm/utils/dom.js.map +1 -0
  232. package/esm/utils/event-emitter.d.ts +52 -0
  233. package/esm/utils/event-emitter.d.ts.map +1 -0
  234. package/esm/utils/event-emitter.js +99 -0
  235. package/esm/utils/event-emitter.js.map +1 -0
  236. package/esm/utils/formatters.d.ts +51 -0
  237. package/esm/utils/formatters.d.ts.map +1 -0
  238. package/esm/utils/formatters.js +57 -0
  239. package/esm/utils/formatters.js.map +1 -0
  240. package/esm/utils/index.d.ts +10 -0
  241. package/esm/utils/index.d.ts.map +1 -0
  242. package/esm/utils/index.js +16 -0
  243. package/esm/utils/random.d.ts +71 -0
  244. package/esm/utils/random.d.ts.map +1 -0
  245. package/esm/utils/random.js +292 -0
  246. package/esm/utils/random.js.map +1 -0
  247. package/lib/icons.cjs +44 -0
  248. package/lib/icons.cjs.map +1 -0
  249. package/lib/icons.d.ts +58 -0
  250. package/lib/index.cjs +141 -0
  251. package/lib/index.d.ts +12 -0
  252. package/lib/layouts/amount.cjs +177 -0
  253. package/lib/layouts/amount.cjs.map +1 -0
  254. package/lib/layouts/amount.d.ts +14 -0
  255. package/lib/layouts/bankcard.cjs +100 -0
  256. package/lib/layouts/bankcard.cjs.map +1 -0
  257. package/lib/layouts/bankcard.d.ts +15 -0
  258. package/lib/layouts/email.cjs +128 -0
  259. package/lib/layouts/email.cjs.map +1 -0
  260. package/lib/layouts/email.d.ts +11 -0
  261. package/lib/layouts/idcard.cjs +100 -0
  262. package/lib/layouts/idcard.cjs.map +1 -0
  263. package/lib/layouts/idcard.d.ts +16 -0
  264. package/lib/layouts/index.cjs +107 -0
  265. package/lib/layouts/index.cjs.map +1 -0
  266. package/lib/layouts/index.d.ts +54 -0
  267. package/lib/layouts/license-plate.cjs +296 -0
  268. package/lib/layouts/license-plate.cjs.map +1 -0
  269. package/lib/layouts/license-plate.d.ts +35 -0
  270. package/lib/layouts/number.cjs +170 -0
  271. package/lib/layouts/number.cjs.map +1 -0
  272. package/lib/layouts/number.d.ts +14 -0
  273. package/lib/layouts/phone.cjs +177 -0
  274. package/lib/layouts/phone.cjs.map +1 -0
  275. package/lib/layouts/phone.d.ts +15 -0
  276. package/lib/layouts/punct.cjs +113 -0
  277. package/lib/layouts/punct.cjs.map +1 -0
  278. package/lib/layouts/punct.d.ts +7 -0
  279. package/lib/layouts/qwerty.cjs +117 -0
  280. package/lib/layouts/qwerty.cjs.map +1 -0
  281. package/lib/layouts/qwerty.d.ts +10 -0
  282. package/lib/layouts/search.cjs +102 -0
  283. package/lib/layouts/search.cjs.map +1 -0
  284. package/lib/layouts/search.d.ts +7 -0
  285. package/lib/layouts/symbol.cjs +196 -0
  286. package/lib/layouts/symbol.cjs.map +1 -0
  287. package/lib/layouts/symbol.d.ts +14 -0
  288. package/lib/layouts/url.cjs +100 -0
  289. package/lib/layouts/url.cjs.map +1 -0
  290. package/lib/layouts/url.d.ts +7 -0
  291. package/lib/layouts/verifycode.cjs +101 -0
  292. package/lib/layouts/verifycode.cjs.map +1 -0
  293. package/lib/layouts/verifycode.d.ts +15 -0
  294. package/lib/managers/index.cjs +20 -0
  295. package/lib/managers/index.d.ts +8 -0
  296. package/lib/managers/keyboard-manager.cjs +376 -0
  297. package/lib/managers/keyboard-manager.cjs.map +1 -0
  298. package/lib/managers/keyboard-manager.d.ts +130 -0
  299. package/lib/managers/keyboard-renderer.cjs +285 -0
  300. package/lib/managers/keyboard-renderer.cjs.map +1 -0
  301. package/lib/managers/keyboard-renderer.d.ts +115 -0
  302. package/lib/managers/position-manager.cjs +201 -0
  303. package/lib/managers/position-manager.cjs.map +1 -0
  304. package/lib/managers/position-manager.d.ts +72 -0
  305. package/lib/package.json +3 -0
  306. package/lib/themes/index.cjs +117 -0
  307. package/lib/themes/index.cjs.map +1 -0
  308. package/lib/themes/index.d.ts +70 -0
  309. package/lib/themes/presets.cjs +214 -0
  310. package/lib/themes/presets.cjs.map +1 -0
  311. package/lib/themes/presets.d.ts +39 -0
  312. package/lib/themes/types.cjs +11 -0
  313. package/lib/themes/types.d.ts +118 -0
  314. package/lib/types/index.cjs +11 -0
  315. package/lib/types/index.d.ts +7 -0
  316. package/lib/types/keyboard.cjs +11 -0
  317. package/lib/types/keyboard.d.ts +253 -0
  318. package/lib/types/position.cjs +11 -0
  319. package/lib/types/position.d.ts +139 -0
  320. package/lib/utils/device.cjs +120 -0
  321. package/lib/utils/device.cjs.map +1 -0
  322. package/lib/utils/device.d.ts +45 -0
  323. package/lib/utils/dom.cjs +148 -0
  324. package/lib/utils/dom.cjs.map +1 -0
  325. package/lib/utils/dom.d.ts +69 -0
  326. package/lib/utils/event-emitter.cjs +100 -0
  327. package/lib/utils/event-emitter.cjs.map +1 -0
  328. package/lib/utils/event-emitter.d.ts +52 -0
  329. package/lib/utils/formatters.cjs +66 -0
  330. package/lib/utils/formatters.cjs.map +1 -0
  331. package/lib/utils/formatters.d.ts +51 -0
  332. package/lib/utils/index.cjs +58 -0
  333. package/lib/utils/index.d.ts +10 -0
  334. package/lib/utils/random.cjs +301 -0
  335. package/lib/utils/random.cjs.map +1 -0
  336. package/lib/utils/random.d.ts +71 -0
  337. package/package.json +121 -0
@@ -0,0 +1,148 @@
1
+ /*!
2
+ * ***********************************
3
+ * @composy/keyboard-core v0.0.1 *
4
+ * Built with rollup *
5
+ * Build time: 2024-08-17 11:33:29 *
6
+ * Build mode: production *
7
+ * Minified: No *
8
+ * ***********************************
9
+ */
10
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
11
+ //#region src/utils/dom.ts
12
+ function getBoundingRect(element) {
13
+ const rect = element.getBoundingClientRect();
14
+ return {
15
+ x: rect.left,
16
+ y: rect.top,
17
+ width: rect.width,
18
+ height: rect.height
19
+ };
20
+ }
21
+ function getElementOffset(element) {
22
+ const rect = element.getBoundingClientRect();
23
+ const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
24
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
25
+ return {
26
+ x: rect.left + scrollLeft,
27
+ y: rect.top + scrollTop
28
+ };
29
+ }
30
+ function isElementInViewport(element) {
31
+ const rect = element.getBoundingClientRect();
32
+ return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
33
+ }
34
+ function isClickOutside(event, element) {
35
+ const target = event.target;
36
+ return !element.contains(target);
37
+ }
38
+ function preventDefaultAndStopPropagation(event) {
39
+ event.preventDefault();
40
+ event.stopPropagation();
41
+ }
42
+ function onClickOutside(element, callback) {
43
+ const handler = (event) => {
44
+ if (isClickOutside(event, element)) callback(event);
45
+ };
46
+ document.addEventListener("mousedown", handler);
47
+ document.addEventListener("touchstart", handler);
48
+ return () => {
49
+ document.removeEventListener("mousedown", handler);
50
+ document.removeEventListener("touchstart", handler);
51
+ };
52
+ }
53
+ function scrollIntoViewIfNeeded(element, container) {
54
+ if (!container) {
55
+ element.scrollIntoView({
56
+ behavior: "smooth",
57
+ block: "nearest"
58
+ });
59
+ return;
60
+ }
61
+ const elementRect = element.getBoundingClientRect();
62
+ const containerRect = container.getBoundingClientRect();
63
+ if (elementRect.bottom > containerRect.bottom) container.scrollTop += elementRect.bottom - containerRect.bottom;
64
+ else if (elementRect.top < containerRect.top) container.scrollTop -= containerRect.top - elementRect.top;
65
+ }
66
+ function getInputCursorPosition(input) {
67
+ return input.selectionStart ?? input.value.length;
68
+ }
69
+ function setInputCursorPosition(input, position) {
70
+ input.setSelectionRange(position, position);
71
+ }
72
+ function insertTextAtCursor(input, text, maxLength) {
73
+ const start = input.selectionStart ?? input.value.length;
74
+ const end = input.selectionEnd ?? input.value.length;
75
+ const currentValue = input.value;
76
+ let newValue = currentValue.substring(0, start) + text + currentValue.substring(end);
77
+ if (maxLength !== void 0 && newValue.length > maxLength) {
78
+ const allowedLength = maxLength - (currentValue.length - (end - start));
79
+ if (allowedLength <= 0) return {
80
+ value: currentValue,
81
+ cursorPosition: start
82
+ };
83
+ newValue = currentValue.substring(0, start) + text.substring(0, allowedLength) + currentValue.substring(end);
84
+ }
85
+ const newCursorPosition = start + text.length;
86
+ return {
87
+ value: newValue,
88
+ cursorPosition: Math.min(newCursorPosition, newValue.length)
89
+ };
90
+ }
91
+ function deleteCharBeforeCursor(input) {
92
+ const start = input.selectionStart ?? input.value.length;
93
+ const end = input.selectionEnd ?? input.value.length;
94
+ const currentValue = input.value;
95
+ if (start !== end) {
96
+ const deletedChar2 = currentValue.substring(start, end);
97
+ return {
98
+ value: currentValue.substring(0, start) + currentValue.substring(end),
99
+ deletedChar: deletedChar2,
100
+ cursorPosition: start
101
+ };
102
+ }
103
+ if (start === 0) return {
104
+ value: currentValue,
105
+ deletedChar: "",
106
+ cursorPosition: 0
107
+ };
108
+ const deletedChar = currentValue.charAt(start - 1);
109
+ return {
110
+ value: currentValue.substring(0, start - 1) + currentValue.substring(start),
111
+ deletedChar,
112
+ cursorPosition: start - 1
113
+ };
114
+ }
115
+ function createElement(tag, attrs, children) {
116
+ const element = document.createElement(tag);
117
+ if (attrs) Object.entries(attrs).forEach(([key, value]) => {
118
+ element.setAttribute(key, value);
119
+ });
120
+ if (children) children.forEach((child) => {
121
+ if (typeof child === "string") element.appendChild(document.createTextNode(child));
122
+ else element.appendChild(child);
123
+ });
124
+ return element;
125
+ }
126
+ function toggleClass(element, className, force) {
127
+ element.classList.toggle(className, force);
128
+ }
129
+ function setStyles(element, styles) {
130
+ Object.assign(element.style, styles);
131
+ }
132
+ //#endregion
133
+ exports.createElement = createElement;
134
+ exports.deleteCharBeforeCursor = deleteCharBeforeCursor;
135
+ exports.getBoundingRect = getBoundingRect;
136
+ exports.getElementOffset = getElementOffset;
137
+ exports.getInputCursorPosition = getInputCursorPosition;
138
+ exports.insertTextAtCursor = insertTextAtCursor;
139
+ exports.isClickOutside = isClickOutside;
140
+ exports.isElementInViewport = isElementInViewport;
141
+ exports.onClickOutside = onClickOutside;
142
+ exports.preventDefaultAndStopPropagation = preventDefaultAndStopPropagation;
143
+ exports.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
144
+ exports.setInputCursorPosition = setInputCursorPosition;
145
+ exports.setStyles = setStyles;
146
+ exports.toggleClass = toggleClass;
147
+ /*! End of @composy/keyboard-core | Powered by @composy/builder */
148
+ //# sourceMappingURL=dom.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.cjs","names":["deletedChar","newValue"],"sources":["../../src/utils/dom.ts"],"sourcesContent":["/**\n * DOM 操作工具\n * @module utils/dom\n */\n\nimport type { BoundingRect, Position } from '../types'\n\n/**\n * 获取元素的边界矩形\n */\nexport function getBoundingRect(element: HTMLElement): BoundingRect {\n const rect = element.getBoundingClientRect()\n return {\n x: rect.left,\n y: rect.top,\n width: rect.width,\n height: rect.height,\n }\n}\n\n/**\n * 获取元素相对于文档的位置\n */\nexport function getElementOffset(element: HTMLElement): Position {\n const rect = element.getBoundingClientRect()\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop\n\n return {\n x: rect.left + scrollLeft,\n y: rect.top + scrollTop,\n }\n}\n\n/**\n * 检查元素是否在视口内\n */\nexport function isElementInViewport(element: HTMLElement): boolean {\n const rect = element.getBoundingClientRect()\n return (\n rect.top >= 0\n && rect.left >= 0\n && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)\n && rect.right <= (window.innerWidth || document.documentElement.clientWidth)\n )\n}\n\n/**\n * 检查点击是否在元素外部\n */\nexport function isClickOutside(event: MouseEvent | TouchEvent, element: HTMLElement): boolean {\n const target = event.target as Node\n return !element.contains(target)\n}\n\n/**\n * 阻止元素默认事件(用于防止输入框获取焦点)\n */\nexport function preventDefaultAndStopPropagation(event: Event): void {\n event.preventDefault()\n event.stopPropagation()\n}\n\n/**\n * 添加点击外部监听\n */\nexport function onClickOutside(\n element: HTMLElement,\n callback: (event: MouseEvent | TouchEvent) => void,\n): () => void {\n const handler = (event: MouseEvent | TouchEvent) => {\n if (isClickOutside(event, element)) {\n callback(event)\n }\n }\n\n document.addEventListener('mousedown', handler)\n document.addEventListener('touchstart', handler)\n\n return () => {\n document.removeEventListener('mousedown', handler)\n document.removeEventListener('touchstart', handler)\n }\n}\n\n/**\n * 滚动元素到可视区域\n */\nexport function scrollIntoViewIfNeeded(element: HTMLElement, container?: HTMLElement): void {\n if (!container) {\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest' })\n return\n }\n\n const elementRect = element.getBoundingClientRect()\n const containerRect = container.getBoundingClientRect()\n\n if (elementRect.bottom > containerRect.bottom) {\n container.scrollTop += elementRect.bottom - containerRect.bottom\n }\n else if (elementRect.top < containerRect.top) {\n container.scrollTop -= containerRect.top - elementRect.top\n }\n}\n\n/**\n * 获取输入框的光标位置\n */\nexport function getInputCursorPosition(input: HTMLInputElement | HTMLTextAreaElement): number {\n return input.selectionStart ?? input.value.length\n}\n\n/**\n * 设置输入框的光标位置\n */\nexport function setInputCursorPosition(\n input: HTMLInputElement | HTMLTextAreaElement,\n position: number,\n): void {\n input.setSelectionRange(position, position)\n}\n\n/**\n * 在输入框当前光标位置插入文本\n */\nexport function insertTextAtCursor(\n input: HTMLInputElement | HTMLTextAreaElement,\n text: string,\n maxLength?: number,\n): { value: string; cursorPosition: number } {\n const start = input.selectionStart ?? input.value.length\n const end = input.selectionEnd ?? input.value.length\n const currentValue = input.value\n\n let newValue = currentValue.substring(0, start) + text + currentValue.substring(end)\n\n // 检查最大长度\n if (maxLength !== undefined && newValue.length > maxLength) {\n const allowedLength = maxLength - (currentValue.length - (end - start))\n if (allowedLength <= 0) {\n return { value: currentValue, cursorPosition: start }\n }\n newValue = currentValue.substring(0, start) + text.substring(0, allowedLength) + currentValue.substring(end)\n }\n\n const newCursorPosition = start + text.length\n\n return {\n value: newValue,\n cursorPosition: Math.min(newCursorPosition, newValue.length),\n }\n}\n\n/**\n * 删除输入框光标前的字符\n */\nexport function deleteCharBeforeCursor(\n input: HTMLInputElement | HTMLTextAreaElement,\n): { value: string; deletedChar: string; cursorPosition: number } {\n const start = input.selectionStart ?? input.value.length\n const end = input.selectionEnd ?? input.value.length\n const currentValue = input.value\n\n // 如果有选中内容,删除选中内容\n if (start !== end) {\n const deletedChar = currentValue.substring(start, end)\n const newValue = currentValue.substring(0, start) + currentValue.substring(end)\n return {\n value: newValue,\n deletedChar,\n cursorPosition: start,\n }\n }\n\n // 没有选中内容,删除光标前一个字符\n if (start === 0) {\n return {\n value: currentValue,\n deletedChar: '',\n cursorPosition: 0,\n }\n }\n\n const deletedChar = currentValue.charAt(start - 1)\n const newValue = currentValue.substring(0, start - 1) + currentValue.substring(start)\n\n return {\n value: newValue,\n deletedChar,\n cursorPosition: start - 1,\n }\n}\n\n/**\n * 创建 DOM 元素\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string>,\n children?: (HTMLElement | string)[],\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tag)\n\n if (attrs) {\n Object.entries(attrs).forEach(([key, value]) => {\n element.setAttribute(key, value)\n })\n }\n\n if (children) {\n children.forEach((child) => {\n if (typeof child === 'string') {\n element.appendChild(document.createTextNode(child))\n }\n else {\n element.appendChild(child)\n }\n })\n }\n\n return element\n}\n\n/**\n * 添加/移除 CSS 类\n */\nexport function toggleClass(element: HTMLElement, className: string, force?: boolean): void {\n element.classList.toggle(className, force)\n}\n\n/**\n * 设置 CSS 样式\n */\nexport function setStyles(element: HTMLElement, styles: Partial<CSSStyleDeclaration>): void {\n Object.assign(element.style, styles)\n}\n"],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * DOM 操作工具
3
+ * @module utils/dom
4
+ */
5
+ import type { BoundingRect, Position } from '../types';
6
+ /**
7
+ * 获取元素的边界矩形
8
+ */
9
+ export declare function getBoundingRect(element: HTMLElement): BoundingRect;
10
+ /**
11
+ * 获取元素相对于文档的位置
12
+ */
13
+ export declare function getElementOffset(element: HTMLElement): Position;
14
+ /**
15
+ * 检查元素是否在视口内
16
+ */
17
+ export declare function isElementInViewport(element: HTMLElement): boolean;
18
+ /**
19
+ * 检查点击是否在元素外部
20
+ */
21
+ export declare function isClickOutside(event: MouseEvent | TouchEvent, element: HTMLElement): boolean;
22
+ /**
23
+ * 阻止元素默认事件(用于防止输入框获取焦点)
24
+ */
25
+ export declare function preventDefaultAndStopPropagation(event: Event): void;
26
+ /**
27
+ * 添加点击外部监听
28
+ */
29
+ export declare function onClickOutside(element: HTMLElement, callback: (event: MouseEvent | TouchEvent) => void): () => void;
30
+ /**
31
+ * 滚动元素到可视区域
32
+ */
33
+ export declare function scrollIntoViewIfNeeded(element: HTMLElement, container?: HTMLElement): void;
34
+ /**
35
+ * 获取输入框的光标位置
36
+ */
37
+ export declare function getInputCursorPosition(input: HTMLInputElement | HTMLTextAreaElement): number;
38
+ /**
39
+ * 设置输入框的光标位置
40
+ */
41
+ export declare function setInputCursorPosition(input: HTMLInputElement | HTMLTextAreaElement, position: number): void;
42
+ /**
43
+ * 在输入框当前光标位置插入文本
44
+ */
45
+ export declare function insertTextAtCursor(input: HTMLInputElement | HTMLTextAreaElement, text: string, maxLength?: number): {
46
+ value: string;
47
+ cursorPosition: number;
48
+ };
49
+ /**
50
+ * 删除输入框光标前的字符
51
+ */
52
+ export declare function deleteCharBeforeCursor(input: HTMLInputElement | HTMLTextAreaElement): {
53
+ value: string;
54
+ deletedChar: string;
55
+ cursorPosition: number;
56
+ };
57
+ /**
58
+ * 创建 DOM 元素
59
+ */
60
+ export declare function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, attrs?: Record<string, string>, children?: (HTMLElement | string)[]): HTMLElementTagNameMap[K];
61
+ /**
62
+ * 添加/移除 CSS 类
63
+ */
64
+ export declare function toggleClass(element: HTMLElement, className: string, force?: boolean): void;
65
+ /**
66
+ * 设置 CSS 样式
67
+ */
68
+ export declare function setStyles(element: HTMLElement, styles: Partial<CSSStyleDeclaration>): void;
69
+ //# sourceMappingURL=dom.d.ts.map
@@ -0,0 +1,100 @@
1
+ /*!
2
+ * ***********************************
3
+ * @composy/keyboard-core v0.0.1 *
4
+ * Built with rollup *
5
+ * Build time: 2024-08-17 11:33:29 *
6
+ * Build mode: production *
7
+ * Minified: No *
8
+ * ***********************************
9
+ */
10
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
11
+ //#region src/utils/event-emitter.ts
12
+ var EventEmitter = class {
13
+ constructor() {
14
+ this.handlers = /* @__PURE__ */ new Map();
15
+ }
16
+ /**
17
+ * 订阅事件
18
+ */
19
+ on(event, handler, options = {}) {
20
+ if (!this.handlers.has(event)) this.handlers.set(event, /* @__PURE__ */ new Set());
21
+ const handlers = this.handlers.get(event);
22
+ const wrapper = {
23
+ handler,
24
+ options
25
+ };
26
+ handlers.add(wrapper);
27
+ return () => {
28
+ handlers.delete(wrapper);
29
+ if (handlers.size === 0) this.handlers.delete(event);
30
+ };
31
+ }
32
+ /**
33
+ * 订阅事件(仅触发一次)
34
+ */
35
+ once(event, handler, options = {}) {
36
+ return this.on(event, handler, {
37
+ ...options,
38
+ once: true
39
+ });
40
+ }
41
+ /**
42
+ * 取消订阅事件
43
+ */
44
+ off(event, handler) {
45
+ if (!handler) {
46
+ this.handlers.delete(event);
47
+ return;
48
+ }
49
+ const handlers = this.handlers.get(event);
50
+ if (handlers) {
51
+ handlers.forEach((wrapper) => {
52
+ if (wrapper.handler === handler) handlers.delete(wrapper);
53
+ });
54
+ if (handlers.size === 0) this.handlers.delete(event);
55
+ }
56
+ }
57
+ /**
58
+ * 发布事件
59
+ */
60
+ emit(event, data) {
61
+ const handlers = this.handlers.get(event);
62
+ if (!handlers || handlers.size === 0) return;
63
+ const sortedHandlers = Array.from(handlers).sort((a, b) => {
64
+ const priorityA = a.options.priority ?? 0;
65
+ return (b.options.priority ?? 0) - priorityA;
66
+ });
67
+ const toRemove = [];
68
+ sortedHandlers.forEach((wrapper) => {
69
+ try {
70
+ wrapper.handler(data);
71
+ if (wrapper.options.once) toRemove.push(wrapper);
72
+ } catch (error) {
73
+ console.error(`[KeyboardEventEmitter] Error in event handler for "${String(event)}":`, error);
74
+ }
75
+ });
76
+ toRemove.forEach((wrapper) => handlers.delete(wrapper));
77
+ if (handlers.size === 0) this.handlers.delete(event);
78
+ }
79
+ /**
80
+ * 清除所有事件订阅
81
+ */
82
+ clear() {
83
+ this.handlers.clear();
84
+ }
85
+ /**
86
+ * 获取事件订阅数量
87
+ */
88
+ listenerCount(event) {
89
+ if (event !== void 0) return this.handlers.get(event)?.size ?? 0;
90
+ let count = 0;
91
+ this.handlers.forEach((handlers) => {
92
+ count += handlers.size;
93
+ });
94
+ return count;
95
+ }
96
+ };
97
+ //#endregion
98
+ exports.EventEmitter = EventEmitter;
99
+ /*! End of @composy/keyboard-core | Powered by @composy/builder */
100
+ //# sourceMappingURL=event-emitter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-emitter.cjs","names":[],"sources":["../../src/utils/event-emitter.ts"],"sourcesContent":["/**\n * 事件发射器\n * @module utils/event-emitter\n */\n\n/**\n * 事件处理函数类型\n */\nexport type EventHandler<T = unknown> = (data: T) => void\n\n/**\n * 事件处理器配置\n */\nexport interface EventHandlerOptions {\n /**\n * 是否只触发一次\n */\n once?: boolean\n\n /**\n * 优先级(数字越大优先级越高)\n */\n priority?: number\n}\n\n/**\n * 内部事件处理器包装\n */\ninterface EventHandlerWrapper<T> {\n handler: EventHandler<T>\n options: EventHandlerOptions\n}\n\n/**\n * 事件发射器类\n */\nexport class EventEmitter<EventMap extends Record<string, unknown>> {\n private handlers = new Map<keyof EventMap, Set<EventHandlerWrapper<unknown>>>()\n\n /**\n * 订阅事件\n */\n on<K extends keyof EventMap>(\n event: K,\n handler: EventHandler<EventMap[K]>,\n options: EventHandlerOptions = {},\n ): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set())\n }\n\n const handlers = this.handlers.get(event)!\n const wrapper: EventHandlerWrapper<EventMap[K]> = {\n handler: handler as EventHandler<unknown>,\n options,\n }\n\n handlers.add(wrapper as EventHandlerWrapper<unknown>)\n\n return () => {\n handlers.delete(wrapper as EventHandlerWrapper<unknown>)\n if (handlers.size === 0) {\n this.handlers.delete(event)\n }\n }\n }\n\n /**\n * 订阅事件(仅触发一次)\n */\n once<K extends keyof EventMap>(\n event: K,\n handler: EventHandler<EventMap[K]>,\n options: EventHandlerOptions = {},\n ): () => void {\n return this.on(event, handler, { ...options, once: true })\n }\n\n /**\n * 取消订阅事件\n */\n off<K extends keyof EventMap>(\n event: K,\n handler?: EventHandler<EventMap[K]>,\n ): void {\n if (!handler) {\n this.handlers.delete(event)\n return\n }\n\n const handlers = this.handlers.get(event)\n if (handlers) {\n handlers.forEach((wrapper) => {\n if (wrapper.handler === handler) {\n handlers.delete(wrapper)\n }\n })\n if (handlers.size === 0) {\n this.handlers.delete(event)\n }\n }\n }\n\n /**\n * 发布事件\n */\n emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void {\n const handlers = this.handlers.get(event)\n if (!handlers || handlers.size === 0) {\n return\n }\n\n // 按优先级排序\n const sortedHandlers = Array.from(handlers).sort((a, b) => {\n const priorityA = a.options.priority ?? 0\n const priorityB = b.options.priority ?? 0\n return priorityB - priorityA\n })\n\n const toRemove: EventHandlerWrapper<unknown>[] = []\n\n sortedHandlers.forEach((wrapper) => {\n try {\n wrapper.handler(data)\n if (wrapper.options.once) {\n toRemove.push(wrapper)\n }\n }\n catch (error) {\n console.error(`[KeyboardEventEmitter] Error in event handler for \"${String(event)}\":`, error)\n }\n })\n\n // 移除 once 处理器\n toRemove.forEach(wrapper => handlers.delete(wrapper))\n if (handlers.size === 0) {\n this.handlers.delete(event)\n }\n }\n\n /**\n * 清除所有事件订阅\n */\n clear(): void {\n this.handlers.clear()\n }\n\n /**\n * 获取事件订阅数量\n */\n listenerCount(event?: keyof EventMap): number {\n if (event !== undefined) {\n return this.handlers.get(event)?.size ?? 0\n }\n\n let count = 0\n this.handlers.forEach((handlers) => {\n count += handlers.size\n })\n return count\n }\n}\n"],"mappings":";;;;;;;;;;;AAoCO,IAAM,eAAN,MAA6D;CAA7D,cAAA;EACL,KAAQ,2BAAW,IAAI,IAAuD;CAAA;;;;CAK9E,GACE,OACA,SACA,UAA+B,CAAC,GACpB;EACZ,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,GAC1B,KAAK,SAAS,IAAI,uBAAO,IAAI,IAAI,CAAC;EAGpC,MAAM,WAAW,KAAK,SAAS,IAAI,KAAK;EACxC,MAAM,UAA4C;GAChD;GACA;EACF;EAEA,SAAS,IAAI,OAAuC;EAEpD,aAAa;GACX,SAAS,OAAO,OAAuC;GACvD,IAAI,SAAS,SAAS,GACpB,KAAK,SAAS,OAAO,KAAK;EAE9B;CACF;;;;CAKA,KACE,OACA,SACA,UAA+B,CAAC,GACpB;EACZ,OAAO,KAAK,GAAG,OAAO,SAAS;GAAE,GAAG;GAAS,MAAM;EAAK,CAAC;CAC3D;;;;CAKA,IACE,OACA,SACM;EACN,IAAI,CAAC,SAAS;GACZ,KAAK,SAAS,OAAO,KAAK;GAC1B;EACF;EAEA,MAAM,WAAW,KAAK,SAAS,IAAI,KAAK;EACxC,IAAI,UAAU;GACZ,SAAS,SAAS,YAAY;IAC5B,IAAI,QAAQ,YAAY,SACtB,SAAS,OAAO,OAAO;GAE3B,CAAC;GACD,IAAI,SAAS,SAAS,GACpB,KAAK,SAAS,OAAO,KAAK;EAE9B;CACF;;;;CAKA,KAA+B,OAAU,MAAyB;EAChE,MAAM,WAAW,KAAK,SAAS,IAAI,KAAK;EACxC,IAAI,CAAC,YAAY,SAAS,SAAS,GACjC;EAIF,MAAM,iBAAiB,MAAM,KAAK,QAAQ,CAAA,CAAE,MAAM,GAAG,MAAM;GACzD,MAAM,YAAY,EAAE,QAAQ,YAAY;GAExC,QADkB,EAAE,QAAQ,YAAY,KACrB;EACrB,CAAC;EAED,MAAM,WAA2C,CAAC;EAElD,eAAe,SAAS,YAAY;GAClC,IAAI;IACF,QAAQ,QAAQ,IAAI;IACpB,IAAI,QAAQ,QAAQ,MAClB,SAAS,KAAK,OAAO;GAEzB,SACO,OAAO;IACZ,QAAQ,MAAM,sDAAsD,OAAO,KAAK,EAAC,KAAM,KAAK;GAC9F;EACF,CAAC;EAGD,SAAS,SAAQ,YAAW,SAAS,OAAO,OAAO,CAAC;EACpD,IAAI,SAAS,SAAS,GACpB,KAAK,SAAS,OAAO,KAAK;CAE9B;;;;CAKA,QAAc;EACZ,KAAK,SAAS,MAAM;CACtB;;;;CAKA,cAAc,OAAgC;EAC5C,IAAI,UAAU,KAAA,GACZ,OAAO,KAAK,SAAS,IAAI,KAAK,CAAA,EAAG,QAAQ;EAG3C,IAAI,QAAQ;EACZ,KAAK,SAAS,SAAS,aAAa;GAClC,SAAS,SAAS;EACpB,CAAC;EACD,OAAO;CACT;AACF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * 事件发射器
3
+ * @module utils/event-emitter
4
+ */
5
+ /**
6
+ * 事件处理函数类型
7
+ */
8
+ export type EventHandler<T = unknown> = (data: T) => void;
9
+ /**
10
+ * 事件处理器配置
11
+ */
12
+ export interface EventHandlerOptions {
13
+ /**
14
+ * 是否只触发一次
15
+ */
16
+ once?: boolean;
17
+ /**
18
+ * 优先级(数字越大优先级越高)
19
+ */
20
+ priority?: number;
21
+ }
22
+ /**
23
+ * 事件发射器类
24
+ */
25
+ export declare class EventEmitter<EventMap extends Record<string, unknown>> {
26
+ private handlers;
27
+ /**
28
+ * 订阅事件
29
+ */
30
+ on<K extends keyof EventMap>(event: K, handler: EventHandler<EventMap[K]>, options?: EventHandlerOptions): () => void;
31
+ /**
32
+ * 订阅事件(仅触发一次)
33
+ */
34
+ once<K extends keyof EventMap>(event: K, handler: EventHandler<EventMap[K]>, options?: EventHandlerOptions): () => void;
35
+ /**
36
+ * 取消订阅事件
37
+ */
38
+ off<K extends keyof EventMap>(event: K, handler?: EventHandler<EventMap[K]>): void;
39
+ /**
40
+ * 发布事件
41
+ */
42
+ emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void;
43
+ /**
44
+ * 清除所有事件订阅
45
+ */
46
+ clear(): void;
47
+ /**
48
+ * 获取事件订阅数量
49
+ */
50
+ listenerCount(event?: keyof EventMap): number;
51
+ }
52
+ //# sourceMappingURL=event-emitter.d.ts.map
@@ -0,0 +1,66 @@
1
+ /*!
2
+ * ***********************************
3
+ * @composy/keyboard-core v0.0.1 *
4
+ * Built with rollup *
5
+ * Build time: 2024-08-17 11:33:29 *
6
+ * Build mode: production *
7
+ * Minified: No *
8
+ * ***********************************
9
+ */
10
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
11
+ //#region src/utils/formatters.ts
12
+ function formatPhone(value) {
13
+ const digits = value.replace(/\D/g, "").slice(0, 11);
14
+ if (digits.length <= 3) return digits;
15
+ if (digits.length <= 7) return `${digits.slice(0, 3)} ${digits.slice(3)}`;
16
+ return `${digits.slice(0, 3)} ${digits.slice(3, 7)} ${digits.slice(7)}`;
17
+ }
18
+ function formatBankCard(value) {
19
+ return value.replace(/\D/g, "").slice(0, 19).replace(/(\d{4})(?=\d)/g, "$1 ");
20
+ }
21
+ function formatAmount(value, decimalPlaces = 2) {
22
+ let result = value.replace(/[^\d.]/g, "");
23
+ const parts = result.split(".");
24
+ if (parts.length > 2) result = parts[0] + "." + parts.slice(1).join("");
25
+ if (parts.length === 2 && parts[1].length > decimalPlaces) result = parts[0] + "." + parts[1].slice(0, decimalPlaces);
26
+ if (result.length > 1 && result.startsWith("0") && result[1] !== ".") result = result.replace(/^0+/, "") || "0";
27
+ return result;
28
+ }
29
+ function formatIdCard(value) {
30
+ return value.replace(/[^\dXx]/g, "").slice(0, 18).toUpperCase();
31
+ }
32
+ function formatLicensePlate(value) {
33
+ return value.toUpperCase().slice(0, 8);
34
+ }
35
+ function formatVerifyCode(value, length = 6) {
36
+ return value.replace(/\D/g, "").slice(0, length);
37
+ }
38
+ const formatters = /* @__PURE__ */ new Map([
39
+ ["phone", formatPhone],
40
+ ["bankcard", formatBankCard],
41
+ ["idcard", formatIdCard],
42
+ ["license-plate", formatLicensePlate],
43
+ ["verifycode", formatVerifyCode]
44
+ ]);
45
+ function registerFormatter(name, formatter) {
46
+ formatters.set(name, formatter);
47
+ }
48
+ function getFormatter(name) {
49
+ return formatters.get(name);
50
+ }
51
+ function applyFormatter(name, value) {
52
+ const formatter = formatters.get(name);
53
+ return formatter ? formatter(value) : value;
54
+ }
55
+ //#endregion
56
+ exports.applyFormatter = applyFormatter;
57
+ exports.formatAmount = formatAmount;
58
+ exports.formatBankCard = formatBankCard;
59
+ exports.formatIdCard = formatIdCard;
60
+ exports.formatLicensePlate = formatLicensePlate;
61
+ exports.formatPhone = formatPhone;
62
+ exports.formatVerifyCode = formatVerifyCode;
63
+ exports.getFormatter = getFormatter;
64
+ exports.registerFormatter = registerFormatter;
65
+ /*! End of @composy/keyboard-core | Powered by @composy/builder */
66
+ //# sourceMappingURL=formatters.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.cjs","names":[],"sources":["../../src/utils/formatters.ts"],"sourcesContent":["/**\n * 输入格式化工具\n * @module utils/formatters\n */\n\n/**\n * 格式化手机号 (3-4-4)\n * @example formatPhone('13812345678') => '138 1234 5678'\n */\nexport function formatPhone(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 11)\n if (digits.length <= 3) return digits\n if (digits.length <= 7) return `${digits.slice(0, 3)} ${digits.slice(3)}`\n return `${digits.slice(0, 3)} ${digits.slice(3, 7)} ${digits.slice(7)}`\n}\n\n/**\n * 格式化银行卡号 (4-4-4-4-3)\n * @example formatBankCard('6222021234567890123') => '6222 0212 3456 7890 123'\n */\nexport function formatBankCard(value: string): string {\n const digits = value.replace(/\\D/g, '').slice(0, 19)\n return digits.replace(/(\\d{4})(?=\\d)/g, '$1 ')\n}\n\n/**\n * 格式化金额(限制小数位数)\n * @param value - 输入值\n * @param decimalPlaces - 小数位数,默认 2\n */\nexport function formatAmount(value: string, decimalPlaces: number = 2): string {\n // 移除非数字和小数点\n let result = value.replace(/[^\\d.]/g, '')\n\n // 只保留第一个小数点\n const parts = result.split('.')\n if (parts.length > 2) {\n result = parts[0] + '.' + parts.slice(1).join('')\n }\n\n // 限制小数位数\n if (parts.length === 2 && parts[1].length > decimalPlaces) {\n result = parts[0] + '.' + parts[1].slice(0, decimalPlaces)\n }\n\n // 移除前导零(保留 0.xx 格式)\n if (result.length > 1 && result.startsWith('0') && result[1] !== '.') {\n result = result.replace(/^0+/, '') || '0'\n }\n\n return result\n}\n\n/**\n * 格式化身份证号(自动大写 X)\n */\nexport function formatIdCard(value: string): string {\n return value\n .replace(/[^\\dXx]/g, '')\n .slice(0, 18)\n .toUpperCase()\n}\n\n/**\n * 格式化车牌号\n */\nexport function formatLicensePlate(value: string): string {\n return value.toUpperCase().slice(0, 8)\n}\n\n/**\n * 格式化验证码(纯数字)\n * @param value - 输入值\n * @param length - 验证码长度,默认 6\n */\nexport function formatVerifyCode(value: string, length: number = 6): string {\n return value.replace(/\\D/g, '').slice(0, length)\n}\n\n/**\n * 通用格式化器注册表\n */\nexport type FormatterFunction = (value: string) => string\n\nconst formatters: Map<string, FormatterFunction> = new Map([\n ['phone', formatPhone],\n ['bankcard', formatBankCard],\n ['idcard', formatIdCard],\n ['license-plate', formatLicensePlate],\n ['verifycode', formatVerifyCode],\n])\n\n/**\n * 注册自定义格式化器\n */\nexport function registerFormatter(name: string, formatter: FormatterFunction): void {\n formatters.set(name, formatter)\n}\n\n/**\n * 获取格式化器\n */\nexport function getFormatter(name: string): FormatterFunction | undefined {\n return formatters.get(name)\n}\n\n/**\n * 应用格式化\n */\nexport function applyFormatter(name: string, value: string): string {\n const formatter = formatters.get(name)\n return formatter ? formatter(value) : value\n}\n"],"mappings":";;;;;;;;;;;AASO,SAAS,YAAY,OAAuB;CACjD,MAAM,SAAS,MAAM,QAAQ,OAAO,EAAE,CAAA,CAAE,MAAM,GAAG,EAAE;CACnD,IAAI,OAAO,UAAU,GAAG,OAAO;CAC/B,IAAI,OAAO,UAAU,GAAG,OAAO,GAAG,OAAO,MAAM,GAAG,CAAC,EAAC,GAAI,OAAO,MAAM,CAAC;CACtE,OAAO,GAAG,OAAO,MAAM,GAAG,CAAC,EAAC,GAAI,OAAO,MAAM,GAAG,CAAC,EAAC,GAAI,OAAO,MAAM,CAAC;AACtE;AAMO,SAAS,eAAe,OAAuB;CAEpD,OADe,MAAM,QAAQ,OAAO,EAAE,CAAA,CAAE,MAAM,GAAG,EAC1C,CAAA,CAAO,QAAQ,kBAAkB,KAAK;AAC/C;AAOO,SAAS,aAAa,OAAe,gBAAwB,GAAW;CAE7E,IAAI,SAAS,MAAM,QAAQ,WAAW,EAAE;CAGxC,MAAM,QAAQ,OAAO,MAAM,GAAG;CAC9B,IAAI,MAAM,SAAS,GACjB,SAAS,MAAM,KAAK,MAAM,MAAM,MAAM,CAAC,CAAA,CAAE,KAAK,EAAE;CAIlD,IAAI,MAAM,WAAW,KAAK,MAAM,EAAC,CAAE,SAAS,eAC1C,SAAS,MAAM,KAAK,MAAM,MAAM,EAAC,CAAE,MAAM,GAAG,aAAa;CAI3D,IAAI,OAAO,SAAS,KAAK,OAAO,WAAW,GAAG,KAAK,OAAO,OAAO,KAC/D,SAAS,OAAO,QAAQ,OAAO,EAAE,KAAK;CAGxC,OAAO;AACT;AAKO,SAAS,aAAa,OAAuB;CAClD,OAAO,MACJ,QAAQ,YAAY,EAAE,CAAA,CACtB,MAAM,GAAG,EAAE,CAAA,CACX,YAAY;AACjB;AAKO,SAAS,mBAAmB,OAAuB;CACxD,OAAO,MAAM,YAAY,CAAA,CAAE,MAAM,GAAG,CAAC;AACvC;AAOO,SAAS,iBAAiB,OAAe,SAAiB,GAAW;CAC1E,OAAO,MAAM,QAAQ,OAAO,EAAE,CAAA,CAAE,MAAM,GAAG,MAAM;AACjD;AAOA,MAAM,6BAA6C,IAAI,IAAI;CACzD,CAAC,SAAS,WAAW;CACrB,CAAC,YAAY,cAAc;CAC3B,CAAC,UAAU,YAAY;CACvB,CAAC,iBAAiB,kBAAkB;CACpC,CAAC,cAAc,gBAAgB;AACjC,CAAC;AAKM,SAAS,kBAAkB,MAAc,WAAoC;CAClF,WAAW,IAAI,MAAM,SAAS;AAChC;AAKO,SAAS,aAAa,MAA6C;CACxE,OAAO,WAAW,IAAI,IAAI;AAC5B;AAKO,SAAS,eAAe,MAAc,OAAuB;CAClE,MAAM,YAAY,WAAW,IAAI,IAAI;CACrC,OAAO,YAAY,UAAU,KAAK,IAAI;AACxC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 输入格式化工具
3
+ * @module utils/formatters
4
+ */
5
+ /**
6
+ * 格式化手机号 (3-4-4)
7
+ * @example formatPhone('13812345678') => '138 1234 5678'
8
+ */
9
+ export declare function formatPhone(value: string): string;
10
+ /**
11
+ * 格式化银行卡号 (4-4-4-4-3)
12
+ * @example formatBankCard('6222021234567890123') => '6222 0212 3456 7890 123'
13
+ */
14
+ export declare function formatBankCard(value: string): string;
15
+ /**
16
+ * 格式化金额(限制小数位数)
17
+ * @param value - 输入值
18
+ * @param decimalPlaces - 小数位数,默认 2
19
+ */
20
+ export declare function formatAmount(value: string, decimalPlaces?: number): string;
21
+ /**
22
+ * 格式化身份证号(自动大写 X)
23
+ */
24
+ export declare function formatIdCard(value: string): string;
25
+ /**
26
+ * 格式化车牌号
27
+ */
28
+ export declare function formatLicensePlate(value: string): string;
29
+ /**
30
+ * 格式化验证码(纯数字)
31
+ * @param value - 输入值
32
+ * @param length - 验证码长度,默认 6
33
+ */
34
+ export declare function formatVerifyCode(value: string, length?: number): string;
35
+ /**
36
+ * 通用格式化器注册表
37
+ */
38
+ export type FormatterFunction = (value: string) => string;
39
+ /**
40
+ * 注册自定义格式化器
41
+ */
42
+ export declare function registerFormatter(name: string, formatter: FormatterFunction): void;
43
+ /**
44
+ * 获取格式化器
45
+ */
46
+ export declare function getFormatter(name: string): FormatterFunction | undefined;
47
+ /**
48
+ * 应用格式化
49
+ */
50
+ export declare function applyFormatter(name: string, value: string): string;
51
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1,58 @@
1
+ /*!
2
+ * ***********************************
3
+ * @composy/keyboard-core v0.0.1 *
4
+ * Built with rollup *
5
+ * Build time: 2024-08-17 11:33:29 *
6
+ * Build mode: production *
7
+ * Minified: No *
8
+ * ***********************************
9
+ */
10
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
11
+ const require_event_emitter = require("./event-emitter.cjs");
12
+ const require_device = require("./device.cjs");
13
+ const require_dom = require("./dom.cjs");
14
+ const require_random = require("./random.cjs");
15
+ const require_formatters = require("./formatters.cjs");
16
+ exports.EventEmitter = require_event_emitter.EventEmitter;
17
+ exports.applyFormatter = require_formatters.applyFormatter;
18
+ exports.createElement = require_dom.createElement;
19
+ exports.createRandomLetterLayout = require_random.createRandomLetterLayout;
20
+ exports.createRandomMixedLayout = require_random.createRandomMixedLayout;
21
+ exports.createRandomNumberLayout = require_random.createRandomNumberLayout;
22
+ exports.createRandomPinLayout = require_random.createRandomPinLayout;
23
+ exports.deleteCharBeforeCursor = require_dom.deleteCharBeforeCursor;
24
+ exports.formatAmount = require_formatters.formatAmount;
25
+ exports.formatBankCard = require_formatters.formatBankCard;
26
+ exports.formatIdCard = require_formatters.formatIdCard;
27
+ exports.formatLicensePlate = require_formatters.formatLicensePlate;
28
+ exports.formatPhone = require_formatters.formatPhone;
29
+ exports.formatVerifyCode = require_formatters.formatVerifyCode;
30
+ exports.getBoundingRect = require_dom.getBoundingRect;
31
+ exports.getDeviceType = require_device.getDeviceType;
32
+ exports.getElementOffset = require_dom.getElementOffset;
33
+ exports.getFormatter = require_formatters.getFormatter;
34
+ exports.getInputCursorPosition = require_dom.getInputCursorPosition;
35
+ exports.getRandomAlphanumeric = require_random.getRandomAlphanumeric;
36
+ exports.getRandomLetters = require_random.getRandomLetters;
37
+ exports.getRandomNumbers = require_random.getRandomNumbers;
38
+ exports.getSafeAreaInsets = require_device.getSafeAreaInsets;
39
+ exports.getViewportInfo = require_device.getViewportInfo;
40
+ exports.insertTextAtCursor = require_dom.insertTextAtCursor;
41
+ exports.isClickOutside = require_dom.isClickOutside;
42
+ exports.isElementInViewport = require_dom.isElementInViewport;
43
+ exports.isMobile = require_device.isMobile;
44
+ exports.isMobileUA = require_device.isMobileUA;
45
+ exports.isTouchDevice = require_device.isTouchDevice;
46
+ exports.onClickOutside = require_dom.onClickOutside;
47
+ exports.onViewportChange = require_device.onViewportChange;
48
+ exports.preventDefaultAndStopPropagation = require_dom.preventDefaultAndStopPropagation;
49
+ exports.refreshRandomLayout = require_random.refreshRandomLayout;
50
+ exports.registerFormatter = require_formatters.registerFormatter;
51
+ exports.scrollIntoViewIfNeeded = require_dom.scrollIntoViewIfNeeded;
52
+ exports.setInputCursorPosition = require_dom.setInputCursorPosition;
53
+ exports.setStyles = require_dom.setStyles;
54
+ exports.shuffleArray = require_random.shuffleArray;
55
+ exports.supportsVibrate = require_device.supportsVibrate;
56
+ exports.toggleClass = require_dom.toggleClass;
57
+ exports.vibrate = require_device.vibrate;
58
+ /*! End of @composy/keyboard-core | Powered by @composy/builder */
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 工具函数导出
3
+ * @module utils
4
+ */
5
+ export * from './event-emitter';
6
+ export * from './device';
7
+ export * from './dom';
8
+ export * from './random';
9
+ export * from './formatters';
10
+ //# sourceMappingURL=index.d.ts.map