@studiometa/js-toolkit 2.6.5 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/Base/features.cjs +29 -0
  2. package/Base/features.cjs.map +7 -0
  3. package/Base/features.d.ts +2 -0
  4. package/Base/features.js +7 -0
  5. package/Base/features.js.map +7 -0
  6. package/Base/index.cjs +12 -15
  7. package/Base/index.cjs.map +2 -2
  8. package/Base/index.d.ts +1 -5
  9. package/Base/index.js +10 -6
  10. package/Base/index.js.map +2 -2
  11. package/Base/managers/AsyncChildrenManager.cjs +61 -0
  12. package/Base/managers/AsyncChildrenManager.cjs.map +7 -0
  13. package/Base/managers/AsyncChildrenManager.d.ts +18 -0
  14. package/Base/managers/AsyncChildrenManager.js +39 -0
  15. package/Base/managers/AsyncChildrenManager.js.map +7 -0
  16. package/Base/managers/ChildrenManager.cjs +32 -29
  17. package/Base/managers/ChildrenManager.cjs.map +2 -2
  18. package/Base/managers/ChildrenManager.d.ts +21 -1
  19. package/Base/managers/ChildrenManager.js +32 -29
  20. package/Base/managers/ChildrenManager.js.map +2 -2
  21. package/Base/managers/EventsManager.cjs.map +2 -2
  22. package/Base/managers/EventsManager.js.map +2 -2
  23. package/Base/managers/RefsManager.cjs.map +2 -2
  24. package/Base/managers/RefsManager.js.map +2 -2
  25. package/Base/managers/index.cjs +41 -0
  26. package/Base/managers/index.cjs.map +7 -0
  27. package/Base/managers/index.d.ts +8 -0
  28. package/Base/managers/index.js +19 -0
  29. package/Base/managers/index.js.map +7 -0
  30. package/Base/types.cjs.map +1 -1
  31. package/Base/utils.cjs.map +2 -2
  32. package/Base/utils.d.ts +1 -0
  33. package/Base/utils.js.map +2 -2
  34. package/decorators/withBreakpointManager.cjs.map +2 -2
  35. package/decorators/withBreakpointManager.js.map +2 -2
  36. package/decorators/withBreakpointObserver.cjs.map +2 -2
  37. package/decorators/withBreakpointObserver.js.map +2 -2
  38. package/decorators/withDrag.cjs.map +2 -2
  39. package/decorators/withDrag.js.map +2 -2
  40. package/decorators/withMountWhenInView.cjs.map +2 -2
  41. package/decorators/withMountWhenInView.js.map +2 -2
  42. package/decorators/withResponsiveOptions.cjs.map +2 -2
  43. package/decorators/withResponsiveOptions.js.map +2 -2
  44. package/decorators/withScrolledInView.cjs +4 -1
  45. package/decorators/withScrolledInView.cjs.map +2 -2
  46. package/decorators/withScrolledInView.js +4 -1
  47. package/decorators/withScrolledInView.js.map +2 -2
  48. package/decorators/withVue2.cjs.map +2 -2
  49. package/decorators/withVue2.js.map +2 -2
  50. package/helpers/createApp.cjs +23 -19
  51. package/helpers/createApp.cjs.map +2 -2
  52. package/helpers/createApp.d.ts +6 -1
  53. package/helpers/createApp.js +23 -19
  54. package/helpers/createApp.js.map +2 -2
  55. package/helpers/getClosestParent.cjs.map +2 -2
  56. package/helpers/getClosestParent.js.map +2 -2
  57. package/helpers/getInstanceFromElement.cjs.map +2 -2
  58. package/helpers/getInstanceFromElement.js.map +2 -2
  59. package/helpers/importOnInteraction.cjs.map +2 -2
  60. package/helpers/importOnInteraction.js.map +2 -2
  61. package/helpers/importWhenIdle.cjs.map +2 -2
  62. package/helpers/importWhenIdle.js.map +2 -2
  63. package/index.cjs.map +1 -1
  64. package/index.d.ts +1 -1
  65. package/index.js.map +1 -1
  66. package/package.json +1 -1
  67. package/services/drag.cjs +1 -1
  68. package/services/drag.cjs.map +3 -3
  69. package/services/drag.d.ts +21 -24
  70. package/services/drag.js.map +3 -3
  71. package/services/key.cjs +1 -1
  72. package/services/key.cjs.map +3 -3
  73. package/services/key.d.ts +8 -9
  74. package/services/key.js.map +3 -3
  75. package/services/load.cjs +1 -1
  76. package/services/load.cjs.map +3 -3
  77. package/services/load.d.ts +6 -5
  78. package/services/load.js.map +3 -3
  79. package/services/pointer.cjs +1 -1
  80. package/services/pointer.cjs.map +3 -3
  81. package/services/pointer.d.ts +10 -10
  82. package/services/pointer.js.map +3 -3
  83. package/services/raf.cjs +4 -4
  84. package/services/raf.cjs.map +3 -3
  85. package/services/raf.d.ts +6 -7
  86. package/services/raf.js +3 -3
  87. package/services/raf.js.map +3 -3
  88. package/services/resize.cjs +1 -1
  89. package/services/resize.cjs.map +3 -3
  90. package/services/resize.d.ts +8 -9
  91. package/services/resize.js.map +3 -3
  92. package/services/scroll.cjs +1 -1
  93. package/services/scroll.cjs.map +3 -3
  94. package/services/scroll.d.ts +16 -17
  95. package/services/scroll.js.map +3 -3
  96. package/services/service.cjs +2 -2
  97. package/services/service.cjs.map +3 -3
  98. package/services/service.d.ts +12 -14
  99. package/services/service.js +1 -1
  100. package/services/service.js.map +3 -3
  101. package/utils/Queue.cjs +60 -0
  102. package/utils/Queue.cjs.map +7 -0
  103. package/utils/Queue.d.ts +44 -0
  104. package/utils/Queue.js +38 -0
  105. package/utils/Queue.js.map +7 -0
  106. package/utils/collide/boundingRectToCircle.cjs +3 -2
  107. package/utils/collide/boundingRectToCircle.cjs.map +3 -3
  108. package/utils/collide/boundingRectToCircle.d.ts +8 -13
  109. package/utils/collide/boundingRectToCircle.js +2 -1
  110. package/utils/collide/boundingRectToCircle.js.map +3 -3
  111. package/utils/collide/collideCircleCircle.cjs +1 -1
  112. package/utils/collide/collideCircleCircle.cjs.map +1 -1
  113. package/utils/collide/collideCircleCircle.d.ts +1 -15
  114. package/utils/collide/collideCircleCircle.js.map +1 -1
  115. package/utils/collide/collideCircleRect.cjs +1 -1
  116. package/utils/collide/collideCircleRect.cjs.map +1 -1
  117. package/utils/collide/collideCircleRect.d.ts +1 -33
  118. package/utils/collide/collideCircleRect.js.map +1 -1
  119. package/utils/collide/collidePointCircle.cjs +1 -1
  120. package/utils/collide/collidePointCircle.cjs.map +1 -1
  121. package/utils/collide/collidePointCircle.d.ts +1 -25
  122. package/utils/collide/collidePointCircle.js.map +1 -1
  123. package/utils/collide/collidePointRect.cjs +1 -1
  124. package/utils/collide/collidePointRect.cjs.map +1 -1
  125. package/utils/collide/collidePointRect.d.ts +1 -29
  126. package/utils/collide/collidePointRect.js.map +1 -1
  127. package/utils/collide/collideRectRect.cjs +1 -1
  128. package/utils/collide/collideRectRect.cjs.map +1 -1
  129. package/utils/collide/collideRectRect.d.ts +1 -19
  130. package/utils/collide/collideRectRect.js.map +1 -1
  131. package/utils/collide/index.cjs +1 -1
  132. package/utils/collide/index.cjs.map +1 -1
  133. package/utils/collide/index.d.ts +9 -6
  134. package/utils/collide/index.js.map +1 -1
  135. package/utils/css/animate.cjs +14 -15
  136. package/utils/css/animate.cjs.map +3 -3
  137. package/utils/css/animate.d.ts +12 -14
  138. package/utils/css/animate.js +13 -14
  139. package/utils/css/animate.js.map +3 -3
  140. package/utils/css/classes.cjs +1 -1
  141. package/utils/css/classes.cjs.map +3 -3
  142. package/utils/css/classes.d.ts +3 -16
  143. package/utils/css/classes.js.map +3 -3
  144. package/utils/css/getOffsetSizes.cjs +1 -1
  145. package/utils/css/getOffsetSizes.cjs.map +3 -3
  146. package/utils/css/getOffsetSizes.d.ts +0 -2
  147. package/utils/css/getOffsetSizes.js.map +3 -3
  148. package/utils/css/matrix.cjs +1 -1
  149. package/utils/css/matrix.cjs.map +3 -3
  150. package/utils/css/matrix.d.ts +10 -8
  151. package/utils/css/matrix.js.map +3 -3
  152. package/utils/css/styles.cjs +1 -1
  153. package/utils/css/styles.cjs.map +3 -3
  154. package/utils/css/styles.d.ts +2 -10
  155. package/utils/css/styles.js.map +3 -3
  156. package/utils/css/transform.cjs +1 -1
  157. package/utils/css/transform.cjs.map +3 -3
  158. package/utils/css/transform.d.ts +6 -28
  159. package/utils/css/transform.js.map +3 -3
  160. package/utils/css/transition.cjs +2 -2
  161. package/utils/css/transition.cjs.map +3 -3
  162. package/utils/css/transition.d.ts +11 -15
  163. package/utils/css/transition.js +1 -1
  164. package/utils/css/transition.js.map +3 -3
  165. package/utils/debounce.cjs +1 -1
  166. package/utils/debounce.cjs.map +3 -3
  167. package/utils/debounce.d.ts +3 -3
  168. package/utils/debounce.js.map +3 -3
  169. package/utils/focusTrap.cjs +4 -2
  170. package/utils/focusTrap.cjs.map +3 -3
  171. package/utils/focusTrap.d.ts +3 -4
  172. package/utils/focusTrap.js +3 -1
  173. package/utils/focusTrap.js.map +3 -3
  174. package/utils/has.cjs +1 -1
  175. package/utils/has.cjs.map +3 -3
  176. package/utils/has.d.ts +1 -3
  177. package/utils/has.js.map +3 -3
  178. package/utils/history.cjs +1 -1
  179. package/utils/history.cjs.map +3 -3
  180. package/utils/history.d.ts +10 -10
  181. package/utils/history.js.map +3 -3
  182. package/utils/index.cjs +2 -0
  183. package/utils/index.cjs.map +2 -2
  184. package/utils/index.d.ts +1 -0
  185. package/utils/index.js +2 -0
  186. package/utils/index.js.map +2 -2
  187. package/utils/is.cjs +1 -1
  188. package/utils/is.cjs.map +3 -3
  189. package/utils/is.d.ts +26 -8
  190. package/utils/is.js.map +3 -3
  191. package/utils/keyCodes.cjs +1 -1
  192. package/utils/keyCodes.cjs.map +2 -2
  193. package/utils/keyCodes.d.ts +10 -10
  194. package/utils/keyCodes.js.map +2 -2
  195. package/utils/math/clamp.cjs +1 -1
  196. package/utils/math/clamp.cjs.map +3 -3
  197. package/utils/math/clamp.js.map +3 -3
  198. package/utils/math/clamp01.cjs +1 -1
  199. package/utils/math/clamp01.cjs.map +3 -3
  200. package/utils/math/clamp01.js.map +3 -3
  201. package/utils/math/createEases.cjs +1 -1
  202. package/utils/math/createEases.cjs.map +3 -3
  203. package/utils/math/createEases.d.ts +3 -6
  204. package/utils/math/createEases.js.map +3 -3
  205. package/utils/math/damp.cjs +1 -1
  206. package/utils/math/damp.cjs.map +3 -3
  207. package/utils/math/damp.js.map +3 -3
  208. package/utils/math/ease.cjs +1 -1
  209. package/utils/math/ease.cjs.map +3 -3
  210. package/utils/math/ease.d.ts +21 -21
  211. package/utils/math/ease.js.map +3 -3
  212. package/utils/math/index.cjs +1 -1
  213. package/utils/math/index.cjs.map +1 -1
  214. package/utils/math/index.d.ts +10 -10
  215. package/utils/math/index.js.map +1 -1
  216. package/utils/math/inertiaFinalValue.cjs +1 -1
  217. package/utils/math/inertiaFinalValue.cjs.map +3 -3
  218. package/utils/math/inertiaFinalValue.js.map +3 -3
  219. package/utils/math/lerp.cjs +1 -1
  220. package/utils/math/lerp.cjs.map +3 -3
  221. package/utils/math/lerp.js.map +3 -3
  222. package/utils/math/map.cjs +1 -1
  223. package/utils/math/map.cjs.map +3 -3
  224. package/utils/math/map.js.map +3 -3
  225. package/utils/math/round.cjs +1 -1
  226. package/utils/math/round.cjs.map +3 -3
  227. package/utils/math/round.js.map +3 -3
  228. package/utils/memoize.cjs +6 -2
  229. package/utils/memoize.cjs.map +3 -3
  230. package/utils/memoize.d.ts +18 -28
  231. package/utils/memoize.js +5 -1
  232. package/utils/memoize.js.map +3 -3
  233. package/utils/nextFrame.cjs +1 -1
  234. package/utils/nextFrame.cjs.map +3 -3
  235. package/utils/nextFrame.d.ts +3 -6
  236. package/utils/nextFrame.js.map +3 -3
  237. package/utils/nextMicrotask.cjs +1 -1
  238. package/utils/nextMicrotask.cjs.map +3 -3
  239. package/utils/nextMicrotask.d.ts +1 -5
  240. package/utils/nextMicrotask.js.map +3 -3
  241. package/utils/nextTick.cjs +5 -5
  242. package/utils/nextTick.cjs.map +3 -3
  243. package/utils/nextTick.d.ts +1 -5
  244. package/utils/nextTick.js +4 -4
  245. package/utils/nextTick.js.map +3 -3
  246. package/utils/noop.cjs +1 -1
  247. package/utils/noop.cjs.map +3 -3
  248. package/utils/noop.d.ts +2 -5
  249. package/utils/noop.js.map +3 -3
  250. package/utils/object/autoBind.cjs +1 -1
  251. package/utils/object/autoBind.cjs.map +3 -3
  252. package/utils/object/autoBind.d.ts +5 -4
  253. package/utils/object/autoBind.js.map +3 -3
  254. package/utils/object/getAllProperties.cjs +3 -3
  255. package/utils/object/getAllProperties.cjs.map +3 -3
  256. package/utils/object/getAllProperties.d.ts +1 -1
  257. package/utils/object/getAllProperties.js +2 -2
  258. package/utils/object/getAllProperties.js.map +3 -3
  259. package/utils/object/index.cjs +1 -1
  260. package/utils/object/index.cjs.map +1 -1
  261. package/utils/object/index.d.ts +2 -2
  262. package/utils/object/index.js.map +1 -1
  263. package/utils/scheduler.cjs +2 -2
  264. package/utils/scheduler.cjs.map +3 -3
  265. package/utils/scheduler.d.ts +4 -13
  266. package/utils/scheduler.js +1 -1
  267. package/utils/scheduler.js.map +3 -3
  268. package/utils/scrollTo.cjs +1 -1
  269. package/utils/scrollTo.cjs.map +3 -3
  270. package/utils/scrollTo.d.ts +0 -3
  271. package/utils/scrollTo.js.map +3 -3
  272. package/utils/string/index.cjs +1 -1
  273. package/utils/string/index.cjs.map +1 -1
  274. package/utils/string/index.d.ts +10 -10
  275. package/utils/string/index.js.map +1 -1
  276. package/utils/string/withLeadingCharacters.cjs +1 -1
  277. package/utils/string/withLeadingCharacters.cjs.map +3 -3
  278. package/utils/string/withLeadingCharacters.js.map +3 -3
  279. package/utils/string/withLeadingSlash.cjs +1 -1
  280. package/utils/string/withLeadingSlash.cjs.map +3 -3
  281. package/utils/string/withLeadingSlash.js.map +3 -3
  282. package/utils/string/withTrailingCharacters.cjs +1 -1
  283. package/utils/string/withTrailingCharacters.cjs.map +3 -3
  284. package/utils/string/withTrailingCharacters.js.map +3 -3
  285. package/utils/string/withTrailingSlash.cjs +1 -1
  286. package/utils/string/withTrailingSlash.cjs.map +3 -3
  287. package/utils/string/withTrailingSlash.js.map +3 -3
  288. package/utils/string/withoutLeadingCharacters.cjs +1 -1
  289. package/utils/string/withoutLeadingCharacters.cjs.map +3 -3
  290. package/utils/string/withoutLeadingCharacters.js.map +3 -3
  291. package/utils/string/withoutLeadingCharactersRecursive.cjs +1 -1
  292. package/utils/string/withoutLeadingCharactersRecursive.cjs.map +3 -3
  293. package/utils/string/withoutLeadingCharactersRecursive.js.map +3 -3
  294. package/utils/string/withoutLeadingSlash.cjs +1 -1
  295. package/utils/string/withoutLeadingSlash.cjs.map +3 -3
  296. package/utils/string/withoutLeadingSlash.js.map +3 -3
  297. package/utils/string/withoutTrailingCharacters.cjs +1 -1
  298. package/utils/string/withoutTrailingCharacters.cjs.map +3 -3
  299. package/utils/string/withoutTrailingCharacters.js.map +3 -3
  300. package/utils/string/withoutTrailingCharactersRecursive.cjs +1 -1
  301. package/utils/string/withoutTrailingCharactersRecursive.cjs.map +3 -3
  302. package/utils/string/withoutTrailingCharactersRecursive.js.map +3 -3
  303. package/utils/string/withoutTrailingSlash.cjs +1 -1
  304. package/utils/string/withoutTrailingSlash.cjs.map +3 -3
  305. package/utils/string/withoutTrailingSlash.js.map +3 -3
  306. package/utils/throttle.cjs +2 -2
  307. package/utils/throttle.cjs.map +3 -3
  308. package/utils/throttle.d.ts +1 -1
  309. package/utils/throttle.js +1 -1
  310. package/utils/throttle.js.map +3 -3
  311. package/utils/tween.cjs +1 -1
  312. package/utils/tween.cjs.map +3 -3
  313. package/utils/tween.d.ts +16 -24
  314. package/utils/tween.js.map +3 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/createApp.ts"],
4
- "sourcesContent": ["import type { Base, BaseConstructor, BaseProps } from '../Base/index.js';\n\n/**\n * Instantiate and mount the given component on the given root element when the page has been loaded\n * and return a function to use the app instance when it is ready.\n */\nexport default function createApp<\n S extends BaseConstructor<Base>,\n T extends BaseProps = BaseProps,\n>(App: S, rootElement: HTMLElement = document.body): () => Promise<S & Base<T>> {\n let isLoaded = document.readyState === 'complete';\n let app: S & Base<T>;\n\n if (!isLoaded) {\n document.addEventListener('readystatechange', () => {\n if (document.readyState === 'complete') {\n app = (new App(rootElement) as S & Base<T>).$mount();\n isLoaded = true;\n }\n });\n } else {\n app = (new App(rootElement) as S & Base<T>).$mount();\n }\n\n const promise:Promise<S & Base<T>> = new Promise((resolve) => {\n document.addEventListener('readystatechange', () => {\n if (document.readyState === 'complete') {\n setTimeout(() => resolve(app), 0);\n }\n });\n });\n\n return function useApp() {\n if (isLoaded) {\n return Promise.resolve(app);\n }\n\n return promise;\n };\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMe,SAAR,UAGL,KAAQ,cAA2B,SAAS,MAAkC;AAC9E,MAAI,WAAW,SAAS,eAAe;AACvC,MAAI;AAEJ,MAAI,CAAC,UAAU;AACb,aAAS,iBAAiB,oBAAoB,MAAM;AAClD,UAAI,SAAS,eAAe,YAAY;AACtC,cAAO,IAAI,IAAI,WAAW,EAAkB,OAAO;AACnD,mBAAW;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AACL,UAAO,IAAI,IAAI,WAAW,EAAkB,OAAO;AAAA,EACrD;AAEA,QAAM,UAA+B,IAAI,QAAQ,CAAC,YAAY;AAC5D,aAAS,iBAAiB,oBAAoB,MAAM;AAClD,UAAI,SAAS,eAAe,YAAY;AACtC,mBAAW,MAAM,QAAQ,GAAG,GAAG,CAAC;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO,SAAS,SAAS;AACvB,QAAI,UAAU;AACZ,aAAO,QAAQ,QAAQ,GAAG;AAAA,IAC5B;AAEA,WAAO;AAAA,EACT;AACF;",
4
+ "sourcesContent": ["import type { Base, BaseConstructor, BaseProps } from '../Base/index.js';\nimport type { Features } from '../Base/features.js';\nimport { features } from '../Base/features.js';\nimport { isDefined } from '../utils/index.js';\n\nexport type CreateAppOptions = {\n root: HTMLElement;\n features: Features;\n};\n\n/**\n * Instantiate and mount the given component on the given root element when the page has been loaded\n * and return a function to use the app instance when it is ready.\n */\nexport default function createApp<S extends BaseConstructor<Base>, T extends BaseProps = BaseProps>(\n App: S,\n rootElement: HTMLElement | Partial<CreateAppOptions> = document.body,\n): () => Promise<S & Base<T>> {\n let app: S & Base<T>;\n const options =\n rootElement instanceof HTMLElement\n ? { root: rootElement, features: undefined }\n : { root: document.body, ...rootElement };\n\n if (isDefined(options.features)) {\n Object.entries(options.features).forEach(([feature, value]) => {\n features.set(feature as keyof Features, value);\n });\n }\n\n const p: Promise<S & Base<T>> = new Promise((resolve) => {\n const callback = () => {\n setTimeout(() => {\n app = (new App(options.root) as S & Base<T>).$mount();\n resolve(app);\n }, 0);\n };\n\n if (features.get('asyncChildren') || document.readyState === 'complete') {\n callback();\n } else {\n document.addEventListener('readystatechange', () => {\n if (document.readyState === 'complete') {\n callback();\n }\n });\n }\n });\n\n return function useApp() {\n return p;\n };\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAAyB;AACzB,mBAA0B;AAWX,SAAR,UACL,KACA,cAAuD,SAAS,MACpC;AAC5B,MAAI;AACJ,QAAM,UACJ,uBAAuB,cACnB,EAAE,MAAM,aAAa,UAAU,OAAU,IACzC,EAAE,MAAM,SAAS,MAAM,GAAG,YAAY;AAE5C,UAAI,wBAAU,QAAQ,QAAQ,GAAG;AAC/B,WAAO,QAAQ,QAAQ,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS,KAAK,MAAM;AAC7D,+BAAS,IAAI,SAA2B,KAAK;AAAA,IAC/C,CAAC;AAAA,EACH;AAEA,QAAM,IAA0B,IAAI,QAAQ,CAAC,YAAY;AACvD,UAAM,WAAW,MAAM;AACrB,iBAAW,MAAM;AACf,cAAO,IAAI,IAAI,QAAQ,IAAI,EAAkB,OAAO;AACpD,gBAAQ,GAAG;AAAA,MACb,GAAG,CAAC;AAAA,IACN;AAEA,QAAI,yBAAS,IAAI,eAAe,KAAK,SAAS,eAAe,YAAY;AACvE,eAAS;AAAA,IACX,OAAO;AACL,eAAS,iBAAiB,oBAAoB,MAAM;AAClD,YAAI,SAAS,eAAe,YAAY;AACtC,mBAAS;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,SAAS,SAAS;AACvB,WAAO;AAAA,EACT;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,11 @@
1
1
  import type { Base, BaseConstructor, BaseProps } from '../Base/index.js';
2
+ import type { Features } from '../Base/features.js';
3
+ export declare type CreateAppOptions = {
4
+ root: HTMLElement;
5
+ features: Features;
6
+ };
2
7
  /**
3
8
  * Instantiate and mount the given component on the given root element when the page has been loaded
4
9
  * and return a function to use the app instance when it is ready.
5
10
  */
6
- export default function createApp<S extends BaseConstructor<Base>, T extends BaseProps = BaseProps>(App: S, rootElement?: HTMLElement): () => Promise<S & Base<T>>;
11
+ export default function createApp<S extends BaseConstructor<Base>, T extends BaseProps = BaseProps>(App: S, rootElement?: HTMLElement | Partial<CreateAppOptions>): () => Promise<S & Base<T>>;
@@ -1,28 +1,32 @@
1
+ import { features } from "../Base/features.js";
2
+ import { isDefined } from "../utils/index.js";
1
3
  function createApp(App, rootElement = document.body) {
2
- let isLoaded = document.readyState === "complete";
3
4
  let app;
4
- if (!isLoaded) {
5
- document.addEventListener("readystatechange", () => {
6
- if (document.readyState === "complete") {
7
- app = new App(rootElement).$mount();
8
- isLoaded = true;
9
- }
5
+ const options = rootElement instanceof HTMLElement ? { root: rootElement, features: void 0 } : { root: document.body, ...rootElement };
6
+ if (isDefined(options.features)) {
7
+ Object.entries(options.features).forEach(([feature, value]) => {
8
+ features.set(feature, value);
10
9
  });
11
- } else {
12
- app = new App(rootElement).$mount();
13
10
  }
14
- const promise = new Promise((resolve) => {
15
- document.addEventListener("readystatechange", () => {
16
- if (document.readyState === "complete") {
17
- setTimeout(() => resolve(app), 0);
18
- }
19
- });
11
+ const p = new Promise((resolve) => {
12
+ const callback = () => {
13
+ setTimeout(() => {
14
+ app = new App(options.root).$mount();
15
+ resolve(app);
16
+ }, 0);
17
+ };
18
+ if (features.get("asyncChildren") || document.readyState === "complete") {
19
+ callback();
20
+ } else {
21
+ document.addEventListener("readystatechange", () => {
22
+ if (document.readyState === "complete") {
23
+ callback();
24
+ }
25
+ });
26
+ }
20
27
  });
21
28
  return function useApp() {
22
- if (isLoaded) {
23
- return Promise.resolve(app);
24
- }
25
- return promise;
29
+ return p;
26
30
  };
27
31
  }
28
32
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/createApp.ts"],
4
- "sourcesContent": ["import type { Base, BaseConstructor, BaseProps } from '../Base/index.js';\n\n/**\n * Instantiate and mount the given component on the given root element when the page has been loaded\n * and return a function to use the app instance when it is ready.\n */\nexport default function createApp<\n S extends BaseConstructor<Base>,\n T extends BaseProps = BaseProps,\n>(App: S, rootElement: HTMLElement = document.body): () => Promise<S & Base<T>> {\n let isLoaded = document.readyState === 'complete';\n let app: S & Base<T>;\n\n if (!isLoaded) {\n document.addEventListener('readystatechange', () => {\n if (document.readyState === 'complete') {\n app = (new App(rootElement) as S & Base<T>).$mount();\n isLoaded = true;\n }\n });\n } else {\n app = (new App(rootElement) as S & Base<T>).$mount();\n }\n\n const promise:Promise<S & Base<T>> = new Promise((resolve) => {\n document.addEventListener('readystatechange', () => {\n if (document.readyState === 'complete') {\n setTimeout(() => resolve(app), 0);\n }\n });\n });\n\n return function useApp() {\n if (isLoaded) {\n return Promise.resolve(app);\n }\n\n return promise;\n };\n}\n"],
5
- "mappings": "AAMe,SAAR,UAGL,KAAQ,cAA2B,SAAS,MAAkC;AAC9E,MAAI,WAAW,SAAS,eAAe;AACvC,MAAI;AAEJ,MAAI,CAAC,UAAU;AACb,aAAS,iBAAiB,oBAAoB,MAAM;AAClD,UAAI,SAAS,eAAe,YAAY;AACtC,cAAO,IAAI,IAAI,WAAW,EAAkB,OAAO;AACnD,mBAAW;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AACL,UAAO,IAAI,IAAI,WAAW,EAAkB,OAAO;AAAA,EACrD;AAEA,QAAM,UAA+B,IAAI,QAAQ,CAAC,YAAY;AAC5D,aAAS,iBAAiB,oBAAoB,MAAM;AAClD,UAAI,SAAS,eAAe,YAAY;AACtC,mBAAW,MAAM,QAAQ,GAAG,GAAG,CAAC;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO,SAAS,SAAS;AACvB,QAAI,UAAU;AACZ,aAAO,QAAQ,QAAQ,GAAG;AAAA,IAC5B;AAEA,WAAO;AAAA,EACT;AACF;",
4
+ "sourcesContent": ["import type { Base, BaseConstructor, BaseProps } from '../Base/index.js';\nimport type { Features } from '../Base/features.js';\nimport { features } from '../Base/features.js';\nimport { isDefined } from '../utils/index.js';\n\nexport type CreateAppOptions = {\n root: HTMLElement;\n features: Features;\n};\n\n/**\n * Instantiate and mount the given component on the given root element when the page has been loaded\n * and return a function to use the app instance when it is ready.\n */\nexport default function createApp<S extends BaseConstructor<Base>, T extends BaseProps = BaseProps>(\n App: S,\n rootElement: HTMLElement | Partial<CreateAppOptions> = document.body,\n): () => Promise<S & Base<T>> {\n let app: S & Base<T>;\n const options =\n rootElement instanceof HTMLElement\n ? { root: rootElement, features: undefined }\n : { root: document.body, ...rootElement };\n\n if (isDefined(options.features)) {\n Object.entries(options.features).forEach(([feature, value]) => {\n features.set(feature as keyof Features, value);\n });\n }\n\n const p: Promise<S & Base<T>> = new Promise((resolve) => {\n const callback = () => {\n setTimeout(() => {\n app = (new App(options.root) as S & Base<T>).$mount();\n resolve(app);\n }, 0);\n };\n\n if (features.get('asyncChildren') || document.readyState === 'complete') {\n callback();\n } else {\n document.addEventListener('readystatechange', () => {\n if (document.readyState === 'complete') {\n callback();\n }\n });\n }\n });\n\n return function useApp() {\n return p;\n };\n}\n"],
5
+ "mappings": "AAEA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAWX,SAAR,UACL,KACA,cAAuD,SAAS,MACpC;AAC5B,MAAI;AACJ,QAAM,UACJ,uBAAuB,cACnB,EAAE,MAAM,aAAa,UAAU,OAAU,IACzC,EAAE,MAAM,SAAS,MAAM,GAAG,YAAY;AAE5C,MAAI,UAAU,QAAQ,QAAQ,GAAG;AAC/B,WAAO,QAAQ,QAAQ,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS,KAAK,MAAM;AAC7D,eAAS,IAAI,SAA2B,KAAK;AAAA,IAC/C,CAAC;AAAA,EACH;AAEA,QAAM,IAA0B,IAAI,QAAQ,CAAC,YAAY;AACvD,UAAM,WAAW,MAAM;AACrB,iBAAW,MAAM;AACf,cAAO,IAAI,IAAI,QAAQ,IAAI,EAAkB,OAAO;AACpD,gBAAQ,GAAG;AAAA,MACb,GAAG,CAAC;AAAA,IACN;AAEA,QAAI,SAAS,IAAI,eAAe,KAAK,SAAS,eAAe,YAAY;AACvE,eAAS;AAAA,IACX,OAAO;AACL,eAAS,iBAAiB,oBAAoB,MAAM;AAClD,YAAI,SAAS,eAAe,YAAY;AACtC,mBAAS;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,SAAS,SAAS;AACvB,WAAO;AAAA,EACT;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/getClosestParent.ts"],
4
- "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport getInstanceFromElement from './getInstanceFromElement.js';\n\n/**\n * Walk through an element ancestors while the given condition is true with a\n * limit of 1000 iteration to avoid infinite loops.\n */\nfunction walkAncestorsWhile(\n element: HTMLElement,\n condition: (element: HTMLElement) => boolean,\n limit = 1000,\n): HTMLElement | null {\n let parent = element.parentElement;\n let count = 0;\n\n while (parent && condition(parent) && count < limit) {\n parent = parent.parentElement;\n count += 1;\n }\n\n return parent;\n}\n\n/**\n * Get the closest parent of a component.\n */\nexport default function getClosestParent<T extends BaseConstructor>(childInstance:Base, ParentConstructor:T) {\n const parentEl = walkAncestorsWhile(\n childInstance.$el,\n (element) => !getInstanceFromElement(element, ParentConstructor),\n );\n\n return parentEl ? getInstanceFromElement(parentEl, ParentConstructor) : null;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oCAAmC;AAMnC,SAAS,mBACP,SACA,WACA,QAAQ,KACY;AACpB,MAAI,SAAS,QAAQ;AACrB,MAAI,QAAQ;AAEZ,SAAO,UAAU,UAAU,MAAM,KAAK,QAAQ,OAAO;AACnD,aAAS,OAAO;AAChB,aAAS;AAAA,EACX;AAEA,SAAO;AACT;AAKe,SAAR,iBAA6D,eAAoB,mBAAqB;AAC3G,QAAM,WAAW;AAAA,IACf,cAAc;AAAA,IACd,CAAC,YAAY,KAAC,8BAAAA,SAAuB,SAAS,iBAAiB;AAAA,EACjE;AAEA,SAAO,eAAW,8BAAAA,SAAuB,UAAU,iBAAiB,IAAI;AAC1E;",
4
+ "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport getInstanceFromElement from './getInstanceFromElement.js';\n\n/**\n * Walk through an element ancestors while the given condition is true with a\n * limit of 1000 iteration to avoid infinite loops.\n */\nfunction walkAncestorsWhile(\n element: HTMLElement,\n condition: (element: HTMLElement) => boolean,\n limit = 1000,\n): HTMLElement | null {\n let parent = element.parentElement;\n let count = 0;\n\n while (parent && condition(parent) && count < limit) {\n parent = parent.parentElement;\n count += 1;\n }\n\n return parent;\n}\n\n/**\n * Get the closest parent of a component.\n */\nexport default function getClosestParent<T extends BaseConstructor>(\n childInstance: Base,\n ParentConstructor: T,\n) {\n const parentEl = walkAncestorsWhile(\n childInstance.$el,\n (element) => !getInstanceFromElement(element, ParentConstructor),\n );\n\n return parentEl ? getInstanceFromElement(parentEl, ParentConstructor) : null;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oCAAmC;AAMnC,SAAS,mBACP,SACA,WACA,QAAQ,KACY;AACpB,MAAI,SAAS,QAAQ;AACrB,MAAI,QAAQ;AAEZ,SAAO,UAAU,UAAU,MAAM,KAAK,QAAQ,OAAO;AACnD,aAAS,OAAO;AAChB,aAAS;AAAA,EACX;AAEA,SAAO;AACT;AAKe,SAAR,iBACL,eACA,mBACA;AACA,QAAM,WAAW;AAAA,IACf,cAAc;AAAA,IACd,CAAC,YAAY,KAAC,8BAAAA,SAAuB,SAAS,iBAAiB;AAAA,EACjE;AAEA,SAAO,eAAW,8BAAAA,SAAuB,UAAU,iBAAiB,IAAI;AAC1E;",
6
6
  "names": ["getInstanceFromElement"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/getClosestParent.ts"],
4
- "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport getInstanceFromElement from './getInstanceFromElement.js';\n\n/**\n * Walk through an element ancestors while the given condition is true with a\n * limit of 1000 iteration to avoid infinite loops.\n */\nfunction walkAncestorsWhile(\n element: HTMLElement,\n condition: (element: HTMLElement) => boolean,\n limit = 1000,\n): HTMLElement | null {\n let parent = element.parentElement;\n let count = 0;\n\n while (parent && condition(parent) && count < limit) {\n parent = parent.parentElement;\n count += 1;\n }\n\n return parent;\n}\n\n/**\n * Get the closest parent of a component.\n */\nexport default function getClosestParent<T extends BaseConstructor>(childInstance:Base, ParentConstructor:T) {\n const parentEl = walkAncestorsWhile(\n childInstance.$el,\n (element) => !getInstanceFromElement(element, ParentConstructor),\n );\n\n return parentEl ? getInstanceFromElement(parentEl, ParentConstructor) : null;\n}\n"],
5
- "mappings": "AACA,OAAO,4BAA4B;AAMnC,SAAS,mBACP,SACA,WACA,QAAQ,KACY;AACpB,MAAI,SAAS,QAAQ;AACrB,MAAI,QAAQ;AAEZ,SAAO,UAAU,UAAU,MAAM,KAAK,QAAQ,OAAO;AACnD,aAAS,OAAO;AAChB,aAAS;AAAA,EACX;AAEA,SAAO;AACT;AAKe,SAAR,iBAA6D,eAAoB,mBAAqB;AAC3G,QAAM,WAAW;AAAA,IACf,cAAc;AAAA,IACd,CAAC,YAAY,CAAC,uBAAuB,SAAS,iBAAiB;AAAA,EACjE;AAEA,SAAO,WAAW,uBAAuB,UAAU,iBAAiB,IAAI;AAC1E;",
4
+ "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport getInstanceFromElement from './getInstanceFromElement.js';\n\n/**\n * Walk through an element ancestors while the given condition is true with a\n * limit of 1000 iteration to avoid infinite loops.\n */\nfunction walkAncestorsWhile(\n element: HTMLElement,\n condition: (element: HTMLElement) => boolean,\n limit = 1000,\n): HTMLElement | null {\n let parent = element.parentElement;\n let count = 0;\n\n while (parent && condition(parent) && count < limit) {\n parent = parent.parentElement;\n count += 1;\n }\n\n return parent;\n}\n\n/**\n * Get the closest parent of a component.\n */\nexport default function getClosestParent<T extends BaseConstructor>(\n childInstance: Base,\n ParentConstructor: T,\n) {\n const parentEl = walkAncestorsWhile(\n childInstance.$el,\n (element) => !getInstanceFromElement(element, ParentConstructor),\n );\n\n return parentEl ? getInstanceFromElement(parentEl, ParentConstructor) : null;\n}\n"],
5
+ "mappings": "AACA,OAAO,4BAA4B;AAMnC,SAAS,mBACP,SACA,WACA,QAAQ,KACY;AACpB,MAAI,SAAS,QAAQ;AACrB,MAAI,QAAQ;AAEZ,SAAO,UAAU,UAAU,MAAM,KAAK,QAAQ,OAAO;AACnD,aAAS,OAAO;AAChB,aAAS;AAAA,EACX;AAEA,SAAO;AACT;AAKe,SAAR,iBACL,eACA,mBACA;AACA,QAAM,WAAW;AAAA,IACf,cAAc;AAAA,IACd,CAAC,YAAY,CAAC,uBAAuB,SAAS,iBAAiB;AAAA,EACjE;AAEA,SAAO,WAAW,uBAAuB,UAAU,iBAAiB,IAAI;AAC1E;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/getInstanceFromElement.ts"],
4
- "sourcesContent": ["import type { BaseConstructor, BaseEl } from '../Base/index.js';\n\n/**\n * Get a component instance from a DOM element.\n */\nexport default function getInstanceFromElement<T extends BaseConstructor>(\n element: BaseEl,\n Constructor: T,\n):InstanceType<T> | null {\n if (!element.__base__ || !element.__base__.has(Constructor)) {\n return null;\n }\n\n return element.__base__.get(Constructor) as InstanceType<T>;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKe,SAAR,uBACL,SACA,aACuB;AACvB,MAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,SAAS,IAAI,WAAW,GAAG;AAC3D,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,SAAS,IAAI,WAAW;AACzC;",
4
+ "sourcesContent": ["import type { BaseConstructor, BaseEl } from '../Base/index.js';\n\n/**\n * Get a component instance from a DOM element.\n */\nexport default function getInstanceFromElement<T extends BaseConstructor>(\n element: BaseEl,\n Constructor: T,\n): InstanceType<T> | null {\n if (!element.__base__ || !element.__base__.has(Constructor)) {\n return null;\n }\n\n return element.__base__.get(Constructor) as InstanceType<T>;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKe,SAAR,uBACL,SACA,aACwB;AACxB,MAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,SAAS,IAAI,WAAW,GAAG;AAC3D,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,SAAS,IAAI,WAAW;AACzC;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/getInstanceFromElement.ts"],
4
- "sourcesContent": ["import type { BaseConstructor, BaseEl } from '../Base/index.js';\n\n/**\n * Get a component instance from a DOM element.\n */\nexport default function getInstanceFromElement<T extends BaseConstructor>(\n element: BaseEl,\n Constructor: T,\n):InstanceType<T> | null {\n if (!element.__base__ || !element.__base__.has(Constructor)) {\n return null;\n }\n\n return element.__base__.get(Constructor) as InstanceType<T>;\n}\n"],
5
- "mappings": "AAKe,SAAR,uBACL,SACA,aACuB;AACvB,MAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,SAAS,IAAI,WAAW,GAAG;AAC3D,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,SAAS,IAAI,WAAW;AACzC;",
4
+ "sourcesContent": ["import type { BaseConstructor, BaseEl } from '../Base/index.js';\n\n/**\n * Get a component instance from a DOM element.\n */\nexport default function getInstanceFromElement<T extends BaseConstructor>(\n element: BaseEl,\n Constructor: T,\n): InstanceType<T> | null {\n if (!element.__base__ || !element.__base__.has(Constructor)) {\n return null;\n }\n\n return element.__base__.get(Constructor) as InstanceType<T>;\n}\n"],
5
+ "mappings": "AAKe,SAAR,uBACL,SACA,aACwB;AACxB,MAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,SAAS,IAAI,WAAW,GAAG;AAC3D,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,SAAS,IAAI,WAAW;AACzC;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/importOnInteraction.ts"],
4
- "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport { getTargetElements } from './utils.js';\nimport { isString } from '../utils/index.js';\n\n/**\n * Import a component on an interaction.\n *\n * @template {BaseConstructor} [T=BaseConstructor]\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {string|HTMLElement|HTMLElement[]} nameOrSelectorOrElement\n * The name or selector for the component.\n * @param {string|string[]} events\n * The events to listen to to trigger the import.\n * @param {Base} [parent]\n * The parent component.\n * @returns {Promise<InstanceType<T>>}\n */\nexport default function importOnInteraction<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default:T }>,\n nameOrSelectorOrElement:string | HTMLElement | HTMLElement[],\n events:string | string[],\n parent?: Base,\n):Promise<T> {\n const normalizedEvents = isString(events) ? [events] : events;\n\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n const elements = getTargetElements(nameOrSelectorOrElement, parent?.$el);\n const eventListenerOptions = {\n capture: true,\n passive: true,\n once: true,\n };\n const handler = () => {\n resolver(resolve);\n };\n\n elements.forEach((element) => {\n normalizedEvents.forEach((event) => {\n element.addEventListener(event, handler, eventListenerOptions);\n });\n });\n });\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAkC;AAClC,IAAAA,gBAAyB;AAgBV,SAAR,oBACL,IACA,yBACA,QACA,QACW;AACX,QAAM,uBAAmB,wBAAS,MAAM,IAAI,CAAC,MAAM,IAAI;AAEvD,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAACC,YAAW;AACpB,sBAAgB,aAAaA,UAASA,QAAO,UAAUA;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,eAAW,gCAAkB,yBAAyB,QAAQ,GAAG;AACvE,UAAM,uBAAuB;AAAA,MAC3B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AACA,UAAM,UAAU,MAAM;AACpB,eAAS,OAAO;AAAA,IAClB;AAEA,aAAS,QAAQ,CAAC,YAAY;AAC5B,uBAAiB,QAAQ,CAAC,UAAU;AAClC,gBAAQ,iBAAiB,OAAO,SAAS,oBAAoB;AAAA,MAC/D,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;",
4
+ "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport { getTargetElements } from './utils.js';\nimport { isString } from '../utils/index.js';\n\n/**\n * Import a component on an interaction.\n *\n * @template {BaseConstructor} [T=BaseConstructor]\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {string|HTMLElement|HTMLElement[]} nameOrSelectorOrElement\n * The name or selector for the component.\n * @param {string|string[]} events\n * The events to listen to to trigger the import.\n * @param {Base} [parent]\n * The parent component.\n * @returns {Promise<InstanceType<T>>}\n */\nexport default function importOnInteraction<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default: T }>,\n nameOrSelectorOrElement: string | HTMLElement | HTMLElement[],\n events: string | string[],\n parent?: Base,\n): Promise<T> {\n const normalizedEvents = isString(events) ? [events] : events;\n\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n const elements = getTargetElements(nameOrSelectorOrElement, parent?.$el);\n const eventListenerOptions = {\n capture: true,\n passive: true,\n once: true,\n };\n const handler = () => {\n resolver(resolve);\n };\n\n elements.forEach((element) => {\n normalizedEvents.forEach((event) => {\n element.addEventListener(event, handler, eventListenerOptions);\n });\n });\n });\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAkC;AAClC,IAAAA,gBAAyB;AAgBV,SAAR,oBACL,IACA,yBACA,QACA,QACY;AACZ,QAAM,uBAAmB,wBAAS,MAAM,IAAI,CAAC,MAAM,IAAI;AAEvD,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAACC,YAAW;AACpB,sBAAgB,aAAaA,UAASA,QAAO,UAAUA;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,eAAW,gCAAkB,yBAAyB,QAAQ,GAAG;AACvE,UAAM,uBAAuB;AAAA,MAC3B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AACA,UAAM,UAAU,MAAM;AACpB,eAAS,OAAO;AAAA,IAClB;AAEA,aAAS,QAAQ,CAAC,YAAY;AAC5B,uBAAiB,QAAQ,CAAC,UAAU;AAClC,gBAAQ,iBAAiB,OAAO,SAAS,oBAAoB;AAAA,MAC/D,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;",
6
6
  "names": ["import_utils", "module"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/importOnInteraction.ts"],
4
- "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport { getTargetElements } from './utils.js';\nimport { isString } from '../utils/index.js';\n\n/**\n * Import a component on an interaction.\n *\n * @template {BaseConstructor} [T=BaseConstructor]\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {string|HTMLElement|HTMLElement[]} nameOrSelectorOrElement\n * The name or selector for the component.\n * @param {string|string[]} events\n * The events to listen to to trigger the import.\n * @param {Base} [parent]\n * The parent component.\n * @returns {Promise<InstanceType<T>>}\n */\nexport default function importOnInteraction<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default:T }>,\n nameOrSelectorOrElement:string | HTMLElement | HTMLElement[],\n events:string | string[],\n parent?: Base,\n):Promise<T> {\n const normalizedEvents = isString(events) ? [events] : events;\n\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n const elements = getTargetElements(nameOrSelectorOrElement, parent?.$el);\n const eventListenerOptions = {\n capture: true,\n passive: true,\n once: true,\n };\n const handler = () => {\n resolver(resolve);\n };\n\n elements.forEach((element) => {\n normalizedEvents.forEach((event) => {\n element.addEventListener(event, handler, eventListenerOptions);\n });\n });\n });\n}\n"],
5
- "mappings": "AACA,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AAgBV,SAAR,oBACL,IACA,yBACA,QACA,QACW;AACX,QAAM,mBAAmB,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI;AAEvD,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAAC,WAAW;AACpB,sBAAgB,aAAa,SAAS,OAAO,UAAU;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,WAAW,kBAAkB,yBAAyB,QAAQ,GAAG;AACvE,UAAM,uBAAuB;AAAA,MAC3B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AACA,UAAM,UAAU,MAAM;AACpB,eAAS,OAAO;AAAA,IAClB;AAEA,aAAS,QAAQ,CAAC,YAAY;AAC5B,uBAAiB,QAAQ,CAAC,UAAU;AAClC,gBAAQ,iBAAiB,OAAO,SAAS,oBAAoB;AAAA,MAC/D,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;",
4
+ "sourcesContent": ["import type { Base, BaseConstructor } from '../Base/index.js';\nimport { getTargetElements } from './utils.js';\nimport { isString } from '../utils/index.js';\n\n/**\n * Import a component on an interaction.\n *\n * @template {BaseConstructor} [T=BaseConstructor]\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {string|HTMLElement|HTMLElement[]} nameOrSelectorOrElement\n * The name or selector for the component.\n * @param {string|string[]} events\n * The events to listen to to trigger the import.\n * @param {Base} [parent]\n * The parent component.\n * @returns {Promise<InstanceType<T>>}\n */\nexport default function importOnInteraction<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default: T }>,\n nameOrSelectorOrElement: string | HTMLElement | HTMLElement[],\n events: string | string[],\n parent?: Base,\n): Promise<T> {\n const normalizedEvents = isString(events) ? [events] : events;\n\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n const elements = getTargetElements(nameOrSelectorOrElement, parent?.$el);\n const eventListenerOptions = {\n capture: true,\n passive: true,\n once: true,\n };\n const handler = () => {\n resolver(resolve);\n };\n\n elements.forEach((element) => {\n normalizedEvents.forEach((event) => {\n element.addEventListener(event, handler, eventListenerOptions);\n });\n });\n });\n}\n"],
5
+ "mappings": "AACA,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AAgBV,SAAR,oBACL,IACA,yBACA,QACA,QACY;AACZ,QAAM,mBAAmB,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI;AAEvD,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAAC,WAAW;AACpB,sBAAgB,aAAa,SAAS,OAAO,UAAU;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,WAAW,kBAAkB,yBAAyB,QAAQ,GAAG;AACvE,UAAM,uBAAuB;AAAA,MAC3B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AACA,UAAM,UAAU,MAAM;AACpB,eAAS,OAAO;AAAA,IAClB;AAEA,aAAS,QAAQ,CAAC,YAAY;AAC5B,uBAAiB,QAAQ,CAAC,UAAU;AAClC,gBAAQ,iBAAiB,OAAO,SAAS,oBAAoB;AAAA,MAC/D,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/importWhenIdle.ts"],
4
- "sourcesContent": ["import type { BaseConstructor } from '../Base/index.js';\n\ntype ImportWhenIdleOptions = {\n timeout?: number;\n};\n\n/**\n * Import a component when user is idle.\n *\n * @template {BaseConstructor} T\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {ImportWhenIdleOptions} [options]\n * The time to wait before triggering the callback if never idle.\n * @returns {Promise<T>}\n */\nexport default function importWhenIdle<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default: T }>,\n { timeout = 1 }: ImportWhenIdleOptions = {},\n):Promise<T> {\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n if (!('requestIdleCallback' in window)) {\n setTimeout(() => {\n resolver(resolve);\n }, timeout);\n } else {\n window.requestIdleCallback(\n () => {\n setTimeout(() => {\n resolver(resolve);\n }, 0);\n },\n { timeout },\n );\n }\n });\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBe,SAAR,eACL,IACA,EAAE,UAAU,EAAE,IAA2B,CAAC,GAC/B;AACX,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAACA,YAAW;AACpB,sBAAgB,aAAaA,UAASA,QAAO,UAAUA;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,EAAE,yBAAyB,SAAS;AACtC,iBAAW,MAAM;AACf,iBAAS,OAAO;AAAA,MAClB,GAAG,OAAO;AAAA,IACZ,OAAO;AACL,aAAO;AAAA,QACL,MAAM;AACJ,qBAAW,MAAM;AACf,qBAAS,OAAO;AAAA,UAClB,GAAG,CAAC;AAAA,QACN;AAAA,QACA,EAAE,QAAQ;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AACH;",
4
+ "sourcesContent": ["import type { BaseConstructor } from '../Base/index.js';\n\ntype ImportWhenIdleOptions = {\n timeout?: number;\n};\n\n/**\n * Import a component when user is idle.\n *\n * @template {BaseConstructor} T\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {ImportWhenIdleOptions} [options]\n * The time to wait before triggering the callback if never idle.\n * @returns {Promise<T>}\n */\nexport default function importWhenIdle<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default: T }>,\n { timeout = 1 }: ImportWhenIdleOptions = {},\n): Promise<T> {\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n if (!('requestIdleCallback' in window)) {\n setTimeout(() => {\n resolver(resolve);\n }, timeout);\n } else {\n window.requestIdleCallback(\n () => {\n setTimeout(() => {\n resolver(resolve);\n }, 0);\n },\n { timeout },\n );\n }\n });\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBe,SAAR,eACL,IACA,EAAE,UAAU,EAAE,IAA2B,CAAC,GAC9B;AACZ,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAACA,YAAW;AACpB,sBAAgB,aAAaA,UAASA,QAAO,UAAUA;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,EAAE,yBAAyB,SAAS;AACtC,iBAAW,MAAM;AACf,iBAAS,OAAO;AAAA,MAClB,GAAG,OAAO;AAAA,IACZ,OAAO;AACL,aAAO;AAAA,QACL,MAAM;AACJ,qBAAW,MAAM;AACf,qBAAS,OAAO;AAAA,UAClB,GAAG,CAAC;AAAA,QACN;AAAA,QACA,EAAE,QAAQ;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AACH;",
6
6
  "names": ["module"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/helpers/importWhenIdle.ts"],
4
- "sourcesContent": ["import type { BaseConstructor } from '../Base/index.js';\n\ntype ImportWhenIdleOptions = {\n timeout?: number;\n};\n\n/**\n * Import a component when user is idle.\n *\n * @template {BaseConstructor} T\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {ImportWhenIdleOptions} [options]\n * The time to wait before triggering the callback if never idle.\n * @returns {Promise<T>}\n */\nexport default function importWhenIdle<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default: T }>,\n { timeout = 1 }: ImportWhenIdleOptions = {},\n):Promise<T> {\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n if (!('requestIdleCallback' in window)) {\n setTimeout(() => {\n resolver(resolve);\n }, timeout);\n } else {\n window.requestIdleCallback(\n () => {\n setTimeout(() => {\n resolver(resolve);\n }, 0);\n },\n { timeout },\n );\n }\n });\n}\n"],
5
- "mappings": "AAgBe,SAAR,eACL,IACA,EAAE,UAAU,EAAE,IAA2B,CAAC,GAC/B;AACX,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAAC,WAAW;AACpB,sBAAgB,aAAa,SAAS,OAAO,UAAU;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,EAAE,yBAAyB,SAAS;AACtC,iBAAW,MAAM;AACf,iBAAS,OAAO;AAAA,MAClB,GAAG,OAAO;AAAA,IACZ,OAAO;AACL,aAAO;AAAA,QACL,MAAM;AACJ,qBAAW,MAAM;AACf,qBAAS,OAAO;AAAA,UAClB,GAAG,CAAC;AAAA,QACN;AAAA,QACA,EAAE,QAAQ;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AACH;",
4
+ "sourcesContent": ["import type { BaseConstructor } from '../Base/index.js';\n\ntype ImportWhenIdleOptions = {\n timeout?: number;\n};\n\n/**\n * Import a component when user is idle.\n *\n * @template {BaseConstructor} T\n * @param {() => Promise<T|{default:T}>} fn\n * The import function.\n * @param {ImportWhenIdleOptions} [options]\n * The time to wait before triggering the callback if never idle.\n * @returns {Promise<T>}\n */\nexport default function importWhenIdle<T extends BaseConstructor = BaseConstructor>(\n fn: () => Promise<T | { default: T }>,\n { timeout = 1 }: ImportWhenIdleOptions = {},\n): Promise<T> {\n let ResolvedClass;\n\n const resolver = (resolve) => {\n fn().then((module) => {\n ResolvedClass = 'default' in module ? module.default : module;\n resolve(ResolvedClass);\n });\n };\n\n return new Promise((resolve) => {\n if (!('requestIdleCallback' in window)) {\n setTimeout(() => {\n resolver(resolve);\n }, timeout);\n } else {\n window.requestIdleCallback(\n () => {\n setTimeout(() => {\n resolver(resolve);\n }, 0);\n },\n { timeout },\n );\n }\n });\n}\n"],
5
+ "mappings": "AAgBe,SAAR,eACL,IACA,EAAE,UAAU,EAAE,IAA2B,CAAC,GAC9B;AACZ,MAAI;AAEJ,QAAM,WAAW,CAAC,YAAY;AAC5B,OAAG,EAAE,KAAK,CAAC,WAAW;AACpB,sBAAgB,aAAa,SAAS,OAAO,UAAU;AACvD,cAAQ,aAAa;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,EAAE,yBAAyB,SAAS;AACtC,iBAAW,MAAM;AACf,iBAAS,OAAO;AAAA,MAClB,GAAG,OAAO;AAAA,IACZ,OAAO;AACL,aAAO;AAAA,QACL,MAAM;AACJ,qBAAW,MAAM;AACf,qBAAS,OAAO;AAAA,UAClB,GAAG,CAAC;AAAA,QACN;AAAA,QACA,EAAE,QAAQ;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AACH;",
6
6
  "names": []
7
7
  }
package/index.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../packages/js-toolkit/index.ts"],
4
- "sourcesContent": ["export { Base } from './Base/index.js';\nexport * from './decorators/index.js';\nexport * from './helpers/index.js';\nexport * from './services/index.js';\n\nexport type {\n BaseProps,\n BaseConstructor,\n BaseAsyncConstructor,\n BaseConfig,\n} from './Base/index.js';\n\nexport type { BaseInterface, BaseDecorator } from './Base/types.js';\n"],
4
+ "sourcesContent": ["export { Base } from './Base/index.js';\nexport * from './decorators/index.js';\nexport * from './helpers/index.js';\nexport * from './services/index.js';\n\nexport type { BaseProps, BaseConstructor, BaseAsyncConstructor, BaseConfig } from './Base/index.js';\n\nexport type { BaseInterface, BaseDecorator } from './Base/types.js';\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAqB;AACrB,+BAAc,mCADd;AAEA,+BAAc,gCAFd;AAGA,+BAAc,iCAHd;",
6
6
  "names": []
7
7
  }
package/index.d.ts CHANGED
@@ -2,5 +2,5 @@ export { Base } from './Base/index.js';
2
2
  export * from './decorators/index.js';
3
3
  export * from './helpers/index.js';
4
4
  export * from './services/index.js';
5
- export type { BaseProps, BaseConstructor, BaseAsyncConstructor, BaseConfig, } from './Base/index.js';
5
+ export type { BaseProps, BaseConstructor, BaseAsyncConstructor, BaseConfig } from './Base/index.js';
6
6
  export type { BaseInterface, BaseDecorator } from './Base/types.js';
package/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../packages/js-toolkit/index.ts"],
4
- "sourcesContent": ["export { Base } from './Base/index.js';\nexport * from './decorators/index.js';\nexport * from './helpers/index.js';\nexport * from './services/index.js';\n\nexport type {\n BaseProps,\n BaseConstructor,\n BaseAsyncConstructor,\n BaseConfig,\n} from './Base/index.js';\n\nexport type { BaseInterface, BaseDecorator } from './Base/types.js';\n"],
4
+ "sourcesContent": ["export { Base } from './Base/index.js';\nexport * from './decorators/index.js';\nexport * from './helpers/index.js';\nexport * from './services/index.js';\n\nexport type { BaseProps, BaseConstructor, BaseAsyncConstructor, BaseConfig } from './Base/index.js';\n\nexport type { BaseInterface, BaseDecorator } from './Base/types.js';\n"],
5
5
  "mappings": "AAAA,SAAS,YAAY;AACrB,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/js-toolkit",
3
- "version": "2.6.5",
3
+ "version": "2.7.0",
4
4
  "description": "A set of useful little bits of JavaScript to boost your project! 🚀",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/services/drag.cjs CHANGED
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  ));
23
23
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
24
 
25
- // packages/js-toolkit/services/drag.js
25
+ // packages/js-toolkit/services/drag.ts
26
26
  var drag_exports = {};
27
27
  __export(drag_exports, {
28
28
  default: () => useDrag
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../packages/js-toolkit/services/drag.js"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\n// eslint-disable-next-line import/extensions\nimport { isDefined } from '../utils/index.js';\n\n/**\n * @typedef {import('./index').ServiceInterface<DragServiceProps>} DragService\n * @typedef {import('./pointer.js').PointerServiceProps} PointerServiceProps\n * @typedef {'start'|'drag'|'drop'|'inertia'|'stop'} DragLifecycle\n * @typedef {Object} DragServiceProps\n * @property {DragLifecycle} mode\n * The current mode of the dragging logic.\n * @property {HTMLElement} target\n * The target element of the drag.\n * @property {boolean} isGrabbing\n * Whether the user is currently grabbing the targeted element or not.\n * @property {boolean} hasInertia\n * Whether the drag currently has inertia or not.\n * @property {number} x\n * The current horizontal position in the viewport.\n * @property {number} y\n * The current vertical position in the viewport.\n * @property {{ x: number, y: number }} delta\n * The delta between the current position and the last.\n * @property {{ x: number, y: number }} origin\n * The initial position where the dragging started.\n * @property {{ x: number, y: number }} distance\n * The distance from the current position to the origin.\n * @property {{ x: number, y: number }} final\n * The final position that will be reached at the end of the inertia.\n * @typedef {Object} DragServiceOptions\n * @property {number} [dampFactor]\n * @property {number} [dragTreshold]\n */\n\n/**\n * @type {Record<Uppercase<DragLifecycle>, DragLifecycle>}\n */\nconst MODES = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup', 'touchend'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n * @param {MouseEvent|TouchEvent} event\n * @returns {{ x: number, y: number }}\n */\nfunction getEventPosition(event) {\n // @ts-ignore\n const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;\n return {\n x: eventOrTouch.clientX,\n y: eventOrTouch.clientY,\n };\n}\n\n/**\n * Get drag service.\n * @param {HTMLElement} target\n * @param {Object} options\n * @param {number} [options.dampFactor]\n * @param {number} [options.dragTreshold]\n * @returns {DragService}\n */\nfunction createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n *\n * @private\n * @returns {boolean}\n */\n function shouldPreventClick() {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x, y) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n * @returns {void}\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\n props.hasInertia = true;\n props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);\n props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);\n\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n * @returns {void}\n */\n function rafHandler() {\n if (!props.isGrabbing) {\n props.x += props.delta.x;\n props.y += props.delta.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n * @param {TouchEvent|MouseEvent} event\n * @returns {void}\n */\n function drag(event) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(previousEvent);\n props.delta.x = position.x - previousPosition.x;\n props.delta.y = position.y - previousPosition.y;\n }\n\n props.final.x = position.x;\n props.final.y = position.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n * @param {MouseEvent|PointerEvent|DragEvent} event\n */\n function handleEvent(event) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n /**\n * @type {DragServiceProps}\n */\n props: {\n target,\n mode: undefined,\n isGrabbing: false,\n hasInertia: false,\n x: 0,\n y: 0,\n delta: {\n x: 0,\n y: 0,\n },\n origin: {\n x: 0,\n y: 0,\n },\n distance: {\n x: 0,\n y: 0,\n },\n final: {\n x: 0,\n y: 0,\n },\n },\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\n/**\n * @type {WeakMap<HTMLElement, DragService | undefined>}\n */\nconst instances = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n *\n * @param {HTMLElement} target\n * @param {DragServiceOptions} options\n * @returns {DragService}\n */\nexport default function useDrag(target, options) {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA2B;AAC3B,iBAAmB;AACnB,+BAA8B;AAE9B,mBAA0B;AAmC1B,IAAM,QAAQ;AAAA,EACZ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AACR;AAEA,IAAI,QAAQ;AACZ,IAAM,SAAS,CAAC,eAAe,aAAa,UAAU;AACtD,IAAM,sBAAsB,EAAE,SAAS,KAAK;AAO5C,SAAS,iBAAiB,OAAO;AAE/B,QAAM,mBAAe,wBAAU,MAAM,OAAO,IAAI,MAAM,QAAQ,KAAK;AACnE,SAAO;AAAA,IACL,GAAG,aAAa;AAAA,IAChB,GAAG,aAAa;AAAA,EAClB;AACF;AAUA,SAAS,kBAAkB,QAAQ,EAAE,aAAa,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG;AAChF,WAAS;AACT,QAAM,KAAK,QAAQ;AACnB,MAAI;AAQJ,WAAS,qBAAqB;AAC5B,WAAO,KAAK,IAAI,MAAM,SAAS,CAAC,IAAI,gBAAgB,KAAK,IAAI,MAAM,SAAS,CAAC,IAAI;AAAA,EACnF;AAQA,WAAS,MAAM,GAAG,GAAG;AACnB,QAAI,MAAM,YAAY;AACpB;AAAA,IACF;AAGA,UAAM,IAAI;AACV,UAAM,IAAI;AACV,UAAM,OAAO,IAAI;AACjB,UAAM,OAAO,IAAI;AACjB,UAAM,MAAM,IAAI;AAChB,UAAM,MAAM,IAAI;AAChB,UAAM,SAAS,IAAI;AACnB,UAAM,SAAS,IAAI;AACnB,UAAM,MAAM,IAAI;AAChB,UAAM,MAAM,IAAI;AAEhB,UAAM,OAAO,MAAM;AAGnB,UAAM,aAAa;AAEnB,YAAQ,KAAK;AAEb,aAAS,iBAAiB,aAAa,aAAa,mBAAmB;AACvE,aAAS,iBAAiB,aAAa,aAAa,mBAAmB;AAAA,EACzE;AAMA,WAAS,OAAO;AACd,aAAS,oBAAoB,aAAa,WAAW;AACrD,aAAS,oBAAoB,aAAa,WAAW;AACrD,UAAM,aAAa;AACnB,UAAM,OAAO,MAAM;AAEnB,UAAM,aAAa;AACnB,UAAM,MAAM,QAAI,yBAAAA,SAAkB,MAAM,GAAG,MAAM,MAAM,GAAG,UAAU;AACpE,UAAM,MAAM,QAAI,yBAAAA,SAAkB,MAAM,GAAG,MAAM,MAAM,GAAG,UAAU;AAEpE,YAAQ,KAAK;AAEb,eAAW,MAAM;AACf,YAAM,UAAM,WAAAC,SAAO;AACnB,UAAI,OAAO,EAAE;AACb,UAAI,IAAI,IAAI,UAAU;AAAA,IACxB,GAAG,CAAC;AAAA,EACN;AAKA,WAAS,OAAO;AACd,mBAAAA,SAAO,EAAE,OAAO,EAAE;AAClB,UAAM,aAAa;AACnB,UAAM,aAAa;AACnB,UAAM,OAAO,MAAM;AACnB,YAAQ,KAAK;AAAA,EACf;AAMA,WAAS,aAAa;AACpB,QAAI,CAAC,MAAM,YAAY;AACrB,YAAM,KAAK,MAAM,MAAM;AACvB,YAAM,KAAK,MAAM,MAAM;AACvB,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAC1C,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAE1C,YAAM,MAAM,KAAK;AACjB,YAAM,MAAM,KAAK;AAEjB,UAAI,MAAM,SAAS,MAAM,SAAS;AAChC,cAAM,OAAO,MAAM;AAAA,MACrB;AAEA,cAAQ,KAAK;AAEb,UAAI,KAAK,IAAI,MAAM,MAAM,CAAC,IAAI,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC,IAAI,KAAK;AAClE,aAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAOA,WAAS,KAAK,OAAO;AACnB,QAAI,MAAM,YAAY;AACpB,YAAM,WAAW,iBAAiB,KAAK;AACvC,YAAM,IAAI,SAAS;AACnB,YAAM,IAAI,SAAS;AAEnB,UAAI,eAAe;AACjB,cAAM,mBAAmB,iBAAiB,aAAa;AACvD,cAAM,MAAM,IAAI,SAAS,IAAI,iBAAiB;AAC9C,cAAM,MAAM,IAAI,SAAS,IAAI,iBAAiB;AAAA,MAChD;AAEA,YAAM,MAAM,IAAI,SAAS;AACzB,YAAM,MAAM,IAAI,SAAS;AACzB,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAC1C,YAAM,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAE1C,UAAI,MAAM,SAAS,MAAM,MAAM;AAC7B,cAAM,OAAO,MAAM;AAAA,MACrB;AAEA,cAAQ,KAAK;AACb,sBAAgB;AAAA,IAClB;AAAA,EACF;AAMA,WAAS,YAAY,OAAO;AAC1B,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,cAAM,eAAe;AACrB;AAAA,MACF,KAAK;AACH,YAAI,mBAAmB,GAAG;AACxB,gBAAM,yBAAyB;AAC/B,gBAAM,gBAAgB;AACtB,gBAAM,eAAe;AAAA,QACvB;AACA;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,aAAK;AACL;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,aAAK,KAAK;AACV;AAAA,MACF;AACE,YAAI,MAAM,WAAW,GAAG;AACtB,gBAAM,MAAM,GAAG,MAAM,CAAC;AAAA,QACxB;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,MAAM,QAAI,2BAAW;AAAA,IAItD,OAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MACA,UAAU;AAAA,QACR,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,IACF;AAAA,IACA,OAAO;AACL,aAAO,QAAQ,CAAC,UAAU;AACxB,eAAO,iBAAiB,OAAO,aAAa,mBAAmB;AAAA,MACjE,CAAC;AACD,aAAO,iBAAiB,aAAa,aAAa,EAAE,SAAS,KAAK,CAAC;AACnE,aAAO,iBAAiB,SAAS,aAAa,EAAE,SAAS,KAAK,CAAC;AAAA,IACjE;AAAA,IACA,OAAO;AACL,aAAO,QAAQ,CAAC,UAAU;AACxB,eAAO,oBAAoB,OAAO,WAAW;AAAA,MAC/C,CAAC;AACD,aAAO,oBAAoB,aAAa,WAAW;AACnD,aAAO,oBAAoB,SAAS,WAAW;AAAA,IACjD;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAKA,IAAM,YAAY,oBAAI,QAAQ;AAkBf,SAAR,QAAyB,QAAQ,SAAS;AAC/C,MAAI,CAAC,UAAU,IAAI,MAAM,GAAG;AAC1B,cAAU,IAAI,QAAQ,kBAAkB,QAAQ,OAAO,CAAC;AAAA,EAC1D;AAEA,SAAO,UAAU,IAAI,MAAM;AAC7B;",
3
+ "sources": ["../../packages/js-toolkit/services/drag.ts"],
4
+ "sourcesContent": ["/* eslint-disable no-use-before-define, @typescript-eslint/no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\nimport { isDefined } from '../utils/index.js';\nimport type { ServiceInterface } from './index.js';\n\nexport type DragService = ServiceInterface<DragServiceProps>;\n\ntype DragLifecycle = 'start' | 'drag' | 'drop' | 'inertia' | 'stop';\n\nexport interface DragServiceProps {\n /**\n * The current mode of the dragging logic.\n */\n mode: DragLifecycle;\n /**\n * The target element of the drag.\n */\n target: HTMLElement;\n /**\n * Whether the user is currently grabbing the targeted element or not.\n */\n isGrabbing: boolean;\n /**\n * Whether the drag currently has inertia or not.\n */\n hasInertia: boolean;\n /**\n * The current horizontal position in the viewport.\n */\n x: number;\n /**\n * The current vertical position in the viewport.\n */\n y: number;\n /**\n * The delta between the current position and the last.\n */\n delta: { x: number; y: number };\n /**\n * The initial position where the dragging started.\n */\n origin: { x: number; y: number };\n /**\n * The distance from the current position to the origin.\n */\n distance: { x: number; y: number };\n /**\n * The final position that will be reached at the end of the inertia.\n */\n final: { x: number; y: number };\n}\n\nexport interface DragServiceOptions {\n dampFactor?: number;\n dragTreshold?: number;\n}\n\nconst MODES: Record<Uppercase<DragLifecycle>, DragLifecycle> = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup', 'touchend'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n */\nfunction getEventPosition(event: MouseEvent | TouchEvent): { x: number; y: number } {\n // @ts-ignore\n const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;\n return {\n x: eventOrTouch.clientX,\n y: eventOrTouch.clientY,\n };\n}\n\n/**\n * Get drag service.\n */\nfunction createDragService(\n target: HTMLElement,\n { dampFactor = 0.85, dragTreshold = 10 }: DragServiceOptions = {},\n): DragService {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n */\n function shouldPreventClick(): boolean {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x: number, y: number) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\n props.hasInertia = true;\n props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);\n props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);\n\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n */\n function rafHandler() {\n if (!props.isGrabbing) {\n props.x += props.delta.x;\n props.y += props.delta.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n */\n function drag(event: TouchEvent | MouseEvent) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(previousEvent);\n props.delta.x = position.x - previousPosition.x;\n props.delta.y = position.y - previousPosition.y;\n }\n\n props.final.x = position.x;\n props.final.y = position.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n */\n function handleEvent(event: MouseEvent | PointerEvent | DragEvent) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n props: {\n target,\n mode: undefined,\n isGrabbing: false,\n hasInertia: false,\n x: 0,\n y: 0,\n delta: {\n x: 0,\n y: 0,\n },\n origin: {\n x: 0,\n y: 0,\n },\n distance: {\n x: 0,\n y: 0,\n },\n final: {\n x: 0,\n y: 0,\n },\n } as DragServiceProps,\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\nconst instances: WeakMap<HTMLElement, DragService | undefined> = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n */\nexport default function useDrag(target: HTMLElement, options: DragServiceOptions): DragService {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["inertiaFinalValue", "useRaf"]
7
7
  }
@@ -1,24 +1,7 @@
1
- /**
2
- * Use the drag service.
3
- *
4
- * ```js
5
- * import { useDrag } from '@studiometa/js-toolkit/services';
6
- * const { add, remove, props } = useDrag();
7
- * const draggableElement = document.querySelector('.draggable');
8
- * add(draggableElement, (props) => {}, { factor: 0.8 });
9
- * remove(draggableElement);
10
- * props(draggableElement);
11
- * ```
12
- *
13
- * @param {HTMLElement} target
14
- * @param {DragServiceOptions} options
15
- * @returns {DragService}
16
- */
17
- export default function useDrag(target: HTMLElement, options: DragServiceOptions): import("./index").ServiceInterface<DragServiceProps>;
18
- export type DragService = import('./index').ServiceInterface<DragServiceProps>;
19
- export type PointerServiceProps = import('./pointer.js').PointerServiceProps;
20
- export type DragLifecycle = 'start' | 'drag' | 'drop' | 'inertia' | 'stop';
21
- export type DragServiceProps = {
1
+ import type { ServiceInterface } from './index.js';
2
+ export declare type DragService = ServiceInterface<DragServiceProps>;
3
+ declare type DragLifecycle = 'start' | 'drag' | 'drop' | 'inertia' | 'stop';
4
+ export interface DragServiceProps {
22
5
  /**
23
6
  * The current mode of the dragging logic.
24
7
  */
@@ -71,8 +54,22 @@ export type DragServiceProps = {
71
54
  x: number;
72
55
  y: number;
73
56
  };
74
- };
75
- export type DragServiceOptions = {
57
+ }
58
+ export interface DragServiceOptions {
76
59
  dampFactor?: number;
77
60
  dragTreshold?: number;
78
- };
61
+ }
62
+ /**
63
+ * Use the drag service.
64
+ *
65
+ * ```js
66
+ * import { useDrag } from '@studiometa/js-toolkit/services';
67
+ * const { add, remove, props } = useDrag();
68
+ * const draggableElement = document.querySelector('.draggable');
69
+ * add(draggableElement, (props) => {}, { factor: 0.8 });
70
+ * remove(draggableElement);
71
+ * props(draggableElement);
72
+ * ```
73
+ */
74
+ export default function useDrag(target: HTMLElement, options: DragServiceOptions): DragService;
75
+ export {};
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../packages/js-toolkit/services/drag.js"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\n// eslint-disable-next-line import/extensions\nimport { isDefined } from '../utils/index.js';\n\n/**\n * @typedef {import('./index').ServiceInterface<DragServiceProps>} DragService\n * @typedef {import('./pointer.js').PointerServiceProps} PointerServiceProps\n * @typedef {'start'|'drag'|'drop'|'inertia'|'stop'} DragLifecycle\n * @typedef {Object} DragServiceProps\n * @property {DragLifecycle} mode\n * The current mode of the dragging logic.\n * @property {HTMLElement} target\n * The target element of the drag.\n * @property {boolean} isGrabbing\n * Whether the user is currently grabbing the targeted element or not.\n * @property {boolean} hasInertia\n * Whether the drag currently has inertia or not.\n * @property {number} x\n * The current horizontal position in the viewport.\n * @property {number} y\n * The current vertical position in the viewport.\n * @property {{ x: number, y: number }} delta\n * The delta between the current position and the last.\n * @property {{ x: number, y: number }} origin\n * The initial position where the dragging started.\n * @property {{ x: number, y: number }} distance\n * The distance from the current position to the origin.\n * @property {{ x: number, y: number }} final\n * The final position that will be reached at the end of the inertia.\n * @typedef {Object} DragServiceOptions\n * @property {number} [dampFactor]\n * @property {number} [dragTreshold]\n */\n\n/**\n * @type {Record<Uppercase<DragLifecycle>, DragLifecycle>}\n */\nconst MODES = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup', 'touchend'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n * @param {MouseEvent|TouchEvent} event\n * @returns {{ x: number, y: number }}\n */\nfunction getEventPosition(event) {\n // @ts-ignore\n const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;\n return {\n x: eventOrTouch.clientX,\n y: eventOrTouch.clientY,\n };\n}\n\n/**\n * Get drag service.\n * @param {HTMLElement} target\n * @param {Object} options\n * @param {number} [options.dampFactor]\n * @param {number} [options.dragTreshold]\n * @returns {DragService}\n */\nfunction createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n *\n * @private\n * @returns {boolean}\n */\n function shouldPreventClick() {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x, y) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n * @returns {void}\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\n props.hasInertia = true;\n props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);\n props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);\n\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n * @returns {void}\n */\n function rafHandler() {\n if (!props.isGrabbing) {\n props.x += props.delta.x;\n props.y += props.delta.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n * @param {TouchEvent|MouseEvent} event\n * @returns {void}\n */\n function drag(event) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(previousEvent);\n props.delta.x = position.x - previousPosition.x;\n props.delta.y = position.y - previousPosition.y;\n }\n\n props.final.x = position.x;\n props.final.y = position.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n * @param {MouseEvent|PointerEvent|DragEvent} event\n */\n function handleEvent(event) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n /**\n * @type {DragServiceProps}\n */\n props: {\n target,\n mode: undefined,\n isGrabbing: false,\n hasInertia: false,\n x: 0,\n y: 0,\n delta: {\n x: 0,\n y: 0,\n },\n origin: {\n x: 0,\n y: 0,\n },\n distance: {\n x: 0,\n y: 0,\n },\n final: {\n x: 0,\n y: 0,\n },\n },\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\n/**\n * @type {WeakMap<HTMLElement, DragService | undefined>}\n */\nconst instances = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n *\n * @param {HTMLElement} target\n * @param {DragServiceOptions} options\n * @returns {DragService}\n */\nexport default function useDrag(target, options) {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../packages/js-toolkit/services/drag.ts"],
4
+ "sourcesContent": ["/* eslint-disable no-use-before-define, @typescript-eslint/no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\nimport { isDefined } from '../utils/index.js';\nimport type { ServiceInterface } from './index.js';\n\nexport type DragService = ServiceInterface<DragServiceProps>;\n\ntype DragLifecycle = 'start' | 'drag' | 'drop' | 'inertia' | 'stop';\n\nexport interface DragServiceProps {\n /**\n * The current mode of the dragging logic.\n */\n mode: DragLifecycle;\n /**\n * The target element of the drag.\n */\n target: HTMLElement;\n /**\n * Whether the user is currently grabbing the targeted element or not.\n */\n isGrabbing: boolean;\n /**\n * Whether the drag currently has inertia or not.\n */\n hasInertia: boolean;\n /**\n * The current horizontal position in the viewport.\n */\n x: number;\n /**\n * The current vertical position in the viewport.\n */\n y: number;\n /**\n * The delta between the current position and the last.\n */\n delta: { x: number; y: number };\n /**\n * The initial position where the dragging started.\n */\n origin: { x: number; y: number };\n /**\n * The distance from the current position to the origin.\n */\n distance: { x: number; y: number };\n /**\n * The final position that will be reached at the end of the inertia.\n */\n final: { x: number; y: number };\n}\n\nexport interface DragServiceOptions {\n dampFactor?: number;\n dragTreshold?: number;\n}\n\nconst MODES: Record<Uppercase<DragLifecycle>, DragLifecycle> = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup', 'touchend'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n */\nfunction getEventPosition(event: MouseEvent | TouchEvent): { x: number; y: number } {\n // @ts-ignore\n const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;\n return {\n x: eventOrTouch.clientX,\n y: eventOrTouch.clientY,\n };\n}\n\n/**\n * Get drag service.\n */\nfunction createDragService(\n target: HTMLElement,\n { dampFactor = 0.85, dragTreshold = 10 }: DragServiceOptions = {},\n): DragService {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n */\n function shouldPreventClick(): boolean {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x: number, y: number) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\n props.hasInertia = true;\n props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);\n props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);\n\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n */\n function rafHandler() {\n if (!props.isGrabbing) {\n props.x += props.delta.x;\n props.y += props.delta.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n */\n function drag(event: TouchEvent | MouseEvent) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(previousEvent);\n props.delta.x = position.x - previousPosition.x;\n props.delta.y = position.y - previousPosition.y;\n }\n\n props.final.x = position.x;\n props.final.y = position.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n */\n function handleEvent(event: MouseEvent | PointerEvent | DragEvent) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n props: {\n target,\n mode: undefined,\n isGrabbing: false,\n hasInertia: false,\n x: 0,\n y: 0,\n delta: {\n x: 0,\n y: 0,\n },\n origin: {\n x: 0,\n y: 0,\n },\n distance: {\n x: 0,\n y: 0,\n },\n final: {\n x: 0,\n y: 0,\n },\n } as DragServiceProps,\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\nconst instances: WeakMap<HTMLElement, DragService | undefined> = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n */\nexport default function useDrag(target: HTMLElement, options: DragServiceOptions): DragService {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/services/key.cjs CHANGED
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  ));
23
23
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
24
 
25
- // packages/js-toolkit/services/key.js
25
+ // packages/js-toolkit/services/key.ts
26
26
  var key_exports = {};
27
27
  __export(key_exports, {
28
28
  default: () => useKey
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../packages/js-toolkit/services/key.js"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define */\nimport { useService } from './service.js';\nimport keyCodes from '../utils/keyCodes.js';\n\n/**\n * @returns {Record<keyof keyCodes, false>}\n */\nfunction getInitialKeyCodes() {\n return /** @type {Record<keyof keyCodes, false>} */ (\n Object.fromEntries(Object.keys(keyCodes).map((key) => [key, false]))\n );\n}\n\n/**\n * @typedef {import('./index').ServiceInterface<KeyServiceProps>} KeyService\n * @typedef {Object} KeyServiceProps\n * @property {KeyboardEvent} event\n * @property {number} triggered\n * @property {'up'|'down'|'none'} direction\n * @property {boolean} isUp\n * @property {boolean} isDown\n * @property {boolean} ENTER\n * @property {boolean} SPACE\n * @property {boolean} TAB\n * @property {boolean} ESC\n * @property {boolean} LEFT\n * @property {boolean} UP\n * @property {boolean} RIGHT\n * @property {boolean} DOWN\n */\n\n/**\n * Create key service.\n * @returns {KeyService}\n */\nfunction createKeyService() {\n let previousEvent;\n\n /**\n * Update props\n * @param {KeyboardEvent} event\n * @returns {KeyServiceProps}\n */\n function updateProps(event) {\n props.event = event;\n\n Object.entries(keyCodes).forEach(([name, code]) => {\n props[name] = code === event.keyCode;\n });\n\n if (!previousEvent) {\n props.triggered = 0;\n }\n\n if (props.event.type === 'keydown' && previousEvent?.type === 'keydown') {\n props.triggered += 1;\n } else {\n props.triggered = 1;\n }\n\n previousEvent = props.event;\n\n props.direction = props.event.type === 'keydown' ? 'down' : 'up';\n props.isUp = props.event.type === 'keyup';\n props.isDown = props.event.type === 'keydown';\n\n return props;\n }\n\n /**\n * Desc.\n * @param {KeyboardEvent} event\n * @returns {void}\n */\n function onKey(event) {\n trigger(updateProps(event));\n }\n\n const { add, remove, has, trigger, props } = useService({\n /**\n * @type {KeyServiceProps}\n */\n props: {\n event: null,\n triggered: 0,\n isUp: false,\n isDown: false,\n direction: 'none',\n ...getInitialKeyCodes(),\n },\n init() {\n document.addEventListener('keydown', onKey);\n document.addEventListener('keyup', onKey);\n },\n kill() {\n document.removeEventListener('keydown', onKey);\n document.removeEventListener('keyup', onKey);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\nlet key;\n\n/**\n * Use the keyboard service.\n *\n * @returns {KeyService}\n */\nexport default function useKey() {\n if (!key) {\n key = createKeyService();\n }\n\n return key;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA2B;AAC3B,sBAAqB;AAKrB,SAAS,qBAAqB;AAC5B,SACE,OAAO,YAAY,OAAO,KAAK,gBAAAA,OAAQ,EAAE,IAAI,CAACC,SAAQ,CAACA,MAAK,KAAK,CAAC,CAAC;AAEvE;AAwBA,SAAS,mBAAmB;AAC1B,MAAI;AAOJ,WAAS,YAAY,OAAO;AAC1B,UAAM,QAAQ;AAEd,WAAO,QAAQ,gBAAAD,OAAQ,EAAE,QAAQ,CAAC,CAAC,MAAM,IAAI,MAAM;AACjD,YAAM,QAAQ,SAAS,MAAM;AAAA,IAC/B,CAAC;AAED,QAAI,CAAC,eAAe;AAClB,YAAM,YAAY;AAAA,IACpB;AAEA,QAAI,MAAM,MAAM,SAAS,aAAa,eAAe,SAAS,WAAW;AACvE,YAAM,aAAa;AAAA,IACrB,OAAO;AACL,YAAM,YAAY;AAAA,IACpB;AAEA,oBAAgB,MAAM;AAEtB,UAAM,YAAY,MAAM,MAAM,SAAS,YAAY,SAAS;AAC5D,UAAM,OAAO,MAAM,MAAM,SAAS;AAClC,UAAM,SAAS,MAAM,MAAM,SAAS;AAEpC,WAAO;AAAA,EACT;AAOA,WAAS,MAAM,OAAO;AACpB,YAAQ,YAAY,KAAK,CAAC;AAAA,EAC5B;AAEA,QAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,MAAM,QAAI,2BAAW;AAAA,IAItD,OAAO;AAAA,MACL,OAAO;AAAA,MACP,WAAW;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,GAAG,mBAAmB;AAAA,IACxB;AAAA,IACA,OAAO;AACL,eAAS,iBAAiB,WAAW,KAAK;AAC1C,eAAS,iBAAiB,SAAS,KAAK;AAAA,IAC1C;AAAA,IACA,OAAO;AACL,eAAS,oBAAoB,WAAW,KAAK;AAC7C,eAAS,oBAAoB,SAAS,KAAK;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,IAAI;AAOW,SAAR,SAA0B;AAC/B,MAAI,CAAC,KAAK;AACR,UAAM,iBAAiB;AAAA,EACzB;AAEA,SAAO;AACT;",
3
+ "sources": ["../../packages/js-toolkit/services/key.ts"],
4
+ "sourcesContent": ["/* eslint-disable no-use-before-define, @typescript-eslint/no-use-before-define */\nimport { useService } from './service.js';\nimport keyCodes from '../utils/keyCodes.js';\nimport type { ServiceInterface } from './index.js';\n\n/**\n * Get initial key codes.\n */\nfunction getInitialKeyCodes(): Record<keyof typeof keyCodes, false> {\n return Object.fromEntries(Object.keys(keyCodes).map((key) => [key, false])) as Record<\n keyof typeof keyCodes,\n false\n >;\n}\n\nexport type KeyService = ServiceInterface<KeyServiceProps>;\n\nexport interface KeyServiceProps {\n event: KeyboardEvent;\n triggered: number;\n direction: 'up' | 'down' | 'none';\n isUp: boolean;\n isDown: boolean;\n ENTER: boolean;\n SPACE: boolean;\n TAB: boolean;\n ESC: boolean;\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n}\n\n/**\n * Create key service.\n */\nfunction createKeyService(): KeyService {\n let previousEvent;\n\n /**\n * Update props.\n */\n function updateProps(event: KeyboardEvent): KeyServiceProps {\n props.event = event;\n\n Object.entries(keyCodes).forEach(([name, code]) => {\n props[name] = code === event.keyCode;\n });\n\n if (!previousEvent) {\n props.triggered = 0;\n }\n\n if (props.event.type === 'keydown' && previousEvent?.type === 'keydown') {\n props.triggered += 1;\n } else {\n props.triggered = 1;\n }\n\n previousEvent = props.event;\n\n props.direction = props.event.type === 'keydown' ? 'down' : 'up';\n props.isUp = props.event.type === 'keyup';\n props.isDown = props.event.type === 'keydown';\n\n return props;\n }\n\n /**\n * Trigger callbacks on keyboard event.\n */\n function onKey(event: KeyboardEvent) {\n trigger(updateProps(event));\n }\n\n const { add, remove, has, trigger, props } = useService({\n props: {\n event: null,\n triggered: 0,\n isUp: false,\n isDown: false,\n direction: 'none',\n ...getInitialKeyCodes(),\n } as KeyServiceProps,\n init() {\n document.addEventListener('keydown', onKey);\n document.addEventListener('keyup', onKey);\n },\n kill() {\n document.removeEventListener('keydown', onKey);\n document.removeEventListener('keyup', onKey);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\nlet key;\n\n/**\n * Use the keyboard service.\n */\nexport default function useKey(): KeyService {\n if (!key) {\n key = createKeyService();\n }\n\n return key;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA2B;AAC3B,sBAAqB;AAMrB,SAAS,qBAA2D;AAClE,SAAO,OAAO,YAAY,OAAO,KAAK,gBAAAA,OAAQ,EAAE,IAAI,CAACC,SAAQ,CAACA,MAAK,KAAK,CAAC,CAAC;AAI5E;AAuBA,SAAS,mBAA+B;AACtC,MAAI;AAKJ,WAAS,YAAY,OAAuC;AAC1D,UAAM,QAAQ;AAEd,WAAO,QAAQ,gBAAAD,OAAQ,EAAE,QAAQ,CAAC,CAAC,MAAM,IAAI,MAAM;AACjD,YAAM,QAAQ,SAAS,MAAM;AAAA,IAC/B,CAAC;AAED,QAAI,CAAC,eAAe;AAClB,YAAM,YAAY;AAAA,IACpB;AAEA,QAAI,MAAM,MAAM,SAAS,aAAa,eAAe,SAAS,WAAW;AACvE,YAAM,aAAa;AAAA,IACrB,OAAO;AACL,YAAM,YAAY;AAAA,IACpB;AAEA,oBAAgB,MAAM;AAEtB,UAAM,YAAY,MAAM,MAAM,SAAS,YAAY,SAAS;AAC5D,UAAM,OAAO,MAAM,MAAM,SAAS;AAClC,UAAM,SAAS,MAAM,MAAM,SAAS;AAEpC,WAAO;AAAA,EACT;AAKA,WAAS,MAAM,OAAsB;AACnC,YAAQ,YAAY,KAAK,CAAC;AAAA,EAC5B;AAEA,QAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,MAAM,QAAI,2BAAW;AAAA,IACtD,OAAO;AAAA,MACL,OAAO;AAAA,MACP,WAAW;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,GAAG,mBAAmB;AAAA,IACxB;AAAA,IACA,OAAO;AACL,eAAS,iBAAiB,WAAW,KAAK;AAC1C,eAAS,iBAAiB,SAAS,KAAK;AAAA,IAC1C;AAAA,IACA,OAAO;AACL,eAAS,oBAAoB,WAAW,KAAK;AAC7C,eAAS,oBAAoB,SAAS,KAAK;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,IAAI;AAKW,SAAR,SAAsC;AAC3C,MAAI,CAAC,KAAK;AACR,UAAM,iBAAiB;AAAA,EACzB;AAEA,SAAO;AACT;",
6
6
  "names": ["keyCodes", "key"]
7
7
  }
package/services/key.d.ts CHANGED
@@ -1,11 +1,6 @@
1
- /**
2
- * Use the keyboard service.
3
- *
4
- * @returns {KeyService}
5
- */
6
- export default function useKey(): import("./index").ServiceInterface<KeyServiceProps>;
7
- export type KeyService = import('./index').ServiceInterface<KeyServiceProps>;
8
- export type KeyServiceProps = {
1
+ import type { ServiceInterface } from './index.js';
2
+ export declare type KeyService = ServiceInterface<KeyServiceProps>;
3
+ export interface KeyServiceProps {
9
4
  event: KeyboardEvent;
10
5
  triggered: number;
11
6
  direction: 'up' | 'down' | 'none';
@@ -19,4 +14,8 @@ export type KeyServiceProps = {
19
14
  UP: boolean;
20
15
  RIGHT: boolean;
21
16
  DOWN: boolean;
22
- };
17
+ }
18
+ /**
19
+ * Use the keyboard service.
20
+ */
21
+ export default function useKey(): KeyService;