@vuu-ui/vuu-layout 2.1.18 → 2.1.19-beta.2

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 (353) hide show
  1. package/package.json +15 -18
  2. package/src/Component.js +14 -0
  3. package/src/LayoutContainer.css.js +24 -0
  4. package/src/LayoutContainer.js +26 -0
  5. package/src/debug.js +16 -0
  6. package/src/dock-layout/DockLayout.css.js +36 -0
  7. package/src/dock-layout/DockLayout.js +43 -0
  8. package/src/dock-layout/Drawer.css.js +150 -0
  9. package/src/dock-layout/Drawer.js +82 -0
  10. package/src/dock-layout/index.js +2 -0
  11. package/src/drag-drop/BoxModel.js +337 -0
  12. package/src/drag-drop/DragState.js +119 -0
  13. package/src/drag-drop/Draggable.js +140 -0
  14. package/src/drag-drop/DropTarget.js +286 -0
  15. package/src/drag-drop/DropTargetRenderer.js +275 -0
  16. package/src/drag-drop/dragDropTypes.js +0 -0
  17. package/src/drag-drop/index.js +3 -0
  18. package/src/flexbox/Flexbox.css.js +45 -0
  19. package/src/flexbox/Flexbox.js +45 -0
  20. package/src/flexbox/FlexboxLayout.js +27 -0
  21. package/src/flexbox/Splitter.css.js +57 -0
  22. package/src/flexbox/Splitter.js +112 -0
  23. package/src/flexbox/flexbox-utils.js +92 -0
  24. package/src/flexbox/flexboxTypes.js +0 -0
  25. package/src/flexbox/index.js +2 -0
  26. package/src/flexbox/useSplitterResizing.js +181 -0
  27. package/src/index.js +20 -0
  28. package/src/layout-action.js +20 -0
  29. package/src/layout-header/ActionButton.js +15 -0
  30. package/src/layout-header/Header.css.js +32 -0
  31. package/src/layout-header/Header.js +99 -0
  32. package/src/layout-header/index.js +1 -0
  33. package/src/layout-header/useHeader.js +76 -0
  34. package/src/layout-provider/LayoutProvider.js +242 -0
  35. package/src/layout-provider/LayoutProviderContext.js +13 -0
  36. package/src/layout-provider/index.js +2 -0
  37. package/src/layout-provider/useLayoutDragDrop.js +147 -0
  38. package/src/layout-reducer/flexUtils.js +186 -0
  39. package/src/layout-reducer/index.js +4 -0
  40. package/src/layout-reducer/insert-layout-element.js +179 -0
  41. package/src/layout-reducer/layout-reducer.js +121 -0
  42. package/src/layout-reducer/layoutTypes.js +34 -0
  43. package/src/layout-reducer/layoutUtils.js +178 -0
  44. package/src/layout-reducer/move-layout-element.js +18 -0
  45. package/src/layout-reducer/remove-layout-element.js +161 -0
  46. package/src/layout-reducer/replace-layout-element.js +70 -0
  47. package/src/layout-reducer/resize-flex-children.js +48 -0
  48. package/src/layout-reducer/wrap-layout-element.js +134 -0
  49. package/src/layout-view/View.css.js +76 -0
  50. package/src/layout-view/View.js +116 -0
  51. package/src/layout-view/useView.js +69 -0
  52. package/src/layout-view/useViewBroadcastChannel.js +29 -0
  53. package/src/layout-view/useViewResize.js +27 -0
  54. package/src/layout-view/viewTypes.js +0 -0
  55. package/src/layout-view-actions/ViewContext.js +11 -0
  56. package/src/layout-view-actions/useViewActionDispatcher.js +116 -0
  57. package/src/layout-view-actions/useViewContributions.js +31 -0
  58. package/src/palette/Palette.css.js +31 -0
  59. package/src/palette/Palette.js +85 -0
  60. package/src/palette/index.js +1 -0
  61. package/src/placeholder/LayoutStartPanel.css.js +35 -0
  62. package/src/placeholder/LayoutStartPanel.js +57 -0
  63. package/src/placeholder/Placeholder.css.js +20 -0
  64. package/src/placeholder/Placeholder.js +33 -0
  65. package/src/placeholder/index.js +1 -0
  66. package/src/responsive/index.js +2 -0
  67. package/src/responsive/measureMinimumNodeSize.js +24 -0
  68. package/src/responsive/useResizeObserver.js +109 -0
  69. package/src/responsive/utils.js +27 -0
  70. package/src/stack/Stack.css.js +44 -0
  71. package/src/stack/Stack.js +98 -0
  72. package/src/stack/StackLayout.js +116 -0
  73. package/src/stack/index.js +3 -0
  74. package/src/stack/stackTypes.js +0 -0
  75. package/src/tabs/TabPanel.css.js +17 -0
  76. package/src/tabs/TabPanel.js +11 -0
  77. package/src/tabs/index.js +1 -0
  78. package/src/tools/config-wrapper/ConfigWrapper.js +55 -0
  79. package/src/tools/config-wrapper/index.js +1 -0
  80. package/src/tools/devtools-box/layout-configurator.css.js +113 -0
  81. package/src/tools/devtools-tree/layout-tree-viewer.css.js +17 -0
  82. package/src/tools/index.js +3 -0
  83. package/src/use-persistent-state.js +43 -0
  84. package/src/utils/index.js +5 -0
  85. package/src/utils/pathUtils.js +212 -0
  86. package/src/utils/propUtils.js +15 -0
  87. package/src/utils/refUtils.js +5 -0
  88. package/src/utils/styleUtils.js +9 -0
  89. package/src/utils/typeOf.js +15 -0
  90. package/types/dock-layout/DockLayout.d.ts +4 -4
  91. package/types/dock-layout/Drawer.d.ts +4 -4
  92. package/types/drag-drop/BoxModel.d.ts +7 -7
  93. package/types/flexbox/FlexboxLayout.d.ts +4 -4
  94. package/types/flexbox/Splitter.d.ts +1 -1
  95. package/types/layout-reducer/layoutUtils.d.ts +1 -1
  96. package/types/layout-reducer/remove-layout-element.d.ts +1 -1
  97. package/types/layout-reducer/replace-layout-element.d.ts +2 -2
  98. package/types/layout-reducer/resize-flex-children.d.ts +2 -2
  99. package/types/layout-view/useView.d.ts +1 -1
  100. package/types/placeholder/Placeholder.d.ts +4 -4
  101. package/types/responsive/overflowUtils.d.ts +2 -2
  102. package/types/stack/StackLayout.d.ts +4 -4
  103. package/types/tools/devtools-box/layout-configurator.d.ts +26 -26
  104. package/types/tools/devtools-tree/layout-tree-viewer.d.ts +2 -2
  105. package/types/utils/pathUtils.d.ts +1 -1
  106. package/cjs/Component.js +0 -14
  107. package/cjs/Component.js.map +0 -1
  108. package/cjs/LayoutContainer.css.js +0 -6
  109. package/cjs/LayoutContainer.css.js.map +0 -1
  110. package/cjs/LayoutContainer.js +0 -33
  111. package/cjs/LayoutContainer.js.map +0 -1
  112. package/cjs/dock-layout/DockLayout.css.js +0 -6
  113. package/cjs/dock-layout/DockLayout.css.js.map +0 -1
  114. package/cjs/dock-layout/DockLayout.js +0 -41
  115. package/cjs/dock-layout/DockLayout.js.map +0 -1
  116. package/cjs/dock-layout/Drawer.css.js +0 -6
  117. package/cjs/dock-layout/Drawer.css.js.map +0 -1
  118. package/cjs/dock-layout/Drawer.js +0 -95
  119. package/cjs/dock-layout/Drawer.js.map +0 -1
  120. package/cjs/drag-drop/BoxModel.js +0 -416
  121. package/cjs/drag-drop/BoxModel.js.map +0 -1
  122. package/cjs/drag-drop/DragState.js +0 -161
  123. package/cjs/drag-drop/DragState.js.map +0 -1
  124. package/cjs/drag-drop/Draggable.js +0 -192
  125. package/cjs/drag-drop/Draggable.js.map +0 -1
  126. package/cjs/drag-drop/DropTarget.js +0 -257
  127. package/cjs/drag-drop/DropTarget.js.map +0 -1
  128. package/cjs/drag-drop/DropTargetRenderer.js +0 -218
  129. package/cjs/drag-drop/DropTargetRenderer.js.map +0 -1
  130. package/cjs/flexbox/Flexbox.css.js +0 -6
  131. package/cjs/flexbox/Flexbox.css.js.map +0 -1
  132. package/cjs/flexbox/Flexbox.js +0 -69
  133. package/cjs/flexbox/Flexbox.js.map +0 -1
  134. package/cjs/flexbox/FlexboxLayout.js +0 -30
  135. package/cjs/flexbox/FlexboxLayout.js.map +0 -1
  136. package/cjs/flexbox/Splitter.css.js +0 -6
  137. package/cjs/flexbox/Splitter.css.js.map +0 -1
  138. package/cjs/flexbox/Splitter.js +0 -122
  139. package/cjs/flexbox/Splitter.js.map +0 -1
  140. package/cjs/flexbox/flexbox-utils.js +0 -95
  141. package/cjs/flexbox/flexbox-utils.js.map +0 -1
  142. package/cjs/flexbox/useSplitterResizing.js +0 -197
  143. package/cjs/flexbox/useSplitterResizing.js.map +0 -1
  144. package/cjs/index.js +0 -122
  145. package/cjs/index.js.map +0 -1
  146. package/cjs/layout-action.js +0 -24
  147. package/cjs/layout-action.js.map +0 -1
  148. package/cjs/layout-header/Header.css.js +0 -6
  149. package/cjs/layout-header/Header.css.js.map +0 -1
  150. package/cjs/layout-header/Header.js +0 -152
  151. package/cjs/layout-header/Header.js.map +0 -1
  152. package/cjs/layout-header/useHeader.js +0 -85
  153. package/cjs/layout-header/useHeader.js.map +0 -1
  154. package/cjs/layout-provider/LayoutProvider.js +0 -304
  155. package/cjs/layout-provider/LayoutProvider.js.map +0 -1
  156. package/cjs/layout-provider/LayoutProviderContext.js +0 -23
  157. package/cjs/layout-provider/LayoutProviderContext.js.map +0 -1
  158. package/cjs/layout-provider/useLayoutDragDrop.js +0 -177
  159. package/cjs/layout-provider/useLayoutDragDrop.js.map +0 -1
  160. package/cjs/layout-reducer/flexUtils.js +0 -227
  161. package/cjs/layout-reducer/flexUtils.js.map +0 -1
  162. package/cjs/layout-reducer/insert-layout-element.js +0 -286
  163. package/cjs/layout-reducer/insert-layout-element.js.map +0 -1
  164. package/cjs/layout-reducer/layout-reducer.js +0 -202
  165. package/cjs/layout-reducer/layout-reducer.js.map +0 -1
  166. package/cjs/layout-reducer/layoutTypes.js +0 -40
  167. package/cjs/layout-reducer/layoutTypes.js.map +0 -1
  168. package/cjs/layout-reducer/layoutUtils.js +0 -237
  169. package/cjs/layout-reducer/layoutUtils.js.map +0 -1
  170. package/cjs/layout-reducer/move-layout-element.js +0 -31
  171. package/cjs/layout-reducer/move-layout-element.js.map +0 -1
  172. package/cjs/layout-reducer/remove-layout-element.js +0 -237
  173. package/cjs/layout-reducer/remove-layout-element.js.map +0 -1
  174. package/cjs/layout-reducer/replace-layout-element.js +0 -96
  175. package/cjs/layout-reducer/replace-layout-element.js.map +0 -1
  176. package/cjs/layout-reducer/resize-flex-children.js +0 -62
  177. package/cjs/layout-reducer/resize-flex-children.js.map +0 -1
  178. package/cjs/layout-reducer/wrap-layout-element.js +0 -211
  179. package/cjs/layout-reducer/wrap-layout-element.js.map +0 -1
  180. package/cjs/layout-view/View.css.js +0 -6
  181. package/cjs/layout-view/View.css.js.map +0 -1
  182. package/cjs/layout-view/View.js +0 -160
  183. package/cjs/layout-view/View.js.map +0 -1
  184. package/cjs/layout-view/useView.js +0 -75
  185. package/cjs/layout-view/useView.js.map +0 -1
  186. package/cjs/layout-view/useViewBroadcastChannel.js +0 -35
  187. package/cjs/layout-view/useViewBroadcastChannel.js.map +0 -1
  188. package/cjs/layout-view/useViewResize.js +0 -42
  189. package/cjs/layout-view/useViewResize.js.map +0 -1
  190. package/cjs/layout-view-actions/ViewContext.js +0 -16
  191. package/cjs/layout-view-actions/ViewContext.js.map +0 -1
  192. package/cjs/layout-view-actions/useViewActionDispatcher.js +0 -112
  193. package/cjs/layout-view-actions/useViewActionDispatcher.js.map +0 -1
  194. package/cjs/layout-view-actions/useViewContributions.js +0 -33
  195. package/cjs/layout-view-actions/useViewContributions.js.map +0 -1
  196. package/cjs/palette/Palette.css.js +0 -6
  197. package/cjs/palette/Palette.css.js.map +0 -1
  198. package/cjs/palette/Palette.js +0 -115
  199. package/cjs/palette/Palette.js.map +0 -1
  200. package/cjs/placeholder/LayoutStartPanel.css.js +0 -6
  201. package/cjs/placeholder/LayoutStartPanel.css.js.map +0 -1
  202. package/cjs/placeholder/LayoutStartPanel.js +0 -56
  203. package/cjs/placeholder/LayoutStartPanel.js.map +0 -1
  204. package/cjs/placeholder/Placeholder.css.js +0 -6
  205. package/cjs/placeholder/Placeholder.css.js.map +0 -1
  206. package/cjs/placeholder/Placeholder.js +0 -34
  207. package/cjs/placeholder/Placeholder.js.map +0 -1
  208. package/cjs/responsive/useResizeObserver.js +0 -118
  209. package/cjs/responsive/useResizeObserver.js.map +0 -1
  210. package/cjs/responsive/utils.js +0 -34
  211. package/cjs/responsive/utils.js.map +0 -1
  212. package/cjs/stack/Stack.css.js +0 -6
  213. package/cjs/stack/Stack.css.js.map +0 -1
  214. package/cjs/stack/Stack.js +0 -150
  215. package/cjs/stack/Stack.js.map +0 -1
  216. package/cjs/stack/StackLayout.js +0 -116
  217. package/cjs/stack/StackLayout.js.map +0 -1
  218. package/cjs/use-persistent-state.js +0 -63
  219. package/cjs/use-persistent-state.js.map +0 -1
  220. package/cjs/utils/pathUtils.js +0 -293
  221. package/cjs/utils/pathUtils.js.map +0 -1
  222. package/cjs/utils/propUtils.js +0 -27
  223. package/cjs/utils/propUtils.js.map +0 -1
  224. package/cjs/utils/refUtils.js +0 -12
  225. package/cjs/utils/refUtils.js.map +0 -1
  226. package/cjs/utils/styleUtils.js +0 -15
  227. package/cjs/utils/styleUtils.js.map +0 -1
  228. package/cjs/utils/typeOf.js +0 -27
  229. package/cjs/utils/typeOf.js.map +0 -1
  230. package/esm/Component.js +0 -12
  231. package/esm/Component.js.map +0 -1
  232. package/esm/LayoutContainer.css.js +0 -4
  233. package/esm/LayoutContainer.css.js.map +0 -1
  234. package/esm/LayoutContainer.js +0 -31
  235. package/esm/LayoutContainer.js.map +0 -1
  236. package/esm/dock-layout/DockLayout.css.js +0 -4
  237. package/esm/dock-layout/DockLayout.css.js.map +0 -1
  238. package/esm/dock-layout/DockLayout.js +0 -39
  239. package/esm/dock-layout/DockLayout.js.map +0 -1
  240. package/esm/dock-layout/Drawer.css.js +0 -4
  241. package/esm/dock-layout/Drawer.css.js.map +0 -1
  242. package/esm/dock-layout/Drawer.js +0 -93
  243. package/esm/dock-layout/Drawer.js.map +0 -1
  244. package/esm/drag-drop/BoxModel.js +0 -409
  245. package/esm/drag-drop/BoxModel.js.map +0 -1
  246. package/esm/drag-drop/DragState.js +0 -159
  247. package/esm/drag-drop/DragState.js.map +0 -1
  248. package/esm/drag-drop/Draggable.js +0 -190
  249. package/esm/drag-drop/Draggable.js.map +0 -1
  250. package/esm/drag-drop/DropTarget.js +0 -253
  251. package/esm/drag-drop/DropTarget.js.map +0 -1
  252. package/esm/drag-drop/DropTargetRenderer.js +0 -216
  253. package/esm/drag-drop/DropTargetRenderer.js.map +0 -1
  254. package/esm/flexbox/Flexbox.css.js +0 -4
  255. package/esm/flexbox/Flexbox.css.js.map +0 -1
  256. package/esm/flexbox/Flexbox.js +0 -67
  257. package/esm/flexbox/Flexbox.js.map +0 -1
  258. package/esm/flexbox/FlexboxLayout.js +0 -28
  259. package/esm/flexbox/FlexboxLayout.js.map +0 -1
  260. package/esm/flexbox/Splitter.css.js +0 -4
  261. package/esm/flexbox/Splitter.css.js.map +0 -1
  262. package/esm/flexbox/Splitter.js +0 -120
  263. package/esm/flexbox/Splitter.js.map +0 -1
  264. package/esm/flexbox/flexbox-utils.js +0 -89
  265. package/esm/flexbox/flexbox-utils.js.map +0 -1
  266. package/esm/flexbox/useSplitterResizing.js +0 -195
  267. package/esm/flexbox/useSplitterResizing.js.map +0 -1
  268. package/esm/index.js +0 -33
  269. package/esm/index.js.map +0 -1
  270. package/esm/layout-action.js +0 -22
  271. package/esm/layout-action.js.map +0 -1
  272. package/esm/layout-header/Header.css.js +0 -4
  273. package/esm/layout-header/Header.css.js.map +0 -1
  274. package/esm/layout-header/Header.js +0 -150
  275. package/esm/layout-header/Header.js.map +0 -1
  276. package/esm/layout-header/useHeader.js +0 -83
  277. package/esm/layout-header/useHeader.js.map +0 -1
  278. package/esm/layout-provider/LayoutProvider.js +0 -297
  279. package/esm/layout-provider/LayoutProvider.js.map +0 -1
  280. package/esm/layout-provider/LayoutProviderContext.js +0 -20
  281. package/esm/layout-provider/LayoutProviderContext.js.map +0 -1
  282. package/esm/layout-provider/useLayoutDragDrop.js +0 -175
  283. package/esm/layout-provider/useLayoutDragDrop.js.map +0 -1
  284. package/esm/layout-reducer/flexUtils.js +0 -218
  285. package/esm/layout-reducer/flexUtils.js.map +0 -1
  286. package/esm/layout-reducer/insert-layout-element.js +0 -282
  287. package/esm/layout-reducer/insert-layout-element.js.map +0 -1
  288. package/esm/layout-reducer/layout-reducer.js +0 -200
  289. package/esm/layout-reducer/layout-reducer.js.map +0 -1
  290. package/esm/layout-reducer/layoutTypes.js +0 -36
  291. package/esm/layout-reducer/layoutTypes.js.map +0 -1
  292. package/esm/layout-reducer/layoutUtils.js +0 -226
  293. package/esm/layout-reducer/layoutUtils.js.map +0 -1
  294. package/esm/layout-reducer/move-layout-element.js +0 -29
  295. package/esm/layout-reducer/move-layout-element.js.map +0 -1
  296. package/esm/layout-reducer/remove-layout-element.js +0 -235
  297. package/esm/layout-reducer/remove-layout-element.js.map +0 -1
  298. package/esm/layout-reducer/replace-layout-element.js +0 -92
  299. package/esm/layout-reducer/replace-layout-element.js.map +0 -1
  300. package/esm/layout-reducer/resize-flex-children.js +0 -59
  301. package/esm/layout-reducer/resize-flex-children.js.map +0 -1
  302. package/esm/layout-reducer/wrap-layout-element.js +0 -209
  303. package/esm/layout-reducer/wrap-layout-element.js.map +0 -1
  304. package/esm/layout-view/View.css.js +0 -4
  305. package/esm/layout-view/View.css.js.map +0 -1
  306. package/esm/layout-view/View.js +0 -158
  307. package/esm/layout-view/View.js.map +0 -1
  308. package/esm/layout-view/useView.js +0 -73
  309. package/esm/layout-view/useView.js.map +0 -1
  310. package/esm/layout-view/useViewBroadcastChannel.js +0 -33
  311. package/esm/layout-view/useViewBroadcastChannel.js.map +0 -1
  312. package/esm/layout-view/useViewResize.js +0 -40
  313. package/esm/layout-view/useViewResize.js.map +0 -1
  314. package/esm/layout-view-actions/ViewContext.js +0 -12
  315. package/esm/layout-view-actions/ViewContext.js.map +0 -1
  316. package/esm/layout-view-actions/useViewActionDispatcher.js +0 -110
  317. package/esm/layout-view-actions/useViewActionDispatcher.js.map +0 -1
  318. package/esm/layout-view-actions/useViewContributions.js +0 -31
  319. package/esm/layout-view-actions/useViewContributions.js.map +0 -1
  320. package/esm/palette/Palette.css.js +0 -4
  321. package/esm/palette/Palette.css.js.map +0 -1
  322. package/esm/palette/Palette.js +0 -112
  323. package/esm/palette/Palette.js.map +0 -1
  324. package/esm/placeholder/LayoutStartPanel.css.js +0 -4
  325. package/esm/placeholder/LayoutStartPanel.css.js.map +0 -1
  326. package/esm/placeholder/LayoutStartPanel.js +0 -54
  327. package/esm/placeholder/LayoutStartPanel.js.map +0 -1
  328. package/esm/placeholder/Placeholder.css.js +0 -4
  329. package/esm/placeholder/Placeholder.css.js.map +0 -1
  330. package/esm/placeholder/Placeholder.js +0 -32
  331. package/esm/placeholder/Placeholder.js.map +0 -1
  332. package/esm/responsive/useResizeObserver.js +0 -112
  333. package/esm/responsive/useResizeObserver.js.map +0 -1
  334. package/esm/responsive/utils.js +0 -31
  335. package/esm/responsive/utils.js.map +0 -1
  336. package/esm/stack/Stack.css.js +0 -4
  337. package/esm/stack/Stack.css.js.map +0 -1
  338. package/esm/stack/Stack.js +0 -148
  339. package/esm/stack/Stack.js.map +0 -1
  340. package/esm/stack/StackLayout.js +0 -114
  341. package/esm/stack/StackLayout.js.map +0 -1
  342. package/esm/use-persistent-state.js +0 -58
  343. package/esm/use-persistent-state.js.map +0 -1
  344. package/esm/utils/pathUtils.js +0 -280
  345. package/esm/utils/pathUtils.js.map +0 -1
  346. package/esm/utils/propUtils.js +0 -23
  347. package/esm/utils/propUtils.js.map +0 -1
  348. package/esm/utils/refUtils.js +0 -10
  349. package/esm/utils/refUtils.js.map +0 -1
  350. package/esm/utils/styleUtils.js +0 -13
  351. package/esm/utils/styleUtils.js.map +0 -1
  352. package/esm/utils/typeOf.js +0 -23
  353. package/esm/utils/typeOf.js.map +0 -1
@@ -0,0 +1,179 @@
1
+ import { uuid } from "@vuu-ui/vuu-utils";
2
+ import react from "react";
3
+ import { getProp, getProps, nextStep, resetPath, typeOf } from "../utils/index.js";
4
+ import { createPlaceHolder, getFlexDimensions, getFlexOrIntrinsicStyle, getIntrinsicSize, wrapIntrinsicSizeComponentWithFlexbox } from "./flexUtils.js";
5
+ import { getDefaultTabLabel, getManagedDimension } from "./layoutUtils.js";
6
+ function getInsertTabBeforeAfter(stack, pos) {
7
+ const { children: tabs } = stack.props;
8
+ const tabCount = tabs.length;
9
+ const { index = -1, positionRelativeToTab = "after" } = pos.tab || {};
10
+ return -1 === index || index >= tabCount ? [
11
+ tabs[tabCount - 1],
12
+ "after"
13
+ ] : [
14
+ tabs[index] ?? null,
15
+ positionRelativeToTab
16
+ ];
17
+ }
18
+ function insertIntoContainer(container, targetContainer, newComponent) {
19
+ const { active: containerActive, children: containerChildren = [], path: containerPath } = getProps(container);
20
+ const existingComponentPath = getProp(targetContainer, "path");
21
+ const { idx, finalStep } = nextStep(containerPath, existingComponentPath, true);
22
+ const [insertedIdx, children] = finalStep ? insertIntoChildren(container, containerChildren, newComponent) : [
23
+ containerActive,
24
+ containerChildren?.map((child, index)=>index === idx ? insertIntoContainer(child, targetContainer, newComponent) : child)
25
+ ];
26
+ const active = "Stack" === typeOf(container) ? Array.isArray(insertedIdx) ? insertedIdx[0] : insertedIdx : containerActive;
27
+ return react.cloneElement(container, {
28
+ active
29
+ }, children);
30
+ }
31
+ const getDefaultTitle = (containerType, component, index, existingLabels)=>"Stack" === containerType ? getDefaultTabLabel(component, index, existingLabels) : void 0;
32
+ const getChildrenTitles = (children)=>children.map((child)=>child.props.title);
33
+ function insertIntoChildren(container, containerChildren, newComponent) {
34
+ if (Array.isArray(newComponent)) {
35
+ const [firstChild, ...rest] = newComponent;
36
+ let [idx, children] = insertIntoChildren(container, containerChildren, firstChild);
37
+ for (const child of rest)[, children] = insertIntoChildren(container, children, child);
38
+ return [
39
+ idx,
40
+ children
41
+ ];
42
+ }
43
+ const containerPath = getProp(container, "path");
44
+ const count = containerChildren?.length;
45
+ const { id = uuid(), title = getDefaultTitle(typeOf(container), newComponent, count ?? 0, getChildrenTitles(containerChildren)) } = getProps(newComponent);
46
+ if (count) return [
47
+ count,
48
+ containerChildren.concat(resetPath(newComponent, `${containerPath}.${count}`, {
49
+ id,
50
+ key: id,
51
+ title
52
+ }))
53
+ ];
54
+ return [
55
+ 0,
56
+ [
57
+ resetPath(newComponent, `${containerPath}.0`, {
58
+ id,
59
+ title
60
+ })
61
+ ]
62
+ ];
63
+ }
64
+ function insertBesideChild(container, existingComponent, newComponent, insertionPosition, pos, clientRect, dropRect) {
65
+ const { active: containerActive, children: containerChildren, path: containerPath } = getProps(container);
66
+ const existingComponentPath = getProp(existingComponent, "path");
67
+ const { idx, finalStep } = nextStep(containerPath, existingComponentPath);
68
+ const [insertedIdx, children] = finalStep ? updateChildren(container, containerChildren, idx, newComponent, insertionPosition, pos, clientRect, dropRect) : [
69
+ containerActive,
70
+ containerChildren.map((child, index)=>index === idx ? insertBesideChild(child, existingComponent, newComponent, insertionPosition, pos, clientRect, dropRect) : child)
71
+ ];
72
+ const active = "Stack" === typeOf(container) ? insertedIdx : containerActive;
73
+ return react.cloneElement(container, {
74
+ active
75
+ }, children);
76
+ }
77
+ function updateChildren(container, containerChildren, idx, newComponent, insertionPosition, pos, clientRect, dropRect) {
78
+ const intrinsicSize = getIntrinsicSize(newComponent);
79
+ if (intrinsicSize?.width && intrinsicSize?.height) return insertIntrinsicSizedComponent(container, containerChildren, idx, newComponent, insertionPosition, clientRect, dropRect);
80
+ return insertFlexComponent(container, containerChildren, idx, newComponent, insertionPosition, pos?.width || pos?.height, clientRect);
81
+ }
82
+ const getLeadingPlaceholderSize = (flexDirection, insertionPosition, { top, right, bottom, left }, [rectLeft, rectTop, rectRight, rectBottom])=>{
83
+ if ("column" === flexDirection && "before" === insertionPosition) return rectTop - top;
84
+ if ("column" === flexDirection) return bottom - rectBottom;
85
+ if ("row" === flexDirection && "before" === insertionPosition) return rectLeft - left;
86
+ if ("row" === flexDirection) return right - rectRight;
87
+ };
88
+ function insertIntrinsicSizedComponent(container, containerChildren, idx, newComponent, insertionPosition, clientRect, dropRect) {
89
+ const { style: { flexDirection } } = getProps(container);
90
+ const [dimension, crossDimension, contraDirection] = getFlexDimensions(flexDirection);
91
+ const { [crossDimension]: intrinsicCrossSize, [dimension]: intrinsicSize } = getIntrinsicSize(newComponent);
92
+ const path = getProp(containerChildren[idx], "path");
93
+ const placeholderSize = getLeadingPlaceholderSize(flexDirection, insertionPosition, clientRect, dropRect);
94
+ const [itemToInsert, size] = intrinsicCrossSize < clientRect[crossDimension] ? [
95
+ wrapIntrinsicSizeComponentWithFlexbox(newComponent, contraDirection, path, clientRect, dropRect),
96
+ intrinsicSize
97
+ ] : [
98
+ newComponent,
99
+ void 0
100
+ ];
101
+ const placeholder = placeholderSize ? createPlaceHolder(path, placeholderSize, {
102
+ flexGrow: 0,
103
+ flexShrink: 0
104
+ }) : void 0;
105
+ if (intrinsicCrossSize > clientRect[crossDimension]) containerChildren = containerChildren.map((child)=>{
106
+ if (getProp(child, "placeholder")) return child;
107
+ {
108
+ const { [crossDimension]: intrinsicCrossChildSize } = getIntrinsicSize(child);
109
+ if (intrinsicCrossChildSize && intrinsicCrossChildSize < intrinsicCrossSize) return wrapIntrinsicSizeComponentWithFlexbox(child, contraDirection, getProp(child, "path"));
110
+ return child;
111
+ }
112
+ });
113
+ return insertFlexComponent(container, containerChildren, idx, itemToInsert, insertionPosition, size, clientRect, placeholder);
114
+ }
115
+ function insertFlexComponent(container, containerChildren, idx, newComponent, insertionPosition, size, targetRect, placeholder) {
116
+ const containerPath = getProp(container, "path");
117
+ let insertedIdx = 0;
118
+ const children = containerChildren && 0 !== containerChildren.length ? containerChildren.reduce((arr, child, i)=>{
119
+ if (idx === i) {
120
+ const [existingComponent, insertedComponent] = getStyledComponents(container, child, newComponent, targetRect);
121
+ if ("before" === insertionPosition) if (placeholder) arr.push(placeholder, insertedComponent, existingComponent);
122
+ else arr.push(insertedComponent, existingComponent);
123
+ else if (placeholder) arr.push(existingComponent, insertedComponent, placeholder);
124
+ else arr.push(existingComponent, insertedComponent);
125
+ insertedIdx = arr.indexOf(insertedComponent);
126
+ } else arr.push(child);
127
+ return arr;
128
+ }, []).map((child, i)=>i < insertedIdx ? child : resetPath(child, `${containerPath}.${i}`)) : [
129
+ newComponent
130
+ ];
131
+ return [
132
+ insertedIdx,
133
+ children
134
+ ];
135
+ }
136
+ function getStyledComponents(container, existingComponent, newComponent, targetRect) {
137
+ const id = uuid();
138
+ let { version = 0 } = getProps(newComponent);
139
+ version += 1;
140
+ if ("Flexbox" === typeOf(container)) {
141
+ const { style: containerStyle } = container.props;
142
+ const [dim] = getManagedDimension(containerStyle);
143
+ const splitterSize = 6;
144
+ const size = {
145
+ [dim]: (targetRect[dim] - splitterSize) / 2
146
+ };
147
+ const existingComponentStyle = getFlexOrIntrinsicStyle(existingComponent, dim, size);
148
+ const newComponentStyle = getFlexOrIntrinsicStyle(newComponent, dim, size);
149
+ return [
150
+ react.cloneElement(existingComponent, {
151
+ style: existingComponentStyle
152
+ }),
153
+ react.cloneElement(newComponent, {
154
+ id,
155
+ version,
156
+ style: newComponentStyle
157
+ })
158
+ ];
159
+ }
160
+ {
161
+ const { style: { left: _1, top: _2, flex: _3, ...style } = {
162
+ left: void 0,
163
+ top: void 0,
164
+ flex: void 0
165
+ } } = getProps(newComponent);
166
+ return [
167
+ existingComponent,
168
+ react.cloneElement(newComponent, {
169
+ id,
170
+ version,
171
+ style: {
172
+ ...style,
173
+ flex: "1 1 0px"
174
+ }
175
+ })
176
+ ];
177
+ }
178
+ }
179
+ export { getInsertTabBeforeAfter, insertBesideChild, insertIntoContainer };
@@ -0,0 +1,121 @@
1
+ import { isContainer } from "@vuu-ui/vuu-utils";
2
+ import react from "react";
3
+ import { findTarget, followPath, followPathToParent, getProp, getProps, typeOf } from "../utils/index.js";
4
+ import { getIntrinsicSize } from "./flexUtils.js";
5
+ import { getInsertTabBeforeAfter, insertBesideChild, insertIntoContainer } from "./insert-layout-element.js";
6
+ import { moveChild } from "./move-layout-element.js";
7
+ import { LayoutActionType } from "./layoutTypes.js";
8
+ import { removeChild } from "./remove-layout-element.js";
9
+ import { _replaceChild, replaceChild, swapChild } from "./replace-layout-element.js";
10
+ import { resizeFlexChild, resizeFlexChildren } from "./resize-flex-children.js";
11
+ import { wrap } from "./wrap-layout-element.js";
12
+ const layoutReducer = (state, action)=>{
13
+ switch(action.type){
14
+ case LayoutActionType.ADD:
15
+ return addChild(state, action);
16
+ case LayoutActionType.DRAG_DROP:
17
+ return dragDrop(state, action);
18
+ case "collapse":
19
+ case "expand":
20
+ return setChildProps(state, action);
21
+ case LayoutActionType.REMOVE:
22
+ return removeChild(state, action);
23
+ case LayoutActionType.REPLACE:
24
+ return replaceChild(state, action);
25
+ case LayoutActionType.SET_PROP:
26
+ return setProp(state, action);
27
+ case LayoutActionType.SET_PROPS:
28
+ return setProps(state, action);
29
+ case LayoutActionType.SET_TITLE:
30
+ return setProp(state, {
31
+ type: "set-prop",
32
+ path: action.path,
33
+ propName: "title",
34
+ propValue: action.title
35
+ });
36
+ case LayoutActionType.SPLITTER_RESIZE:
37
+ return resizeFlexChildren(state, action);
38
+ case LayoutActionType.LAYOUT_RESIZE:
39
+ return resizeFlexChild(state, action);
40
+ case LayoutActionType.SWITCH_TAB:
41
+ return switchTab(state, action);
42
+ case LayoutActionType.MOVE_CHILD:
43
+ return moveChild(state, action);
44
+ default:
45
+ return state;
46
+ }
47
+ };
48
+ const switchTab = (state, { path, nextIdx })=>{
49
+ const target = followPath(state, path, true);
50
+ const replacement = react.cloneElement(target, {
51
+ active: nextIdx
52
+ });
53
+ return swapChild(state, target, replacement);
54
+ };
55
+ const setProp = (state, { path, propName, propValue })=>{
56
+ const target = followPath(state, path, true);
57
+ const replacement = react.cloneElement(target, {
58
+ [propName]: propValue
59
+ });
60
+ return swapChild(state, target, replacement);
61
+ };
62
+ const setProps = (state, { path, props })=>{
63
+ const target = followPath(state, path, true);
64
+ const replacement = react.cloneElement(target, props);
65
+ return swapChild(state, target, replacement);
66
+ };
67
+ const setChildProps = (state, { path, type })=>{
68
+ if (!path) return state;
69
+ {
70
+ const target = followPath(state, path, true);
71
+ return swapChild(state, target, target, type);
72
+ }
73
+ };
74
+ const dragDrop = (layoutRoot, action)=>{
75
+ const { draggedReactElement: newComponent, dragInstructions, dropTarget } = action;
76
+ const existingComponent = dropTarget.component;
77
+ const { pos } = dropTarget;
78
+ const destinationTabstrip = pos?.position?.Header && "Stack" === typeOf(existingComponent);
79
+ const { id, version } = getProps(newComponent);
80
+ const intrinsicSize = getIntrinsicSize(newComponent);
81
+ let newLayoutRoot;
82
+ if (destinationTabstrip) {
83
+ const [targetTab, insertionPosition] = getInsertTabBeforeAfter(existingComponent, pos);
84
+ newLayoutRoot = void 0 === targetTab ? insertIntoContainer(layoutRoot, existingComponent, newComponent) : insertBesideChild(layoutRoot, targetTab, newComponent, insertionPosition);
85
+ } else newLayoutRoot = !intrinsicSize && pos?.position?.Centre ? _replaceChild(layoutRoot, existingComponent, newComponent) : dropLayoutIntoContainer(layoutRoot, dropTarget, newComponent);
86
+ if (dragInstructions.DoNotRemove) return newLayoutRoot;
87
+ const finalTarget = findTarget(newLayoutRoot, (props)=>props.id === id && props.version === version);
88
+ const finalPath = getProp(finalTarget, "path");
89
+ return removeChild(newLayoutRoot, {
90
+ path: finalPath,
91
+ type: "remove"
92
+ });
93
+ };
94
+ const addChild = (layoutRoot, { path: containerPath, component })=>insertIntoContainer(layoutRoot, followPath(layoutRoot, containerPath), component);
95
+ const dropLayoutIntoContainer = (layoutRoot, dropTarget, newComponent)=>{
96
+ const { component, pos, clientRect, dropRect } = dropTarget;
97
+ const existingComponent = component;
98
+ const existingComponentPath = getProp(existingComponent, "path");
99
+ if ("0.0" === existingComponentPath) return wrap(layoutRoot, existingComponent, newComponent, pos);
100
+ const targetContainer = followPathToParent(layoutRoot, existingComponentPath);
101
+ if (withTheGrain(pos, targetContainer)) {
102
+ const insertionPosition = pos.position.SouthOrEast ? "after" : "before";
103
+ return insertBesideChild(layoutRoot, existingComponent, newComponent, insertionPosition, pos, clientRect, dropRect);
104
+ }
105
+ if (!withTheGrain(pos, targetContainer)) return wrap(layoutRoot, existingComponent, newComponent, pos, clientRect, dropRect);
106
+ if (isContainer(typeOf(targetContainer))) return wrap(layoutRoot, existingComponent, newComponent, pos);
107
+ throw Error(`no support right now for position = ${pos.position}`);
108
+ };
109
+ const withTheGrain = (pos, container)=>{
110
+ if (pos.position.Centre) return isTerrace(container) || isTower(container);
111
+ return pos.position.NorthOrSouth ? isTower(container) : pos.position.EastOrWest ? isTerrace(container) : false;
112
+ };
113
+ const isTower = (container)=>{
114
+ const { style } = container.props;
115
+ return "Flexbox" === typeOf(container) && "column" === style.flexDirection;
116
+ };
117
+ const isTerrace = (container)=>{
118
+ const { style } = container.props;
119
+ return "Flexbox" === typeOf(container) && "column" !== style.flexDirection;
120
+ };
121
+ export { layoutReducer };
@@ -0,0 +1,34 @@
1
+ const LayoutActionType = {
2
+ ADD: "add",
3
+ DRAG_START: "drag-start",
4
+ DRAG_DROP: "drag-drop",
5
+ LAYOUT_RESIZE: "layout-resize",
6
+ MAXIMIZE: "maximize",
7
+ MINIMIZE: "minimize",
8
+ MOVE_CHILD: "move-child",
9
+ QUERY: "query",
10
+ REMOVE: "remove",
11
+ REPLACE: "replace",
12
+ RESTORE: "restore",
13
+ SET_PROP: "set-prop",
14
+ SET_PROPS: "set-props",
15
+ SET_TITLE: "set-title",
16
+ SPLITTER_RESIZE: "splitter-resize",
17
+ SWITCH_TAB: "switch-tab",
18
+ TEAROUT: "tearout"
19
+ };
20
+ const isApplicationLevelChange = (layoutChangeReason)=>[
21
+ "switch-active-layout",
22
+ "open-layout",
23
+ "close-layout",
24
+ "rename-layout"
25
+ ].includes(layoutChangeReason);
26
+ const isLayoutLevelChange = (layoutChangeReason)=>[
27
+ "switch-active-tab",
28
+ "edit-feature-title",
29
+ "save-feature-props",
30
+ "remove-component",
31
+ "resize-component",
32
+ "drag-drop-operation"
33
+ ].includes(layoutChangeReason);
34
+ export { LayoutActionType, isApplicationLevelChange, isLayoutLevelChange };
@@ -0,0 +1,178 @@
1
+ import { getLayoutComponent, isContainer, isLayoutComponent, uuid } from "@vuu-ui/vuu-utils";
2
+ import react, { cloneElement } from "react";
3
+ import { getPersistentState, hasPersistentState, setPersistentState } from "../use-persistent-state.js";
4
+ import { expandFlex, followPathToParent, getProps, typeOf } from "../utils/index.js";
5
+ const getManagedDimension = (style)=>"column" === style.flexDirection ? [
6
+ "height",
7
+ "width"
8
+ ] : [
9
+ "width",
10
+ "height"
11
+ ];
12
+ const theKidHasNoStyle = {};
13
+ const applyLayoutProps = (component, path = "0")=>{
14
+ const [layoutProps, children] = getChildLayoutProps(typeOf(component), component.props, path);
15
+ return react.cloneElement(component, layoutProps, children);
16
+ };
17
+ const cloneElementAddLayoutProps = (layoutElement, previousLayout)=>{
18
+ const type = typeOf(layoutElement);
19
+ const [layoutProps, children] = getChildLayoutProps(type, layoutElement.props, "0", void 0, previousLayout);
20
+ return cloneElement(layoutElement, layoutProps, children);
21
+ };
22
+ const applyLayout = (type, props, previousLayout)=>{
23
+ const [layoutProps, children] = getChildLayoutProps(type, props, "0", void 0, previousLayout);
24
+ return {
25
+ ...props,
26
+ ...layoutProps,
27
+ type,
28
+ children
29
+ };
30
+ };
31
+ function getLayoutProps(type, props, path = "0", parentType = null, previousLayout) {
32
+ const { active: prevActive = 0, "data-path": dataPath, path: prevPath = dataPath, id: prevId, style: prevStyle } = getProps(previousLayout);
33
+ const prevMatch = typeOf(previousLayout) === type && path === prevPath;
34
+ const id = prevMatch ? prevId : props.id ?? uuid();
35
+ const active = "Stack" === type ? props.active ?? prevActive : void 0;
36
+ const key = id;
37
+ const style = prevMatch ? prevStyle : getStyle(type, props, parentType);
38
+ return isLayoutComponent(type) ? {
39
+ id,
40
+ key,
41
+ path,
42
+ style,
43
+ type,
44
+ active
45
+ } : {
46
+ id,
47
+ key,
48
+ style,
49
+ "data-path": path
50
+ };
51
+ }
52
+ function getChildLayoutProps(type, props, path, parentType = null, previousLayout) {
53
+ const layoutProps = getLayoutProps(type, props, path, parentType, previousLayout);
54
+ if (props.layout && !previousLayout) return [
55
+ layoutProps,
56
+ [
57
+ layoutFromJson(props.layout, `${path}.0`)
58
+ ]
59
+ ];
60
+ const previousChildren = previousLayout?.children ?? previousLayout?.props?.children;
61
+ const hasDynamicChildren = props.dropTarget && previousChildren;
62
+ const children = hasDynamicChildren ? previousChildren : getLayoutChildren(type, props.children, path, previousChildren);
63
+ return [
64
+ layoutProps,
65
+ children
66
+ ];
67
+ }
68
+ function getLayoutChildren(type, children, path = "0", previousChildren) {
69
+ const kids = Array.isArray(children) ? children : react.isValidElement(children) ? [
70
+ children
71
+ ] : [];
72
+ return isContainer(type) ? kids.map((child, i)=>{
73
+ const childType = typeOf(child);
74
+ const previousType = typeOf(previousChildren?.[i]);
75
+ if (!previousType || childType === previousType) {
76
+ const [layoutProps, children] = getChildLayoutProps(childType, child.props, `${path}.${i}`, type, previousChildren?.[i]);
77
+ return react.cloneElement(child, layoutProps, children);
78
+ }
79
+ return previousChildren?.[i];
80
+ }) : children;
81
+ }
82
+ const getStyle = (type, props, parentType)=>{
83
+ let { style = theKidHasNoStyle } = props;
84
+ if ("Flexbox" === type) style = {
85
+ flexDirection: props.column ? "column" : "row",
86
+ ...style,
87
+ display: "flex"
88
+ };
89
+ if (style.flex) {
90
+ const { flex, ...otherStyles } = style;
91
+ style = {
92
+ ...otherStyles,
93
+ ...expandFlex("number" == typeof flex ? flex : 0)
94
+ };
95
+ } else if ("Stack" === parentType) style = {
96
+ ...style,
97
+ ...expandFlex(1)
98
+ };
99
+ else if ("Flexbox" === parentType && (style.width || style.height) && void 0 === style.flexBasis) style = {
100
+ ...style,
101
+ flexBasis: "auto",
102
+ flexGrow: 0,
103
+ flexShrink: 0
104
+ };
105
+ return style;
106
+ };
107
+ function layoutFromJson({ active, id = uuid(), type, children, props, state }, path) {
108
+ const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);
109
+ if (void 0 === componentType) throw Error(`layoutUtils unable to create component from JSON, unknown type ${type}`);
110
+ if (state) setPersistentState(id, state);
111
+ return react.createElement(componentType, {
112
+ active,
113
+ id,
114
+ ...props,
115
+ key: id,
116
+ path
117
+ }, children ? children.map((child, i)=>layoutFromJson(child, `${path}.${i}`)) : void 0);
118
+ }
119
+ function layoutToJSON(component) {
120
+ return componentToJson(component);
121
+ }
122
+ function componentToJson(component) {
123
+ const type = typeOf(component);
124
+ const { id, children, type: _omit, ...props } = getProps(component);
125
+ const state = hasPersistentState(id) ? getPersistentState(id) : void 0;
126
+ return {
127
+ id,
128
+ type,
129
+ props: serializeProps(props),
130
+ state,
131
+ children: react.Children.map(children, componentToJson)
132
+ };
133
+ }
134
+ function serializeProps(props) {
135
+ if (props) {
136
+ const { path, ...otherProps } = props;
137
+ const result = {};
138
+ for (const [key, value] of Object.entries(otherProps))result[key] = serializeValue(value);
139
+ return result;
140
+ }
141
+ }
142
+ function serializeValue(value) {
143
+ if ("string" == typeof value || "number" == typeof value || "boolean" == typeof value) return value;
144
+ if (Array.isArray(value)) return value.map(serializeValue);
145
+ if ("object" == typeof value && null !== value) {
146
+ const result = {};
147
+ for (const [k, v] of Object.entries(value))result[k] = serializeValue(v);
148
+ return result;
149
+ }
150
+ }
151
+ const layoutQuery = (query, path, layoutRoot)=>{
152
+ if (path && layoutRoot) {
153
+ const parentElement = followPathToParent(layoutRoot, path);
154
+ if (parentElement) {
155
+ const { id: parentContainerId } = getProps(parentElement);
156
+ const parentContainerType = typeOf(parentElement);
157
+ return {
158
+ parentContainerId,
159
+ parentContainerType
160
+ };
161
+ }
162
+ return {
163
+ parentContainerType: "Stack",
164
+ parentContainerId: "blah"
165
+ };
166
+ }
167
+ };
168
+ const getDefaultTabLabel = (component, tabIndex, existingLabels = [])=>{
169
+ let label = component.props?.title ?? component.props?.["data-tab-title"] ?? existingLabels[tabIndex];
170
+ if (label) return label;
171
+ {
172
+ let count = tabIndex;
173
+ do label = `Tab ${++count}`;
174
+ while (existingLabels.includes(label))
175
+ return label;
176
+ }
177
+ };
178
+ export { applyLayout, applyLayoutProps, cloneElementAddLayoutProps, componentToJson, getDefaultTabLabel, getManagedDimension, layoutFromJson, layoutQuery, layoutToJSON, serializeProps };
@@ -0,0 +1,18 @@
1
+ import { cloneElement } from "react";
2
+ import { followPath, getProps } from "../utils/index.js";
3
+ import { swapChild } from "./replace-layout-element.js";
4
+ function moveChild(layoutRoot, { fromIndex, path, toIndex }) {
5
+ const target = followPath(layoutRoot, path, true);
6
+ const { children } = getProps(target);
7
+ const replacementChildren = moveChildWithinChildren(children, fromIndex, toIndex);
8
+ const replacement = cloneElement(target, void 0, replacementChildren);
9
+ return swapChild(layoutRoot, target, replacement);
10
+ }
11
+ function moveChildWithinChildren(children, fromIndex, toIndex) {
12
+ const newChildren = children.slice();
13
+ const [child] = newChildren.splice(fromIndex, 1);
14
+ if (-1 === toIndex) return newChildren.concat(child);
15
+ newChildren.splice(toIndex, 0, child);
16
+ return newChildren;
17
+ }
18
+ export { moveChild };