@witchcraft/layout 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/README.md +474 -0
  2. package/dist/module.d.mts +14 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +26 -0
  5. package/dist/runtime/components/LayoutDecos.d.vue.ts +0 -0
  6. package/dist/runtime/components/LayoutDecos.vue +54 -0
  7. package/dist/runtime/components/LayoutDecos.vue.d.ts +0 -0
  8. package/dist/runtime/components/LayoutEdges.d.vue.ts +0 -0
  9. package/dist/runtime/components/LayoutEdges.vue +145 -0
  10. package/dist/runtime/components/LayoutEdges.vue.d.ts +0 -0
  11. package/dist/runtime/components/LayoutFrame.d.vue.ts +0 -0
  12. package/dist/runtime/components/LayoutFrame.vue +41 -0
  13. package/dist/runtime/components/LayoutFrame.vue.d.ts +0 -0
  14. package/dist/runtime/components/LayoutShapeSquare.d.vue.ts +0 -0
  15. package/dist/runtime/components/LayoutShapeSquare.vue +36 -0
  16. package/dist/runtime/components/LayoutShapeSquare.vue.d.ts +0 -0
  17. package/dist/runtime/components/LayoutWindow.d.vue.ts +0 -0
  18. package/dist/runtime/components/LayoutWindow.vue +183 -0
  19. package/dist/runtime/components/LayoutWindow.vue.d.ts +0 -0
  20. package/dist/runtime/composables/useFrames.d.ts +0 -0
  21. package/dist/runtime/composables/useFrames.js +184 -0
  22. package/dist/runtime/demo/App.d.vue.ts +0 -0
  23. package/dist/runtime/demo/App.vue +121 -0
  24. package/dist/runtime/demo/App.vue.d.ts +0 -0
  25. package/dist/runtime/demo/DemoControls.d.vue.ts +0 -0
  26. package/dist/runtime/demo/DemoControls.vue +14 -0
  27. package/dist/runtime/demo/DemoControls.vue.d.ts +0 -0
  28. package/dist/runtime/demo/README.md +1 -0
  29. package/dist/runtime/demo/main.d.ts +0 -0
  30. package/dist/runtime/demo/main.js +4 -0
  31. package/dist/runtime/demo/sharedLayoutInstance.d.ts +0 -0
  32. package/dist/runtime/demo/sharedLayoutInstance.js +5 -0
  33. package/dist/runtime/demo/tailwind.css +1 -0
  34. package/dist/runtime/drag/CloseAction.d.ts +0 -0
  35. package/dist/runtime/drag/CloseAction.js +121 -0
  36. package/dist/runtime/drag/DragActionHandler.d.ts +0 -0
  37. package/dist/runtime/drag/DragActionHandler.js +83 -0
  38. package/dist/runtime/drag/DragDirectionStore.d.ts +0 -0
  39. package/dist/runtime/drag/DragDirectionStore.js +45 -0
  40. package/dist/runtime/drag/SplitAction.d.ts +0 -0
  41. package/dist/runtime/drag/SplitAction.js +110 -0
  42. package/dist/runtime/drag/types.d.ts +0 -0
  43. package/dist/runtime/drag/types.js +0 -0
  44. package/dist/runtime/helpers/addPointsToIntersection.d.ts +0 -0
  45. package/dist/runtime/helpers/addPointsToIntersection.js +7 -0
  46. package/dist/runtime/helpers/assertEdgeSorted.d.ts +0 -0
  47. package/dist/runtime/helpers/assertEdgeSorted.js +7 -0
  48. package/dist/runtime/helpers/assertItemIn.d.ts +0 -0
  49. package/dist/runtime/helpers/assertItemIn.js +8 -0
  50. package/dist/runtime/helpers/assertItemNotIn.d.ts +0 -0
  51. package/dist/runtime/helpers/assertItemNotIn.js +7 -0
  52. package/dist/runtime/helpers/assertLayoutHasActiveWindow.d.ts +0 -0
  53. package/dist/runtime/helpers/assertLayoutHasActiveWindow.js +7 -0
  54. package/dist/runtime/helpers/assertValidWinAndFrame.d.ts +0 -0
  55. package/dist/runtime/helpers/assertValidWinAndFrame.js +5 -0
  56. package/dist/runtime/helpers/assertValidWinAndFrameIds.d.ts +0 -0
  57. package/dist/runtime/helpers/assertValidWinAndFrameIds.js +6 -0
  58. package/dist/runtime/helpers/assertWindowHasActiveFrame.d.ts +0 -0
  59. package/dist/runtime/helpers/assertWindowHasActiveFrame.js +7 -0
  60. package/dist/runtime/helpers/clampNumber.d.ts +0 -0
  61. package/dist/runtime/helpers/clampNumber.js +3 -0
  62. package/dist/runtime/helpers/cloneFrame.d.ts +0 -0
  63. package/dist/runtime/helpers/cloneFrame.js +3 -0
  64. package/dist/runtime/helpers/cloneFrames.d.ts +0 -0
  65. package/dist/runtime/helpers/cloneFrames.js +16 -0
  66. package/dist/runtime/helpers/containsEdge.d.ts +0 -0
  67. package/dist/runtime/helpers/containsEdge.js +13 -0
  68. package/dist/runtime/helpers/convertLayoutWindowToWorkspace.d.ts +0 -0
  69. package/dist/runtime/helpers/convertLayoutWindowToWorkspace.js +10 -0
  70. package/dist/runtime/helpers/copySize.d.ts +0 -0
  71. package/dist/runtime/helpers/copySize.js +5 -0
  72. package/dist/runtime/helpers/createEdge.d.ts +0 -0
  73. package/dist/runtime/helpers/createEdge.js +13 -0
  74. package/dist/runtime/helpers/dirToOrientation.d.ts +0 -0
  75. package/dist/runtime/helpers/dirToOrientation.js +10 -0
  76. package/dist/runtime/helpers/dirToSide.d.ts +0 -0
  77. package/dist/runtime/helpers/dirToSide.js +5 -0
  78. package/dist/runtime/helpers/doEdgesOverlap.d.ts +0 -0
  79. package/dist/runtime/helpers/doEdgesOverlap.js +22 -0
  80. package/dist/runtime/helpers/doesEdgeContinueEdge.d.ts +0 -0
  81. package/dist/runtime/helpers/doesEdgeContinueEdge.js +17 -0
  82. package/dist/runtime/helpers/edgeToPoints.d.ts +0 -0
  83. package/dist/runtime/helpers/edgeToPoints.js +3 -0
  84. package/dist/runtime/helpers/findDraggableEdge.d.ts +0 -0
  85. package/dist/runtime/helpers/findDraggableEdge.js +13 -0
  86. package/dist/runtime/helpers/findFrameDraggableEdges.d.ts +0 -0
  87. package/dist/runtime/helpers/findFrameDraggableEdges.js +18 -0
  88. package/dist/runtime/helpers/frameToEdges.d.ts +0 -0
  89. package/dist/runtime/helpers/frameToEdges.js +21 -0
  90. package/dist/runtime/helpers/frameToPoints.d.ts +0 -0
  91. package/dist/runtime/helpers/frameToPoints.js +7 -0
  92. package/dist/runtime/helpers/getEdgeOrientation.d.ts +0 -0
  93. package/dist/runtime/helpers/getEdgeOrientation.js +4 -0
  94. package/dist/runtime/helpers/getEdgeSharedDirection.d.ts +0 -0
  95. package/dist/runtime/helpers/getEdgeSharedDirection.js +7 -0
  96. package/dist/runtime/helpers/getEdgeSide.d.ts +0 -0
  97. package/dist/runtime/helpers/getEdgeSide.js +16 -0
  98. package/dist/runtime/helpers/getFrameById.d.ts +0 -0
  99. package/dist/runtime/helpers/getFrameById.js +5 -0
  100. package/dist/runtime/helpers/getFrameConstant.d.ts +0 -0
  101. package/dist/runtime/helpers/getFrameConstant.js +15 -0
  102. package/dist/runtime/helpers/getIntersections.d.ts +0 -0
  103. package/dist/runtime/helpers/getIntersections.js +63 -0
  104. package/dist/runtime/helpers/getIntersectionsCss.d.ts +0 -0
  105. package/dist/runtime/helpers/getIntersectionsCss.js +56 -0
  106. package/dist/runtime/helpers/getMoveEdgeInfo.d.ts +0 -0
  107. package/dist/runtime/helpers/getMoveEdgeInfo.js +42 -0
  108. package/dist/runtime/helpers/getResizeLimit.d.ts +0 -0
  109. package/dist/runtime/helpers/getResizeLimit.js +39 -0
  110. package/dist/runtime/helpers/getShapeSquareCss.d.ts +0 -0
  111. package/dist/runtime/helpers/getShapeSquareCss.js +17 -0
  112. package/dist/runtime/helpers/getSideTouching.d.ts +0 -0
  113. package/dist/runtime/helpers/getSideTouching.js +7 -0
  114. package/dist/runtime/helpers/getVisualEdgeCss.d.ts +0 -0
  115. package/dist/runtime/helpers/getVisualEdgeCss.js +40 -0
  116. package/dist/runtime/helpers/getVisualEdges.d.ts +0 -0
  117. package/dist/runtime/helpers/getVisualEdges.js +89 -0
  118. package/dist/runtime/helpers/getVisualEdgesCss.d.ts +0 -0
  119. package/dist/runtime/helpers/getVisualEdgesCss.js +4 -0
  120. package/dist/runtime/helpers/getWinAndFrameById.d.ts +0 -0
  121. package/dist/runtime/helpers/getWinAndFrameById.js +14 -0
  122. package/dist/runtime/helpers/getWinByFrameUuid.d.ts +0 -0
  123. package/dist/runtime/helpers/getWinByFrameUuid.js +13 -0
  124. package/dist/runtime/helpers/getWinById.d.ts +0 -0
  125. package/dist/runtime/helpers/getWinById.js +5 -0
  126. package/dist/runtime/helpers/getWindowConstant.d.ts +0 -0
  127. package/dist/runtime/helpers/getWindowConstant.js +14 -0
  128. package/dist/runtime/helpers/inRange.d.ts +0 -0
  129. package/dist/runtime/helpers/inRange.js +3 -0
  130. package/dist/runtime/helpers/index.d.ts +0 -0
  131. package/dist/runtime/helpers/index.js +62 -0
  132. package/dist/runtime/helpers/isEdgeEqual.d.ts +0 -0
  133. package/dist/runtime/helpers/isEdgeEqual.js +11 -0
  134. package/dist/runtime/helpers/isEdgeParallel.d.ts +0 -0
  135. package/dist/runtime/helpers/isEdgeParallel.js +7 -0
  136. package/dist/runtime/helpers/isPointEqual.d.ts +0 -0
  137. package/dist/runtime/helpers/isPointEqual.js +3 -0
  138. package/dist/runtime/helpers/isSizeAboveMin.d.ts +0 -0
  139. package/dist/runtime/helpers/isSizeAboveMin.js +3 -0
  140. package/dist/runtime/helpers/isSizeEqual.d.ts +0 -0
  141. package/dist/runtime/helpers/isSizeEqual.js +3 -0
  142. package/dist/runtime/helpers/isWindowEdge.d.ts +0 -0
  143. package/dist/runtime/helpers/isWindowEdge.js +7 -0
  144. package/dist/runtime/helpers/isWindowEdgePoint.d.ts +0 -0
  145. package/dist/runtime/helpers/isWindowEdgePoint.js +5 -0
  146. package/dist/runtime/helpers/moveEdge.d.ts +0 -0
  147. package/dist/runtime/helpers/moveEdge.js +8 -0
  148. package/dist/runtime/helpers/numberToScaledPercent.d.ts +0 -0
  149. package/dist/runtime/helpers/numberToScaledPercent.js +5 -0
  150. package/dist/runtime/helpers/numberToScaledSize.d.ts +0 -0
  151. package/dist/runtime/helpers/numberToScaledSize.js +19 -0
  152. package/dist/runtime/helpers/oppositeSide.d.ts +0 -0
  153. package/dist/runtime/helpers/oppositeSide.js +30 -0
  154. package/dist/runtime/helpers/resizeByEdge.d.ts +0 -0
  155. package/dist/runtime/helpers/resizeByEdge.js +29 -0
  156. package/dist/runtime/helpers/sideToDirection.d.ts +0 -0
  157. package/dist/runtime/helpers/sideToDirection.js +11 -0
  158. package/dist/runtime/helpers/sideToOrientation.d.ts +0 -0
  159. package/dist/runtime/helpers/sideToOrientation.js +10 -0
  160. package/dist/runtime/helpers/splitEdge.d.ts +0 -0
  161. package/dist/runtime/helpers/splitEdge.js +20 -0
  162. package/dist/runtime/helpers/toCoord.d.ts +0 -0
  163. package/dist/runtime/helpers/toCoord.js +10 -0
  164. package/dist/runtime/helpers/toId.d.ts +0 -0
  165. package/dist/runtime/helpers/toId.js +4 -0
  166. package/dist/runtime/helpers/toWindowCoord.d.ts +0 -0
  167. package/dist/runtime/helpers/toWindowCoord.js +14 -0
  168. package/dist/runtime/helpers/unionEdges.d.ts +0 -0
  169. package/dist/runtime/helpers/unionEdges.js +8 -0
  170. package/dist/runtime/helpers/updateWindowSizeWithEvent.d.ts +0 -0
  171. package/dist/runtime/helpers/updateWindowSizeWithEvent.js +8 -0
  172. package/dist/runtime/index.d.ts +0 -0
  173. package/dist/runtime/index.js +5 -0
  174. package/dist/runtime/layout/closeFrame.d.ts +0 -0
  175. package/dist/runtime/layout/closeFrame.js +13 -0
  176. package/dist/runtime/layout/closeFrames.d.ts +0 -0
  177. package/dist/runtime/layout/closeFrames.js +8 -0
  178. package/dist/runtime/layout/createSplitDecoEdge.d.ts +0 -0
  179. package/dist/runtime/layout/createSplitDecoEdge.js +24 -0
  180. package/dist/runtime/layout/createSplitDecoFromDrag.d.ts +0 -0
  181. package/dist/runtime/layout/createSplitDecoFromDrag.js +14 -0
  182. package/dist/runtime/layout/debugFrame.d.ts +0 -0
  183. package/dist/runtime/layout/debugFrame.js +4 -0
  184. package/dist/runtime/layout/findFramesTouchingEdge.d.ts +0 -0
  185. package/dist/runtime/layout/findFramesTouchingEdge.js +33 -0
  186. package/dist/runtime/layout/findSafeSplitEdge.d.ts +0 -0
  187. package/dist/runtime/layout/findSafeSplitEdge.js +20 -0
  188. package/dist/runtime/layout/findVisualEdge.d.ts +0 -0
  189. package/dist/runtime/layout/findVisualEdge.js +9 -0
  190. package/dist/runtime/layout/frameCreate.d.ts +0 -0
  191. package/dist/runtime/layout/frameCreate.js +13 -0
  192. package/dist/runtime/layout/frameSplit.d.ts +0 -0
  193. package/dist/runtime/layout/frameSplit.js +9 -0
  194. package/dist/runtime/layout/getCloseFrameInfo.d.ts +0 -0
  195. package/dist/runtime/layout/getCloseFrameInfo.js +103 -0
  196. package/dist/runtime/layout/getFrameSplitInfo.d.ts +0 -0
  197. package/dist/runtime/layout/getFrameSplitInfo.js +40 -0
  198. package/dist/runtime/layout/getFrameTo.d.ts +0 -0
  199. package/dist/runtime/layout/getFrameTo.js +47 -0
  200. package/dist/runtime/layout/index.d.ts +0 -0
  201. package/dist/runtime/layout/index.js +22 -0
  202. package/dist/runtime/layout/isPointInFrame.d.ts +0 -0
  203. package/dist/runtime/layout/isPointInFrame.js +4 -0
  204. package/dist/runtime/layout/layoutAddWindow.d.ts +0 -0
  205. package/dist/runtime/layout/layoutAddWindow.js +4 -0
  206. package/dist/runtime/layout/layoutCreate.d.ts +0 -0
  207. package/dist/runtime/layout/layoutCreate.js +7 -0
  208. package/dist/runtime/layout/layoutRemoveWindow.d.ts +0 -0
  209. package/dist/runtime/layout/layoutRemoveWindow.js +5 -0
  210. package/dist/runtime/layout/resizeFrame.d.ts +0 -0
  211. package/dist/runtime/layout/resizeFrame.js +69 -0
  212. package/dist/runtime/layout/windowAddFrame.d.ts +0 -0
  213. package/dist/runtime/layout/windowAddFrame.js +4 -0
  214. package/dist/runtime/layout/windowCreate.d.ts +0 -0
  215. package/dist/runtime/layout/windowCreate.js +13 -0
  216. package/dist/runtime/layout/windowRemoveFrame.d.ts +0 -0
  217. package/dist/runtime/layout/windowRemoveFrame.js +5 -0
  218. package/dist/runtime/layout/windowSetActiveFrame.d.ts +0 -0
  219. package/dist/runtime/layout/windowSetActiveFrame.js +5 -0
  220. package/dist/runtime/settings.d.ts +0 -0
  221. package/dist/runtime/settings.js +54 -0
  222. package/dist/runtime/types/index.d.ts +0 -0
  223. package/dist/runtime/types/index.js +120 -0
  224. package/dist/runtime/utils/KnownError.d.ts +0 -0
  225. package/dist/runtime/utils/KnownError.js +9 -0
  226. package/dist/types.d.mts +5 -0
  227. package/package.json +153 -0
  228. package/src/module.ts +43 -0
  229. package/src/runtime/components/LayoutDecos.vue +62 -0
  230. package/src/runtime/components/LayoutEdges.vue +172 -0
  231. package/src/runtime/components/LayoutFrame.vue +47 -0
  232. package/src/runtime/components/LayoutShapeSquare.vue +38 -0
  233. package/src/runtime/components/LayoutWindow.vue +223 -0
  234. package/src/runtime/composables/useFrames.ts +251 -0
  235. package/src/runtime/demo/App.vue +139 -0
  236. package/src/runtime/demo/DemoControls.vue +17 -0
  237. package/src/runtime/demo/README.md +1 -0
  238. package/src/runtime/demo/main.ts +9 -0
  239. package/src/runtime/demo/sharedLayoutInstance.ts +7 -0
  240. package/src/runtime/demo/tailwind.css +4 -0
  241. package/src/runtime/drag/CloseAction.ts +158 -0
  242. package/src/runtime/drag/DragActionHandler.ts +146 -0
  243. package/src/runtime/drag/DragDirectionStore.ts +63 -0
  244. package/src/runtime/drag/SplitAction.ts +147 -0
  245. package/src/runtime/drag/types.ts +107 -0
  246. package/src/runtime/helpers/addPointsToIntersection.ts +9 -0
  247. package/src/runtime/helpers/assertEdgeSorted.ts +11 -0
  248. package/src/runtime/helpers/assertItemIn.ts +13 -0
  249. package/src/runtime/helpers/assertItemNotIn.ts +10 -0
  250. package/src/runtime/helpers/assertLayoutHasActiveWindow.ts +9 -0
  251. package/src/runtime/helpers/assertValidWinAndFrame.ts +16 -0
  252. package/src/runtime/helpers/assertValidWinAndFrameIds.ts +9 -0
  253. package/src/runtime/helpers/assertWindowHasActiveFrame.ts +9 -0
  254. package/src/runtime/helpers/clampNumber.ts +9 -0
  255. package/src/runtime/helpers/cloneFrame.ts +5 -0
  256. package/src/runtime/helpers/cloneFrames.ts +20 -0
  257. package/src/runtime/helpers/containsEdge.ts +16 -0
  258. package/src/runtime/helpers/convertLayoutWindowToWorkspace.ts +18 -0
  259. package/src/runtime/helpers/copySize.ts +7 -0
  260. package/src/runtime/helpers/createEdge.ts +19 -0
  261. package/src/runtime/helpers/dirToOrientation.ts +12 -0
  262. package/src/runtime/helpers/dirToSide.ts +7 -0
  263. package/src/runtime/helpers/doEdgesOverlap.ts +25 -0
  264. package/src/runtime/helpers/doesEdgeContinueEdge.ts +20 -0
  265. package/src/runtime/helpers/edgeToPoints.ts +5 -0
  266. package/src/runtime/helpers/findDraggableEdge.ts +24 -0
  267. package/src/runtime/helpers/findFrameDraggableEdges.ts +32 -0
  268. package/src/runtime/helpers/frameToEdges.ts +32 -0
  269. package/src/runtime/helpers/frameToPoints.ts +14 -0
  270. package/src/runtime/helpers/getEdgeOrientation.ts +6 -0
  271. package/src/runtime/helpers/getEdgeSharedDirection.ts +10 -0
  272. package/src/runtime/helpers/getEdgeSide.ts +27 -0
  273. package/src/runtime/helpers/getFrameById.ts +15 -0
  274. package/src/runtime/helpers/getFrameConstant.ts +22 -0
  275. package/src/runtime/helpers/getIntersections.ts +87 -0
  276. package/src/runtime/helpers/getIntersectionsCss.ts +65 -0
  277. package/src/runtime/helpers/getMoveEdgeInfo.ts +69 -0
  278. package/src/runtime/helpers/getResizeLimit.ts +60 -0
  279. package/src/runtime/helpers/getShapeSquareCss.ts +28 -0
  280. package/src/runtime/helpers/getSideTouching.ts +9 -0
  281. package/src/runtime/helpers/getVisualEdgeCss.ts +53 -0
  282. package/src/runtime/helpers/getVisualEdges.ts +155 -0
  283. package/src/runtime/helpers/getVisualEdgesCss.ts +13 -0
  284. package/src/runtime/helpers/getWinAndFrameById.ts +28 -0
  285. package/src/runtime/helpers/getWinByFrameUuid.ts +19 -0
  286. package/src/runtime/helpers/getWinById.ts +12 -0
  287. package/src/runtime/helpers/getWindowConstant.ts +21 -0
  288. package/src/runtime/helpers/inRange.ts +5 -0
  289. package/src/runtime/helpers/index.ts +64 -0
  290. package/src/runtime/helpers/isEdgeEqual.ts +14 -0
  291. package/src/runtime/helpers/isEdgeParallel.ts +10 -0
  292. package/src/runtime/helpers/isPointEqual.ts +5 -0
  293. package/src/runtime/helpers/isSizeAboveMin.ts +8 -0
  294. package/src/runtime/helpers/isSizeEqual.ts +5 -0
  295. package/src/runtime/helpers/isWindowEdge.ts +11 -0
  296. package/src/runtime/helpers/isWindowEdgePoint.ts +8 -0
  297. package/src/runtime/helpers/moveEdge.ts +21 -0
  298. package/src/runtime/helpers/numberToScaledPercent.ts +19 -0
  299. package/src/runtime/helpers/numberToScaledSize.ts +28 -0
  300. package/src/runtime/helpers/oppositeSide.ts +45 -0
  301. package/src/runtime/helpers/resizeByEdge.ts +45 -0
  302. package/src/runtime/helpers/sideToDirection.ts +15 -0
  303. package/src/runtime/helpers/sideToOrientation.ts +12 -0
  304. package/src/runtime/helpers/splitEdge.ts +23 -0
  305. package/src/runtime/helpers/toCoord.ts +13 -0
  306. package/src/runtime/helpers/toId.ts +9 -0
  307. package/src/runtime/helpers/toWindowCoord.ts +23 -0
  308. package/src/runtime/helpers/unionEdges.ts +11 -0
  309. package/src/runtime/helpers/updateWindowSizeWithEvent.ts +10 -0
  310. package/src/runtime/index.ts +5 -0
  311. package/src/runtime/layout/closeFrame.ts +33 -0
  312. package/src/runtime/layout/closeFrames.ts +14 -0
  313. package/src/runtime/layout/createSplitDecoEdge.ts +34 -0
  314. package/src/runtime/layout/createSplitDecoFromDrag.ts +24 -0
  315. package/src/runtime/layout/debugFrame.ts +6 -0
  316. package/src/runtime/layout/findFramesTouchingEdge.ts +92 -0
  317. package/src/runtime/layout/findSafeSplitEdge.ts +39 -0
  318. package/src/runtime/layout/findVisualEdge.ts +11 -0
  319. package/src/runtime/layout/frameCreate.ts +23 -0
  320. package/src/runtime/layout/frameSplit.ts +31 -0
  321. package/src/runtime/layout/getCloseFrameInfo.ts +193 -0
  322. package/src/runtime/layout/getFrameSplitInfo.ts +65 -0
  323. package/src/runtime/layout/getFrameTo.ts +65 -0
  324. package/src/runtime/layout/index.ts +24 -0
  325. package/src/runtime/layout/isPointInFrame.ts +7 -0
  326. package/src/runtime/layout/layoutAddWindow.ts +6 -0
  327. package/src/runtime/layout/layoutCreate.ts +12 -0
  328. package/src/runtime/layout/layoutRemoveWindow.ts +7 -0
  329. package/src/runtime/layout/resizeFrame.ts +106 -0
  330. package/src/runtime/layout/windowAddFrame.ts +10 -0
  331. package/src/runtime/layout/windowCreate.ts +18 -0
  332. package/src/runtime/layout/windowRemoveFrame.ts +7 -0
  333. package/src/runtime/layout/windowSetActiveFrame.ts +7 -0
  334. package/src/runtime/settings.ts +63 -0
  335. package/src/runtime/types/index.ts +293 -0
  336. package/src/runtime/utils/KnownError.ts +24 -0
@@ -0,0 +1,45 @@
1
+ import type {
2
+ Direction,
3
+ Edge, LayoutFrame
4
+ } from "../types/index.js"
5
+
6
+ export function resizeByEdge(
7
+ touchingFrames: LayoutFrame[],
8
+ edge: Edge,
9
+ dir: Direction,
10
+ newPos: number,
11
+ distance: number
12
+ ): void {
13
+ if (distance === 0) return
14
+
15
+ for (const frame of touchingFrames) {
16
+ if (dir === "up" || dir === "down") {
17
+ const isAbove = frame.y < edge!.startY
18
+
19
+ if (isAbove) {
20
+ frame.height = newPos - frame.y
21
+ } else {
22
+ // careful order
23
+ frame.height = (frame.y + frame.height) - newPos
24
+ frame.y = newPos
25
+ }
26
+ } else {
27
+ const isLeft = frame.x < edge!.startX
28
+
29
+ if (isLeft) {
30
+ frame.width = newPos - frame.x
31
+ } else {
32
+ // careful order
33
+ frame.width = (frame.x + frame.width) - newPos
34
+ frame.x = newPos
35
+ }
36
+ }
37
+ }
38
+ if (dir === "up" || dir === "down") {
39
+ edge!.startY = newPos
40
+ edge!.endY = newPos
41
+ } else {
42
+ edge!.startX = newPos
43
+ edge!.endX = newPos
44
+ }
45
+ }
@@ -0,0 +1,15 @@
1
+ import type { Direction, EdgeSide } from "../types/index.js"
2
+
3
+ /** Converts a side to a direction (relative to a frame's center) */
4
+
5
+ export function sideToDirection(side: EdgeSide): Direction {
6
+ switch (side) {
7
+ case "left":
8
+ case "right":
9
+ return side
10
+ case "top":
11
+ return "up"
12
+ case "bottom":
13
+ return "down"
14
+ }
15
+ }
@@ -0,0 +1,12 @@
1
+ import type { EdgeSide, Orientation } from "../types/index.js"
2
+
3
+ export function sideToOrientation(dir: EdgeSide): Orientation {
4
+ switch (dir) {
5
+ case "left":
6
+ case "right":
7
+ return "vertical"
8
+ case "top":
9
+ case "bottom":
10
+ return "horizontal"
11
+ }
12
+ }
@@ -0,0 +1,23 @@
1
+ import { last } from "@alanscodelog/utils/last"
2
+
3
+ import type { Edge, Orientation } from "../types/index.js"
4
+
5
+ export function splitEdge(edge: Edge, edgeDirection: Orientation, splits: number[]): Edge[] {
6
+ const startKey = edgeDirection === "horizontal" ? "startX" : "startY"
7
+ const endKey = edgeDirection === "horizontal" ? "endX" : "endY"
8
+ const newEdges: Edge[] = []
9
+ if (splits.length === 0) throw new Error("There must be at least one split position.")
10
+ for (const [i, splitPos] of splits.entries()) {
11
+ if (i === 0) {
12
+ newEdges.push({ ...edge, [startKey]: edge[startKey], [endKey]: splitPos })
13
+ } else {
14
+ const prevEdge = newEdges[i - 1]
15
+ newEdges.push({ ...prevEdge, [startKey]: prevEdge[endKey], [endKey]: splitPos })
16
+ }
17
+ }
18
+ const prevEdge = last(newEdges)
19
+ if (prevEdge[endKey] !== edge[endKey]) {
20
+ newEdges.push({ ...prevEdge, [startKey]: prevEdge[endKey], [endKey]: edge[endKey] })
21
+ }
22
+ return newEdges
23
+ }
@@ -0,0 +1,13 @@
1
+ import type { HasOpposite } from "../types/index.js"
2
+
3
+ /** Converts the given side/dir into a coordinate key (x/y) */
4
+ export function toCoord<T extends HasOpposite>(dir: T): T extends "left" | "right" | "horizontal" ? "x" : "y" {
5
+ switch (dir) {
6
+ case "left":
7
+ case "right":
8
+ case "horizontal":
9
+ return "x" satisfies "x" | "y" as any
10
+ default:
11
+ return "y" satisfies "x" | "y" as any
12
+ }
13
+ }
@@ -0,0 +1,9 @@
1
+ import { unreachable } from "@alanscodelog/utils/unreachable"
2
+
3
+ export function toId(item: { id: string } | string): string {
4
+ return typeof item === "string"
5
+ ? item
6
+ : typeof item.id === "string"
7
+ ? item.id
8
+ : unreachable()
9
+ }
@@ -0,0 +1,23 @@
1
+ import { snapNumber } from "@alanscodelog/utils/snapNumber"
2
+
3
+ import { numberToScaledPercent } from "./numberToScaledPercent.js"
4
+
5
+ import { getSnapPoint } from "../settings.js"
6
+ import type { LayoutWindow, Point } from "../types/index.js"
7
+
8
+ export function toWindowCoord(
9
+ win: LayoutWindow,
10
+ e: Pick<PointerEvent, "clientX" | "clientY">,
11
+ snapAmount: Point = getSnapPoint()
12
+ ): Point {
13
+ const x = numberToScaledPercent((e.clientX - win.pxX), win.pxWidth)
14
+ const y = numberToScaledPercent((e.clientY - win.pxY), win.pxHeight)
15
+
16
+ if (snapAmount) {
17
+ return {
18
+ x: snapNumber(x, snapAmount.x),
19
+ y: snapNumber(y, snapAmount.x)
20
+ }
21
+ }
22
+ return { x, y }
23
+ }
@@ -0,0 +1,11 @@
1
+ import { last } from "@alanscodelog/utils/last"
2
+
3
+ import type { Edge, Orientation } from "../types/index.js"
4
+
5
+ export function unionEdges(edges: Edge[], dir: Orientation): Edge {
6
+ const startKey = dir === "horizontal" ? "startX" : "startY"
7
+ const endKey = dir === "horizontal" ? "endX" : "endY"
8
+ edges.sort((a, b) => a[startKey] - b[startKey])
9
+ const newEdge = { ...edges[0], [startKey]: edges[0][startKey], [endKey]: last(edges)[endKey] }
10
+ return newEdge
11
+ }
@@ -0,0 +1,10 @@
1
+ import type { LayoutWindow, PxPos, PxSize } from "../types/index.js"
2
+
3
+ const props = ["pxWidth", "pxHeight", "pxX", "pxY"] as const
4
+ export function updateWindowWithEvent(win: LayoutWindow, event: PxPos & PxSize): void {
5
+ for (const prop of props) {
6
+ if (event[prop] && win[prop] !== event[prop]) {
7
+ win[prop] = event[prop]
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./types/index.js"
2
+ export * from "./layout/index.js"
3
+ export * from "./helpers/index.js"
4
+ export * from "./utils/KnownError.js"
5
+ export * from "./settings.js"
@@ -0,0 +1,33 @@
1
+ import { closeFrames } from "./closeFrames.js"
2
+ import { getCloseFrameInfo } from "./getCloseFrameInfo.js"
3
+
4
+ import { getMarginSize } from "../settings.js"
5
+ import type { Direction, Edge, EdgeSide, LAYOUT_ERROR, LayoutFrame, LayoutWindow, Size } from "../types/index.js"
6
+ import type { KnownError } from "../utils/KnownError.js"
7
+
8
+ export function closeFrame<T extends "edge" | "dir">(
9
+ win: LayoutWindow,
10
+ visualEdges: Edge[],
11
+ frame: LayoutFrame,
12
+ /** See {@link getCloseFrameInfo} */
13
+ // future, support multiple dirs? return aggregate error?
14
+ closeDirOrSide: (T extends "dir" ? Direction : EdgeSide),
15
+ closeBy: T = "dir" as any as T,
16
+ force: boolean = false,
17
+ minSize: Size = getMarginSize()
18
+ ): LayoutFrame[]
19
+ | KnownError<
20
+ | typeof LAYOUT_ERROR.CANT_CLOSE_NEARBY_FRAMES_TOO_SMALL
21
+ | typeof LAYOUT_ERROR.CANT_CLOSE_NO_DRAG_EDGE
22
+ | typeof LAYOUT_ERROR.CANT_CLOSE_SINGLE_FRAME
23
+ | typeof LAYOUT_ERROR.CANT_CLOSE_WITHOUT_FORCE
24
+ > {
25
+ const canClose = getCloseFrameInfo(Object.values(win.frames), visualEdges, frame, closeDirOrSide, closeBy, force, minSize)
26
+ if ((canClose instanceof Error)) {
27
+ return canClose
28
+ }
29
+ const { deletedFrames, modifiedFrames } = canClose
30
+ closeFrames(win, deletedFrames, modifiedFrames)
31
+ win.activeFrame = modifiedFrames[0].id
32
+ return deletedFrames
33
+ }
@@ -0,0 +1,14 @@
1
+ import type { LayoutFrame, LayoutWindow } from "../types/index.js"
2
+
3
+ export function closeFrames(
4
+ win: LayoutWindow,
5
+ deletedFrames: LayoutFrame[],
6
+ modifiedFrames: LayoutFrame[]
7
+ ): void {
8
+ for (const f of deletedFrames) {
9
+ delete win.frames[f.id]
10
+ }
11
+ for (const mod of modifiedFrames) {
12
+ win.frames[mod.id] = mod
13
+ }
14
+ }
@@ -0,0 +1,34 @@
1
+ import { findSafeSplitEdgeAndPosition } from "./findSafeSplitEdge.js"
2
+
3
+ import { getMarginSize, getSnapPoint } from "../settings.js"
4
+ import type { LayoutFrame, Point, RawSplitDeco, Size, SplitDecoShapes } from "../types/index.js"
5
+
6
+ export function createSplitDecoEdge(
7
+ frames: Record<string, LayoutFrame>,
8
+ deco: RawSplitDeco,
9
+ snapAmount: Point = getSnapPoint(),
10
+ minSize: Size = getMarginSize()
11
+ ): SplitDecoShapes {
12
+ const frame = frames[deco.id]
13
+ const { edge, position } = findSafeSplitEdgeAndPosition(frame, deco.direction, deco.position, snapAmount, minSize)
14
+ const newFrame = { x: frame.x, y: frame.y, width: frame.width, height: frame.height }
15
+
16
+ switch (deco.direction) {
17
+ case "right":
18
+ newFrame.x = position
19
+ newFrame.width = frame.x + frame.width - position
20
+ break
21
+ case "left":
22
+ newFrame.width = position - frame.x
23
+ break
24
+ case "down":
25
+ newFrame.y = position
26
+ newFrame.height = frame.y + frame.height - position
27
+ break
28
+ case "up":
29
+ newFrame.height = position - frame.y
30
+ break
31
+ }
32
+
33
+ return { edge, newFrame }
34
+ }
@@ -0,0 +1,24 @@
1
+ import { createSplitDecoEdge } from "./createSplitDecoEdge.js"
2
+
3
+ import { dirToOrientation } from "../helpers/dirToOrientation.js"
4
+ import { getMarginSize, getSnapPoint } from "../settings.js"
5
+ import type { Direction, LayoutFrame, Point, RawSplitDeco, Size, SplitDeco } from "../types/index.js"
6
+
7
+ export function createSplitDecoFromDrag(
8
+ frames: Record<string, LayoutFrame>,
9
+ frame: LayoutFrame,
10
+ dragDirection: Direction,
11
+ dragPoint: Point,
12
+ snapAmount: Point = getSnapPoint(),
13
+ minSize: Size = getMarginSize()
14
+ ): SplitDeco {
15
+ const orientation = dirToOrientation(dragDirection)
16
+ const deco: RawSplitDeco = {
17
+ type: "split",
18
+ id: frame.id,
19
+ position: dragPoint[orientation === "horizontal" ? "x" : "y"],
20
+ direction: dragDirection
21
+ }
22
+ ;(deco as SplitDeco).shapes = createSplitDecoEdge(frames, deco, snapAmount, minSize)
23
+ return deco as SplitDeco
24
+ }
@@ -0,0 +1,6 @@
1
+ import type { LayoutFrame } from "../types/index.js"
2
+
3
+ export function debugFrame(frame: LayoutFrame): string {
4
+ const f = frame
5
+ return `id: ${f.id.slice(0, 4)}, x: ${f.x}, y: ${f.y}, w: ${f.width}, h: ${f.height}`
6
+ }
@@ -0,0 +1,92 @@
1
+ import { containsEdge } from "../helpers/containsEdge.js"
2
+ import { dirToSide } from "../helpers/dirToSide.js"
3
+ import { frameToEdges } from "../helpers/frameToEdges.js"
4
+ import { getEdgeOrientation } from "../helpers/getEdgeOrientation.js"
5
+ import { inRange } from "../helpers/inRange.js"
6
+ import { oppositeSide } from "../helpers/oppositeSide.js"
7
+ import { toCoord } from "../helpers/toCoord.js"
8
+ import type { Direction, Edge, EdgeSide, LayoutFrame, Point } from "../types/index.js"
9
+
10
+ /**
11
+ * Given an edge or visualEdge (which might touch/contain several frame edges, see {@link getVisualEdges }), returns the frame edges that match the given criteria. If no criteria is given, just returns all touching frames.
12
+ *
13
+ * Useful, for implementing drag related features.
14
+ *
15
+ * A visual explanation of the options:
16
+ * ```
17
+ * frames (A,B,C,D):
18
+ * ┌──────────────────┐
19
+ * │A ╏B │
20
+ * │ ╏ │
21
+ * ├────────╏ │
22
+ * │C ╏─────────┤
23
+ * │ ╏D │
24
+ * │ ╏ │
25
+ * │ < ╏ > searchDirections
26
+ * │ ╏ │
27
+ * │ + referencePoint*
28
+ * │ ╏ │
29
+ * └──────────────────┘
30
+ * ^visualEdge
31
+ *
32
+ * Note the reference point is not on the line. The coordinate used depends on the orientation of the visualEdge.
33
+ * ```
34
+ * So given the middle visual edge, the point `+` and the right search direction, would return the left edge of frame D.
35
+ *
36
+ * Given the left direction instead it would return C.
37
+ *
38
+ * Given no point, and the right direction it would return B and D.
39
+ */
40
+
41
+ export function findFramesTouchingEdge(
42
+ edge: Edge,
43
+ frames: LayoutFrame[],
44
+ criteria: {
45
+ /**
46
+ * If a position (e.g. a cursor position) is given, only edges within the corresponding horizontal/vertical range will be returned.
47
+ *
48
+ * For example, if the visual edge is vertical, the function will only return edges that contain the y position, ignoring the x position. See the function documentation for a visual example.
49
+ */
50
+ referencePoint?: Point
51
+ /**
52
+ * Several frames can lay to either side of a visual edge. This limits the directions in which to look. Otherwise we look in the directions perpendicular to the visual edge.
53
+ *
54
+ * See the function documentation for a visual example.
55
+ */
56
+ searchDirections?: Direction[]
57
+ } = {}
58
+ ): ({ edge: Edge, frame: LayoutFrame, side: EdgeSide })[] {
59
+ const visualEdge = edge
60
+ const res: ({ edge: Edge, frame: LayoutFrame, side: EdgeSide })[] = []
61
+ const visualEdgeDirection = getEdgeOrientation(visualEdge)
62
+
63
+ const searchDirections = criteria.searchDirections
64
+ ?? (visualEdgeDirection === "horizontal"
65
+ ? ["up", "down"]
66
+ : ["left", "right"])
67
+
68
+ // the side opposite to the direction is the one touching the visual edge
69
+ const frameSearchSides = searchDirections.map(dir => oppositeSide(dirToSide(dir)))
70
+
71
+ const coord = toCoord(visualEdgeDirection)
72
+ const coordUpper: "X" | "Y" = coord.toUpperCase() as any
73
+
74
+ for (const frame of frames) {
75
+ const frameEdges = frameToEdges(frame, frameSearchSides)
76
+ const edges = Object.entries(frameEdges)
77
+
78
+ for (const [side, edge] of edges as [EdgeSide, Edge][]) {
79
+ if (containsEdge(edge, visualEdge, visualEdgeDirection)) {
80
+ if (criteria.referencePoint) {
81
+ const isInRange = inRange(criteria.referencePoint[coord], edge[`start${coordUpper}`], edge[`end${coordUpper}`])
82
+ if (isInRange) {
83
+ res.push({ edge, frame, side })
84
+ }
85
+ } else {
86
+ res.push({ edge, frame, side })
87
+ }
88
+ }
89
+ }
90
+ }
91
+ return res
92
+ }
@@ -0,0 +1,39 @@
1
+ import { clampNumber, snapNumber } from "@alanscodelog/utils"
2
+
3
+ import { dirToOrientation } from "../helpers/dirToOrientation.js"
4
+ import { oppositeSide } from "../helpers/oppositeSide.js"
5
+ import { getMarginSize, getSnapPoint } from "../settings.js"
6
+ import type { Direction, Edge, LayoutFrame, Point, Size } from "../types/index.js"
7
+
8
+ export function findSafeSplitEdgeAndPosition(
9
+ frame: LayoutFrame,
10
+ dragDirection: Direction,
11
+ dragPointOrPosition: Point | number,
12
+ snapAmount: Point = getSnapPoint(),
13
+ minSize: Size = getMarginSize()
14
+ ): { edge: Edge, position: number } {
15
+ const orientation = dirToOrientation(dragDirection)
16
+ const position
17
+ = typeof dragPointOrPosition === "number"
18
+ ? dragPointOrPosition
19
+ : dragPointOrPosition[orientation === "horizontal" ? "x" : "y"]
20
+
21
+ const coordKey = orientation === "vertical" ? "y" : "x"
22
+ const sizeKey = orientation === "vertical" ? "height" : "width"
23
+ const pos = snapNumber(position, snapAmount[coordKey])
24
+ const lowerLimit = snapNumber(frame[coordKey] + minSize[sizeKey], snapAmount[coordKey], "floor")
25
+ const upperLimit = snapNumber(frame[coordKey] + frame[sizeKey] - minSize[sizeKey], snapAmount[coordKey], "floor")
26
+ const clampedPos = clampNumber(pos, lowerLimit, upperLimit)
27
+
28
+ const oppositeCoordKey = oppositeSide(coordKey)
29
+ const oppositeSizeKey = oppositeSide(sizeKey)
30
+ const frameStart = snapNumber(frame[oppositeCoordKey], snapAmount[oppositeCoordKey])
31
+ const frameEnd = snapNumber(frameStart + frame[oppositeSizeKey], snapAmount[oppositeCoordKey])
32
+
33
+ // createEdge is not needed, we can be sure edge created is sorted
34
+ const edge = orientation === "vertical"
35
+ ? { startY: clampedPos, endY: clampedPos, startX: frameStart, endX: frameEnd }
36
+ : { startX: clampedPos, endX: clampedPos, startY: frameStart, endY: frameEnd }
37
+
38
+ return { edge, position: clampedPos }
39
+ }
@@ -0,0 +1,11 @@
1
+ import { containsEdge } from "../helpers/containsEdge.js"
2
+ import { getEdgeOrientation } from "../helpers/getEdgeOrientation.js"
3
+ import type { Edge } from "../types/index.js"
4
+
5
+ export function findVisualEdge(visualEdges: Edge[], edge: Edge): Edge | undefined {
6
+ const edgeDirection = getEdgeOrientation(edge)
7
+ for (const visualEdge of visualEdges) {
8
+ if (containsEdge(visualEdge, edge, edgeDirection)) return visualEdge
9
+ }
10
+ return undefined
11
+ }
@@ -0,0 +1,23 @@
1
+ import { v4 as uuidv4 } from "uuid"
2
+
3
+ import { getMaxInt } from "../settings.js"
4
+ import type {
5
+ BaseLayoutFrame,
6
+ ExtendedLayoutFrame,
7
+ LayoutFrame
8
+ } from "../types/index.js"
9
+
10
+ /** Create a new frame. Note that it will always have a new id if it's undefined. */
11
+ export function frameCreate(
12
+ opts: Partial<BaseLayoutFrame> & Omit<ExtendedLayoutFrame, keyof BaseLayoutFrame> = {}
13
+ ): LayoutFrame {
14
+ const maxInt = getMaxInt()
15
+ return {
16
+ width: maxInt,
17
+ height: maxInt,
18
+ x: 0,
19
+ y: 0,
20
+ ...opts,
21
+ id: opts.id ?? uuidv4()
22
+ }
23
+ }
@@ -0,0 +1,31 @@
1
+ import { keys } from "@alanscodelog/utils/keys"
2
+
3
+ import type { LayoutFrame, LayoutWindow } from "../types/index.js"
4
+
5
+ /**
6
+ * Apply a frame split. See {@link getFrameSplitInfo}
7
+ * ```ts
8
+ * // undefined if we can't split
9
+ * const splitInfo = getFrameSplitInfo()
10
+ * if (splitInfo) {
11
+ * frameSplit(win, splitInfo)
12
+ *
13
+ * }
14
+ * ```
15
+ */
16
+
17
+ export function frameSplit(
18
+ win: LayoutWindow,
19
+ { splitFrame, newFrame }: {
20
+ splitFrame: LayoutFrame
21
+ newFrame: LayoutFrame
22
+ }
23
+ ): LayoutFrame | undefined {
24
+ const winFrame = win.frames[splitFrame.id]
25
+ for (const key of keys(splitFrame)) {
26
+ // @ts-expect-error wut
27
+ winFrame[key] = splitFrame[key]
28
+ }
29
+ win.frames[newFrame.id] = newFrame
30
+ return newFrame
31
+ }