@witchcraft/layout 0.3.0 → 0.4.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 (167) hide show
  1. package/README.md +79 -74
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +6 -1
  4. package/dist/runtime/components/FrameDragHandle.vue +1 -1
  5. package/dist/runtime/components/LayoutDecosEdges.d.vue.ts +15 -0
  6. package/dist/runtime/components/LayoutDecosEdges.vue +34 -0
  7. package/dist/runtime/components/LayoutDecosEdges.vue.d.ts +15 -0
  8. package/dist/runtime/components/LayoutDecosRects.d.vue.ts +15 -0
  9. package/dist/runtime/components/LayoutDecosRects.vue +37 -0
  10. package/dist/runtime/components/LayoutDecosRects.vue.d.ts +15 -0
  11. package/dist/runtime/components/LayoutDragEdgeGrabbed.d.vue.ts +2 -0
  12. package/dist/runtime/components/LayoutDragEdgeGrabbed.vue +43 -0
  13. package/dist/runtime/components/LayoutDragEdgeGrabbed.vue.d.ts +2 -0
  14. package/dist/runtime/components/LayoutDragEdgeHandle.d.vue.ts +9 -0
  15. package/dist/runtime/components/LayoutDragEdgeHandle.vue +44 -0
  16. package/dist/runtime/components/LayoutDragEdgeHandle.vue.d.ts +9 -0
  17. package/dist/runtime/components/{LayoutDecos.d.vue.ts → LayoutDragEdgeVisible.d.vue.ts} +3 -2
  18. package/dist/runtime/components/LayoutDragEdgeVisible.vue +38 -0
  19. package/dist/runtime/components/{LayoutDecos.vue.d.ts → LayoutDragEdgeVisible.vue.d.ts} +3 -2
  20. package/dist/runtime/components/LayoutDragEdges.d.vue.ts +21 -0
  21. package/dist/runtime/components/LayoutDragEdges.vue +67 -0
  22. package/dist/runtime/components/LayoutDragEdges.vue.d.ts +21 -0
  23. package/dist/runtime/components/LayoutEdgesActiveFrame.d.vue.ts +2 -0
  24. package/dist/runtime/components/LayoutEdgesActiveFrame.vue +35 -0
  25. package/dist/runtime/components/LayoutEdgesActiveFrame.vue.d.ts +2 -0
  26. package/dist/runtime/components/LayoutFrame.d.vue.ts +7 -6
  27. package/dist/runtime/components/LayoutFrame.vue +18 -14
  28. package/dist/runtime/components/LayoutFrame.vue.d.ts +7 -6
  29. package/dist/runtime/components/LayoutIntersectionHandle.d.vue.ts +10 -0
  30. package/dist/runtime/components/LayoutIntersectionHandle.vue +36 -0
  31. package/dist/runtime/components/LayoutIntersectionHandle.vue.d.ts +10 -0
  32. package/dist/runtime/components/LayoutIntersectionVisible.d.vue.ts +6 -0
  33. package/dist/runtime/components/LayoutIntersectionVisible.vue +34 -0
  34. package/dist/runtime/components/LayoutIntersectionVisible.vue.d.ts +6 -0
  35. package/dist/runtime/components/LayoutIntersections.d.vue.ts +21 -0
  36. package/dist/runtime/components/LayoutIntersections.vue +52 -0
  37. package/dist/runtime/components/LayoutIntersections.vue.d.ts +21 -0
  38. package/dist/runtime/components/{LayoutShapeSquare.d.vue.ts → LayoutShapeRect.d.vue.ts} +2 -2
  39. package/dist/runtime/components/{LayoutShapeSquare.vue.d.ts → LayoutShapeRect.vue.d.ts} +2 -2
  40. package/dist/runtime/components/LayoutWindow.d.vue.ts +252 -14
  41. package/dist/runtime/components/LayoutWindow.vue +27 -48
  42. package/dist/runtime/components/LayoutWindow.vue.d.ts +252 -14
  43. package/dist/runtime/composables/useFrames.d.ts +859 -2
  44. package/dist/runtime/composables/useFrames.js +2 -0
  45. package/dist/runtime/demo/App.vue +122 -74
  46. package/dist/runtime/demo/DemoControls.vue +7 -5
  47. package/dist/runtime/demo/index.html +12 -0
  48. package/dist/runtime/demo/tailwind.css +1 -1
  49. package/dist/runtime/drag/CloseAction.d.ts +1 -2
  50. package/dist/runtime/drag/CloseAction.js +1 -1
  51. package/dist/runtime/drag/DragActionHandler.d.ts +5 -3
  52. package/dist/runtime/drag/DragActionHandler.js +40 -6
  53. package/dist/runtime/drag/FrameDragAction.js +6 -7
  54. package/dist/runtime/drag/SplitAction.d.ts +1 -2
  55. package/dist/runtime/drag/SplitAction.js +1 -1
  56. package/dist/runtime/drag/createDefaultHandlers.d.ts +1 -1
  57. package/dist/runtime/drag/defaultDragActions.d.ts +1 -1
  58. package/dist/runtime/helpers/consoleDebugWindow.d.ts +43 -0
  59. package/dist/runtime/helpers/consoleDebugWindow.js +222 -0
  60. package/dist/runtime/helpers/convertLayoutWindowToWorkspace.js +2 -2
  61. package/dist/runtime/helpers/framesRedistributeFix.d.ts +87 -0
  62. package/dist/runtime/helpers/framesRedistributeFix.js +54 -0
  63. package/dist/runtime/helpers/getMoveEdgeInfo.d.ts +6 -2
  64. package/dist/runtime/helpers/getMoveEdgeInfo.js +11 -2
  65. package/dist/runtime/helpers/getPinnedEdgesForCollapsedFrames.d.ts +5 -0
  66. package/dist/runtime/helpers/getPinnedEdgesForCollapsedFrames.js +18 -0
  67. package/dist/runtime/helpers/getShapeRectCss.d.ts +7 -0
  68. package/dist/runtime/helpers/{getShapeSquareCss.js → getShapeRectCss.js} +1 -1
  69. package/dist/runtime/helpers/index.d.ts +3 -3
  70. package/dist/runtime/helpers/index.js +3 -3
  71. package/dist/runtime/helpers/moveEdge.js +3 -1
  72. package/dist/runtime/helpers/pxSizeToScaledSize.d.ts +2 -0
  73. package/dist/runtime/helpers/{numberToScaledSize.js → pxSizeToScaledSize.js} +1 -1
  74. package/dist/runtime/helpers/updateWindowSizeWithEvent.d.ts +3 -0
  75. package/dist/runtime/helpers/validateLayoutShape.d.ts +5 -0
  76. package/dist/runtime/helpers/validateLayoutShape.js +28 -0
  77. package/dist/runtime/layout/applyFrameChanges.js +6 -0
  78. package/dist/runtime/layout/createSplitDecoShapes.js +1 -1
  79. package/dist/runtime/layout/getFrameCollapseInfo.d.ts +5 -2
  80. package/dist/runtime/layout/getFrameCollapseInfo.js +16 -46
  81. package/dist/runtime/layout/getFrameDockInfo.d.ts +1 -1
  82. package/dist/runtime/layout/getFrameDockInfo.js +5 -1
  83. package/dist/runtime/layout/getFrameUncollapseInfo.d.ts +5 -2
  84. package/dist/runtime/layout/getFrameUncollapseInfo.js +16 -50
  85. package/dist/runtime/layout/getFramesRedistributeInfo.d.ts +20 -4
  86. package/dist/runtime/layout/getFramesRedistributeInfo.js +31 -2
  87. package/dist/runtime/layout/getRelaxFramesInfo.d.ts +7 -0
  88. package/dist/runtime/layout/getRelaxFramesInfo.js +91 -0
  89. package/dist/runtime/layout/getUpdateWindowSizeInfo.d.ts +13 -0
  90. package/dist/runtime/layout/getUpdateWindowSizeInfo.js +65 -0
  91. package/dist/runtime/layout/index.d.ts +1 -0
  92. package/dist/runtime/layout/index.js +1 -0
  93. package/dist/runtime/layout/resizeFrame.js +1 -3
  94. package/dist/runtime/settings.d.ts +26 -19
  95. package/dist/runtime/settings.js +57 -22
  96. package/dist/runtime/types/index.d.ts +1243 -30
  97. package/dist/runtime/types/index.js +22 -8
  98. package/dist/runtime/types/vue.d.ts +41 -0
  99. package/dist/runtime/{drag/types.js → types/vue.js} +1 -0
  100. package/dist/runtime/utils/cssToKey.d.ts +5 -0
  101. package/dist/runtime/utils/cssToKey.js +3 -0
  102. package/package.json +11 -12
  103. package/src/module.ts +6 -1
  104. package/src/runtime/components/FrameDragHandle.vue +1 -1
  105. package/src/runtime/components/LayoutDecosEdges.vue +38 -0
  106. package/src/runtime/components/LayoutDecosRects.vue +42 -0
  107. package/src/runtime/components/LayoutDragEdgeGrabbed.vue +50 -0
  108. package/src/runtime/components/LayoutDragEdgeHandle.vue +52 -0
  109. package/src/runtime/components/LayoutDragEdgeVisible.vue +45 -0
  110. package/src/runtime/components/LayoutDragEdges.vue +78 -0
  111. package/src/runtime/components/LayoutEdgesActiveFrame.vue +43 -0
  112. package/src/runtime/components/LayoutFrame.vue +22 -15
  113. package/src/runtime/components/LayoutIntersectionHandle.vue +45 -0
  114. package/src/runtime/components/LayoutIntersectionVisible.vue +41 -0
  115. package/src/runtime/components/LayoutIntersections.vue +64 -0
  116. package/src/runtime/components/{LayoutShapeSquare.vue → LayoutShapeRect.vue} +2 -2
  117. package/src/runtime/components/LayoutWindow.vue +29 -49
  118. package/src/runtime/composables/useFrames.ts +7 -2
  119. package/src/runtime/demo/App.vue +128 -78
  120. package/src/runtime/demo/DemoControls.vue +7 -5
  121. package/src/runtime/demo/index.html +12 -0
  122. package/src/runtime/demo/tailwind.css +3 -0
  123. package/src/runtime/drag/CloseAction.ts +2 -3
  124. package/src/runtime/drag/DragActionHandler.ts +48 -10
  125. package/src/runtime/drag/FrameDragAction.ts +4 -5
  126. package/src/runtime/drag/SplitAction.ts +4 -3
  127. package/src/runtime/drag/createDefaultHandlers.ts +2 -1
  128. package/src/runtime/drag/defaultDragActions.ts +2 -1
  129. package/src/runtime/helpers/consoleDebugWindow.ts +331 -0
  130. package/src/runtime/helpers/convertLayoutWindowToWorkspace.ts +2 -2
  131. package/src/runtime/helpers/framesRedistributeFix.ts +162 -0
  132. package/src/runtime/helpers/getMoveEdgeInfo.ts +22 -5
  133. package/src/runtime/helpers/getPinnedEdgesForCollapsedFrames.ts +29 -0
  134. package/src/runtime/helpers/{getShapeSquareCss.ts → getShapeRectCss.ts} +3 -3
  135. package/src/runtime/helpers/index.ts +4 -3
  136. package/src/runtime/helpers/moveEdge.ts +3 -1
  137. package/src/runtime/helpers/{numberToScaledSize.ts → pxSizeToScaledSize.ts} +2 -2
  138. package/src/runtime/helpers/updateWindowSizeWithEvent.ts +3 -0
  139. package/src/runtime/helpers/validateLayoutShape.ts +46 -0
  140. package/src/runtime/layout/applyFrameChanges.ts +5 -0
  141. package/src/runtime/layout/createSplitDecoShapes.ts +1 -1
  142. package/src/runtime/layout/getFrameCollapseInfo.ts +26 -85
  143. package/src/runtime/layout/getFrameDockInfo.ts +8 -1
  144. package/src/runtime/layout/getFrameUncollapseInfo.ts +29 -96
  145. package/src/runtime/layout/getFramesRedistributeInfo.ts +60 -5
  146. package/src/runtime/layout/getRelaxFramesInfo.ts +139 -0
  147. package/src/runtime/layout/getUpdateWindowSizeInfo.ts +105 -0
  148. package/src/runtime/layout/index.ts +1 -0
  149. package/src/runtime/layout/resizeFrame.ts +4 -3
  150. package/src/runtime/settings.ts +78 -25
  151. package/src/runtime/types/index.ts +205 -33
  152. package/src/runtime/types/vue.ts +41 -0
  153. package/src/runtime/utils/cssToKey.ts +8 -0
  154. package/dist/runtime/components/LayoutDecos.vue +0 -26
  155. package/dist/runtime/components/LayoutEdges.d.vue.ts +0 -17
  156. package/dist/runtime/components/LayoutEdges.vue +0 -144
  157. package/dist/runtime/components/LayoutEdges.vue.d.ts +0 -17
  158. package/dist/runtime/drag/types.d.ts +0 -161
  159. package/dist/runtime/helpers/clampNumber.d.ts +0 -1
  160. package/dist/runtime/helpers/clampNumber.js +0 -3
  161. package/dist/runtime/helpers/getShapeSquareCss.d.ts +0 -7
  162. package/dist/runtime/helpers/numberToScaledSize.d.ts +0 -2
  163. package/src/runtime/components/LayoutDecos.vue +0 -28
  164. package/src/runtime/components/LayoutEdges.vue +0 -170
  165. package/src/runtime/drag/types.ts +0 -177
  166. package/src/runtime/helpers/clampNumber.ts +0 -9
  167. /package/dist/runtime/components/{LayoutShapeSquare.vue → LayoutShapeRect.vue} +0 -0
package/README.md CHANGED
@@ -1,6 +1,9 @@
1
- [![Docs](https://github.com/witchcraftjs/layout/workflows/Docs/badge.svg)](https://github.com/witchcraftjs/layout/actions/workflows/docs.yml)
2
- [![Release](https://github.com/witchcraftjs/layout/actions/workflows/release.yml/badge.svg)](https://github.com/witchcraftjs/layout/actions/workflows/release.yml)
3
- [![NPM Version (with latest tag)](https://img.shields.io/npm/v/%40alanscodelog%2FREPONAME/latest)](https://www.npmjs.com/package/@witchcraft/layout/v/latest)
1
+ [![Docs][docs-src]][docs-href]
2
+ [![Release][release-src]][release-href]
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![License][license-src]][license-href]
5
+ [![Nuxt][nuxt-src]][nuxt-href]
6
+
4
7
  # [Docs](https://witchcraftjs.github.io/layout)
5
8
  # [Demo](https://witchcraftjs.github.io/layout/demo)
6
9
 
@@ -135,10 +138,8 @@ settings.minSize = 5 (5%)
135
138
  There are utilities for converting between non-scaled and scaled values if you need to:
136
139
 
137
140
  ```ts
138
- import {
139
- numberToScaledSize,
140
- numverToScaledPercent
141
- } from "@witchcraft-layout/helpers/numberToScaledSize.js"
141
+ import { numberToScaledPercent } from "@witchcraft-layout/helpers/numberToScaledSize.js"
142
+ import { pxSizeToScaledSize } from "@witchcraft-layout/helpers/pxSizeToScaledSize.js"
142
143
 
143
144
  /* -----------
144
145
  * | * |
@@ -162,9 +163,9 @@ import {reactive} from "vue"
162
163
  export const layout = ref(layoutCreate())
163
164
  ```
164
165
 
165
- Then in the page with the layout, initialize it and add a component to handle the rendering. One is included for vue, but it's pretty simple.
166
+ Then in the page with the layout, initialize it and add a component to handle the rendering. One is included for vue with composability but you can do something simpler if needed.
166
167
 
167
- It uses a flat structure insides like so, so edges are always on top of frames, and decorations (drag/drop) are always on top of edges:
168
+ The component should render to a flat structure inside like so, so edges are always on top of frames, and decorations (drag/drop) are always on top of edges:
168
169
  ```
169
170
  - LayoutWindow
170
171
  - LayoutFrame
@@ -173,7 +174,7 @@ It uses a flat structure insides like so, so edges are always on top of frames,
173
174
  - LayoutDecos
174
175
  ```
175
176
 
176
- Edges and Decos are very simple and there are various utilies like `getVisualEdgesCss` and `getShapeSquareCss` to create the css needed to display them. They can both be handled as squares making it easy to reuse a single component to render them.
177
+ Edges and Decos are very simple and there are various utilies like `getVisualEdgesCss` and `getShapeRectCss` to create the css needed to display them. They can both be handled as rects making it easy to reuse a single component to render them.
177
178
 
178
179
  This has the benefit for edges, that the grabable area can be easily adjusted and bigger than the displayed edge.
179
180
 
@@ -372,25 +373,64 @@ requestAnimationFrame(() => {
372
373
 
373
374
  ## LayoutWindow
374
375
 
375
- This is the main component that can render and handle dragging.
376
+ This is the main component that provides context and handles dragging. It takes care of updating the size/pos of the window on mount.
377
+
378
+ `LayoutWindow` does not render frames, edges, or decorations internally. You explicitly place each component inside it, which lets you override styles, add props, or wrap individual components.
379
+
380
+ ### Customizing
381
+
382
+ You can add props/classes to most components directly except for LayoutDragEdges and LayoutIntersections as they are loops and contain two components per edge/intersection. For those you must use slots
383
+
384
+ This is so you can have a bigger invisible handle for pointer events, and a small visible indicator which by default only shows when the handle is hovered over (in the dom they are ordered like siblings: handle, visible, handle, visible, etc). You can control their size via css variables, see below.
385
+
386
+ ```vue
387
+ <LayoutDragEdges>
388
+ <template #handle="slotProps">
389
+ <LayoutDragEdgeHandle class="..." v-bind="slotProps" />
390
+ </template>
391
+ <template #indicator="slotProps">
392
+ <LayoutDragEdgeVisible class="..." v-bind="slotProps" />
393
+ </template>
394
+ </LayoutDragEdges>
395
+
396
+ <LayoutIntersections>
397
+ <template #handler="slotProps">
398
+ <LayoutIntersectionHandle class="..." v-bind="slotProps" />
399
+ </template>
400
+ <template #indicator="slotProps">
401
+ <LayoutIntersectionVisible class="..." v-bind="slotProps" />
402
+ </template>
403
+ </LayoutIntersections>
404
+ ```
405
+ ### CSS Variables
406
+
407
+ They are all called width but apply both to width and height.
376
408
 
377
- The component takes care of updating the size/pos of the window on mount.
409
+ - `--layoutHandleWidth`: for both edges and intersections
410
+ - `--layoutEdgeWidth`: visible edge width
411
+ - `--layoutSplitEdgeWidth` : drag split edge width
412
+ - `--layoutIntersectionWidth` : visible intersection width
378
413
 
379
- It also includes basic styles for the edges and decos.
414
+ ### CSS Classes
380
415
 
381
- The order and styles classes look like this:
416
+ There are more classes defined internally than this that you can target, but usually what you'll want to style are the following:
382
417
 
383
- - `.frame` - frames come first so that edges can be rendered on top of them when needed.
418
+ - LayoutWindow - has "state" classes so you can do stuff like target an edge during an event `.request-split .drag-edge`.
419
+ - `.dragging`
420
+ - `.request-split`
421
+ - `.request-close`
422
+ - `.request-frame-drag`
423
+ - LayoutEdgesActiveFrame (`.active-frame-edge`) - active frame outline, rendered as a single div
424
+ - LayoutDragEdgeHandle (`.drag-edge`) - thicker invisible handle for pointer events
425
+ - LayoutDragEdgeVisible (`.visible-drag-edge`) - visible edge
426
+ - LayoutDragEdgeGrabbed (`.drag-edge-grabbed`) - the grabbed edge while dragging
427
+ - LayoutIntersectionHandle (`.drag-intersection`) - clickable intersection handle
428
+ - LayoutIntersectionVisible (`.drag-intersection-visible`) - visible intersection
384
429
 
385
- Edges are stacked in this order.
430
+ If you need to target the visible edge when it's handle is hovered, you can do the following:
386
431
 
387
- - `.active-frame-edge` (active frame - rendered as single div)
388
- - `.drag-edge` (thicker edge for attaching pointer events) + sibling .edge
389
- - It looks like `.drag-edge .edge .drag-edge .edge` and so on.
390
- - `.edge` is not shown by default, instead frames are padded to let the background show through since that way we can support having rounded corners inside the frames.
391
- - This is you can target the edge style on the drag-edge's hover: `.drag-edge:hover+.edge`
392
- - `.grabbed-edge` (the grabbed drag edge if any) - prefer this over drag-edge:hover for css that should remain visible when dragging to avoid flickering when the mouse moves slightly off the edge
393
- - `.intersection` (intersections)
432
+ `.drag-intersection:hover+.drag-intersection-visible`
433
+ `.drag-edge:hover+.visible-drag-edge`
394
434
 
395
435
  **ALL edges except `active-frame-edge` are rendered as individual divs, so set the background color instead of the border.**
396
436
 
@@ -398,7 +438,9 @@ This is done like this for several reasons:
398
438
  - Edges can be shared by frames, only the active edges are guaranteed to equal some frame's edges. And we need to know the full edge that is being dragged to implement dragging.
399
439
  - The css/logic is simpler, edges can be any width without affecting the layout. We just transform translate them to be exactly centered over their position and then just pad the frames the correct amount.
400
440
 
401
- Decos:
441
+ #### Decos
442
+
443
+ Action handlers add these internally to the corresponding `LayoutDecosRects/Edges` components.
402
444
 
403
445
  - Close:
404
446
  - `.deco-close-frame` (close frame preview)
@@ -413,56 +455,9 @@ Decos:
413
455
  - `.deco-frame-drag-${type}-${side}` (e.g. `.deco-frame-drag-frame-left`, `.deco-frame-drag-zone-right`)
414
456
 
415
457
 
416
- State classes (so you can do stuff like `.request-split .drag-edge`)
417
- - `.dragging`
418
- - `.request-split`
419
- - `.request-close`
420
- - `.request-frame-drag`
421
-
422
- Several css variables are provided to help with sizing:
423
- - `--layoutHandleWidth`
424
- - `--layoutEdgeWidth`
425
- - `--layoutSplitEdgeWidth`
426
- - `--layoutIntersectionWidth`
427
-
428
- ```vue
429
- <template>
430
-
431
- <LayoutWindow
432
- v-if="win"
433
- class="flex-1 w-full
434
- // hide drag/grabbed edge when splitting (let only split edge show)
435
- [&.request-split_.grabbed-edge]:hidden
436
- [&.request-split_.drag-edge]:hidden
437
- "
438
- style="--layoutSplitEdgeWidth:2px;"
439
- :win="win"
440
- >
441
- <template #[`frame-${f.id}`] v-for="f in frames" :key="f.id">
442
- <ContentFrame
443
- :frame="f"
444
- :get-component="getComponent"
445
- />
446
- </template>
447
- </LayoutWindow>
448
- </template>
449
-
450
- <script setup lang="ts">
451
- const {
452
- layout,
453
- activeWindow: win,
454
- activeFrame,
455
- frames
456
- } = storeToRefs(useLayoutStore())
457
-
458
- function getComponent(type: string | undefined) {
459
- if (type === "contentA") {
460
- return yourContentAComponent
461
- }
462
- }
458
+ #### Other
459
+ See also the [demo code](https://github.com/witchcraftjs/layout/blob/main/src/runtime/demo/App.vue).
463
460
 
464
- </script>
465
- ```
466
461
  ## Nuxt w/ Tailwind
467
462
 
468
463
  The nuxt module creates a `witchcraft-layout.css` file with the proper source imports for the components folder. You just have to import it in your tailwind css file. Note that this requires `@witchcraft/ui` be installed and setup in a similar way also.
@@ -475,4 +470,14 @@ The nuxt module creates a `witchcraft-layout.css` file with the proper source im
475
470
  @import "../../../.nuxt/witchcraft-layout.css";
476
471
  ```
477
472
 
478
-
473
+ <!-- Badges -->
474
+ [docs-src]: https://github.com/witchcraftjs/layout/actions/workflows/docs.yml/badge.svg
475
+ [docs-href]: https://github.com/witchcraftjs/layout/actions/workflows/docs.yml
476
+ [release-src]: https://github.com/witchcraftjs/layout/actions/workflows/release.yml/badge.svg
477
+ [release-href]: https://github.com/witchcraftjs/layout/actions/workflows/release.yml
478
+ [npm-version-src]: https://img.shields.io/npm/v/@witchcraft/layout/latest
479
+ [npm-version-href]: https://www.npmjs.com/package/@witchcraft/layout/v/latest
480
+ [license-src]: https://img.shields.io/npm/l/@witchcraft/layout.svg?style=flat&colorA=020420&colorB=00DC82
481
+ [license-href]: https://npmjs.com/package/@witchcraft/layout
482
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
483
+ [nuxt-href]: https://nuxt.com
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@witchcraft/layout",
3
3
  "configKey": "witchcraftLayout",
4
- "version": "0.3.0",
4
+ "version": "0.4.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -17,7 +17,12 @@ const module$1 = defineNuxtModule({
17
17
  addTemplate({
18
18
  filename: "witchcraft-layout.css",
19
19
  write: true,
20
- getContents: () => `@source "${resolve("runtime/components")}";`
20
+ getContents: () => [
21
+ `@source "${resolve("runtime/components")}";`,
22
+ // the drag actions handlers and utils they use add some styles
23
+ `@source "${resolve("runtime/drag")}";`,
24
+ `@source "${resolve("runtime/utils/createSplitDecoShapes")}";`
25
+ ].join("\n")
21
26
  });
22
27
  nuxt.options.alias["#witchcraft-layout"] = resolve("runtime");
23
28
  }
@@ -9,7 +9,7 @@
9
9
 
10
10
  <script setup>
11
11
  import { inject, onBeforeUnmount } from "vue";
12
- import { dragContextInjectionKey } from "../drag/types.js";
12
+ import { dragContextInjectionKey } from "../types/vue.js";
13
13
  const props = defineProps({
14
14
  frameId: { type: String, required: true }
15
15
  });
@@ -0,0 +1,15 @@
1
+ declare var __VLS_1: {
2
+ shape: any;
3
+ css: any;
4
+ };
5
+ type __VLS_Slots = {} & {
6
+ edge?: (props: typeof __VLS_1) => any;
7
+ };
8
+ declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
9
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <template
3
+ v-for="(shape, i) of ctx.shapes.filter((_) => _.type === 'edge')"
4
+ :key="cssToKey(shape.data)"
5
+ >
6
+
7
+ <slot
8
+ name="edge"
9
+ v-bind="{
10
+ shape,
11
+ css: getVisualEdgeCss(shape.data, { padLongAxis: 'var(--layoutEdgeWidth,2px)' })
12
+ }"
13
+ >
14
+ <LayoutShapeRect
15
+ :css="getVisualEdgeCss(shape.data, { padLongAxis: 'var(--layoutEdgeWidth,2px)' })"
16
+ :class="twMerge(shape.attrs?.class, $attrs.class)"
17
+ v-bind="{ ...shape.attrs, ...$attrs, class: void 0 }"
18
+
19
+ />
20
+ </slot>
21
+ </template>
22
+ </template>
23
+
24
+ <script setup>
25
+ import LayoutShapeRect from "./LayoutShapeRect.vue";
26
+ import { getVisualEdgeCss } from "../helpers/getVisualEdgeCss";
27
+ import { layoutContextInjectionKey } from "../types/vue.js";
28
+ import { useAttrs, inject } from "vue";
29
+ import { cssToKey } from "../utils/cssToKey.js";
30
+ import { twMerge } from "@witchcraft/ui/utils/twMerge";
31
+ const $attrs = useAttrs();
32
+ const ctx = inject(layoutContextInjectionKey, void 0);
33
+ if (!ctx) throw new Error("LayoutEdges must be used within a LayoutWindow");
34
+ </script>
@@ -0,0 +1,15 @@
1
+ declare var __VLS_1: {
2
+ shape: any;
3
+ css: any;
4
+ };
5
+ type __VLS_Slots = {} & {
6
+ edge?: (props: typeof __VLS_1) => any;
7
+ };
8
+ declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
9
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,15 @@
1
+ declare var __VLS_1: {
2
+ shape: any;
3
+ css: any;
4
+ };
5
+ type __VLS_Slots = {} & {
6
+ rect?: (props: typeof __VLS_1) => any;
7
+ };
8
+ declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
9
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,37 @@
1
+ <template>
2
+ <template
3
+ v-for="(shape) of ctx.shapes.filter((_) => _.type === 'rect')"
4
+ :key="cssToKey(shape.data)"
5
+ >
6
+ <slot
7
+ name="rect"
8
+ v-bind="{
9
+ shape,
10
+ css: getShapeRectCss(shape.data, `var(--layoutEdgeWidth,2px)`)
11
+ }"
12
+ >
13
+ <LayoutShapeRect
14
+ v-if="shape.type === 'rect'"
15
+ :css="getShapeRectCss(shape.data, `var(--layoutEdgeWidth,2px)`)"
16
+ :class="twMerge(`bg-neutral-500/20`, shape.attrs?.class, $attrs.class)"
17
+ v-bind="{ ...shape.attrs, ...$attrs, class: void 0 }"
18
+ />
19
+ </slot>
20
+
21
+ </template>
22
+ </template>
23
+
24
+ <script setup>
25
+ import LayoutShapeRect from "./LayoutShapeRect.vue";
26
+ import { getShapeRectCss } from "../helpers/getShapeRectCss";
27
+ import { layoutContextInjectionKey } from "../types/vue.js";
28
+ import { useAttrs, inject } from "vue";
29
+ import { cssToKey } from "../utils/cssToKey.js";
30
+ import { twMerge } from "@witchcraft/ui/utils/twMerge";
31
+ const $attrs = useAttrs();
32
+ defineOptions({
33
+ inheritAttrs: false
34
+ });
35
+ const ctx = inject(layoutContextInjectionKey, void 0);
36
+ if (!ctx) throw new Error("LayoutEdges must be used within a LayoutWindow");
37
+ </script>
@@ -0,0 +1,15 @@
1
+ declare var __VLS_1: {
2
+ shape: any;
3
+ css: any;
4
+ };
5
+ type __VLS_Slots = {} & {
6
+ rect?: (props: typeof __VLS_1) => any;
7
+ };
8
+ declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
9
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ export default _default;
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <LayoutShapeRect
3
+ :css="css"
4
+ :class="twMerge(
5
+ `
6
+ drag-edge-grabbed
7
+ z-20
8
+ bg-accent-500
9
+ cursor-pointer
10
+ [&.request-split]:hidden
11
+ `,
12
+ $attrs.class
13
+ )"
14
+ v-bind="{ ...$attrs, class: void 0 }"
15
+ v-for="css, i of cssDragEdge"
16
+ :key="cssToKey(css)"
17
+ />
18
+ </template>
19
+
20
+ <script setup>
21
+ import { dragContextInjectionKey, layoutContextInjectionKey } from "../types/vue.js";
22
+ import { twMerge } from "@witchcraft/ui/utils/twMerge";
23
+ import { computed, inject, useAttrs } from "vue";
24
+ import LayoutShapeRect from "./LayoutShapeRect.vue";
25
+ import { getVisualEdgesCss } from "../helpers/getVisualEdgesCss.js";
26
+ import { cssToKey } from "../utils/cssToKey.js";
27
+ const $attrs = useAttrs();
28
+ defineOptions({
29
+ inheritAttrs: false
30
+ });
31
+ const ctx = inject(layoutContextInjectionKey, void 0);
32
+ if (!ctx) throw new Error("LayoutEdges must be used within a LayoutWindow");
33
+ const dragCtx = inject(dragContextInjectionKey, void 0);
34
+ if (!dragCtx) throw new Error("LayoutEdges must be used within a LayoutWindow");
35
+ const draggingEdge = computed(() => dragCtx.draggingEdges.value.length === 1 ? dragCtx.draggingEdges.value[0] : void 0);
36
+ const cssDragEdge = computed(() => {
37
+ if (!draggingEdge.value) return [];
38
+ return getVisualEdgesCss([draggingEdge.value], {
39
+ edgeWidth: `var(--layoutEdgeWidth, 2px)`,
40
+ padLongAxis: `(var(--layoutEdgeWidth, 2px) + var(--layoutExtraDragEdgePadding, 0px))`
41
+ });
42
+ });
43
+ </script>
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import { type EdgeDragStartData } from "../types/index.js";
2
+ import type { Edge, EdgeCss } from "../types/index.js";
3
+ type __VLS_Props = {
4
+ edge: Edge;
5
+ css: EdgeCss;
6
+ onPointerDown?: (e: PointerEvent, type: "edge", data: EdgeDragStartData) => void;
7
+ };
8
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <LayoutShapeRect
3
+ :css="css"
4
+ :title="edge.error?.message"
5
+ :class="twMerge(
6
+ `
7
+ drag-edge
8
+ z-20
9
+ hover:cursor-pointer
10
+
11
+ [&.request-split]:hidden
12
+ `,
13
+ edge.error && `
14
+ drag-edge-errored
15
+ hover:cursor-not-allowed
16
+ `,
17
+ $attrs.class
18
+ )"
19
+ v-bind="{ ...$attrs, class: void 0 }"
20
+ @pointerdown="onPointerDown?.($event, 'edge', { edge })"
21
+ />
22
+ </template>
23
+
24
+ <script setup>
25
+ import { layoutContextInjectionKey } from "../types/vue.js";
26
+ import { twMerge } from "@witchcraft/ui/utils/twMerge";
27
+ import { useAttrs, inject } from "vue";
28
+ import LayoutShapeRect from "./LayoutShapeRect.vue";
29
+ import {} from "../types/index.js";
30
+ import { dragContextInjectionKey } from "../types/vue.js";
31
+ const $attrs = useAttrs();
32
+ defineOptions({
33
+ inheritAttrs: false
34
+ });
35
+ const props = defineProps({
36
+ edge: { type: null, required: true },
37
+ css: { type: Object, required: true },
38
+ onPointerDown: { type: Function, required: false }
39
+ });
40
+ const ctx = inject(layoutContextInjectionKey, void 0);
41
+ if (!ctx) throw new Error("LayoutEdges must be used within a LayoutWindow");
42
+ const dragCtx = inject(dragContextInjectionKey, void 0);
43
+ if (!dragCtx) throw new Error("LayoutEdges must be used within a LayoutWindow");
44
+ </script>
@@ -0,0 +1,9 @@
1
+ import { type EdgeDragStartData } from "../types/index.js";
2
+ import type { Edge, EdgeCss } from "../types/index.js";
3
+ type __VLS_Props = {
4
+ edge: Edge;
5
+ css: EdgeCss;
6
+ onPointerDown?: (e: PointerEvent, type: "edge", data: EdgeDragStartData) => void;
7
+ };
8
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -1,6 +1,7 @@
1
- import type { LayoutShape } from "../types/index.js";
1
+ import { type Edge, type EdgeCss } from "../types/index.js";
2
2
  type __VLS_Props = {
3
- shapes: LayoutShape[];
3
+ edge: Edge;
4
+ css: EdgeCss;
4
5
  };
5
6
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
7
  export default _default;
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <LayoutShapeRect
3
+ :class="twMerge(
4
+ `
5
+ visible-drag-edge
6
+ pointer-events-none
7
+ [.drag-edge:hover+&]:bg-accent-500/60
8
+ `,
9
+ edge.error && `
10
+ visible-drag-edge-errored
11
+ [.drag-edge:hover+&]:bg-red-500/50
12
+ [.drag-edge:hover+&]:cursor-not-allowed
13
+
14
+ `,
15
+ $attrs.class
16
+ )"
17
+ :css="css"
18
+ v-bind="{ ...$attrs, class: void 0 }"
19
+ />
20
+ </template>
21
+
22
+ <script setup>
23
+ import { twMerge } from "@witchcraft/ui/utils/twMerge";
24
+ import { useAttrs, inject } from "vue";
25
+ import LayoutShapeRect from "./LayoutShapeRect.vue";
26
+ import {} from "../types/index.js";
27
+ import { layoutContextInjectionKey } from "../types/vue.js";
28
+ const $attrs = useAttrs();
29
+ defineOptions({
30
+ inheritAttrs: false
31
+ });
32
+ defineProps({
33
+ edge: { type: null, required: true },
34
+ css: { type: Object, required: true }
35
+ });
36
+ const ctx = inject(layoutContextInjectionKey, void 0);
37
+ if (!ctx) throw new Error("LayoutEdges must be used within a LayoutWindow");
38
+ </script>
@@ -1,6 +1,7 @@
1
- import type { LayoutShape } from "../types/index.js";
1
+ import { type Edge, type EdgeCss } from "../types/index.js";
2
2
  type __VLS_Props = {
3
- shapes: LayoutShape[];
3
+ edge: Edge;
4
+ css: EdgeCss;
4
5
  };
5
6
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
7
  export default _default;
@@ -0,0 +1,21 @@
1
+ declare var __VLS_1: {
2
+ css: any;
3
+ edge: any;
4
+ onPointerDown: any;
5
+ }, __VLS_10: {
6
+ css: any;
7
+ edge: any;
8
+ };
9
+ type __VLS_Slots = {} & {
10
+ handle?: (props: typeof __VLS_1) => any;
11
+ } & {
12
+ indicator?: (props: typeof __VLS_10) => any;
13
+ };
14
+ declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
15
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <template
3
+ v-for="css, i in cssDragEdges"
4
+ :key="cssToKey(css.handle)"
5
+ >
6
+ <slot name="handle" v-bind="{
7
+ css: css.handle,
8
+ edge: visualEdges[i],
9
+ onPointerDown: dragCtx.dragStart
10
+ }">
11
+ <LayoutDragEdgeHandle
12
+ :css="css.handle"
13
+ :edge="visualEdges[i]"
14
+ @pointerdown="dragCtx.dragStart"
15
+ />
16
+ </slot>
17
+ <slot name="indicator" v-bind="{
18
+ css: css.visible,
19
+ edge: visualEdges[i]
20
+ }">
21
+ <LayoutDragEdgeVisible
22
+ :edge="visualEdges[i]"
23
+ :css="css.visible"
24
+ />
25
+ </slot>
26
+ </template>
27
+ </template>
28
+
29
+ <script setup>
30
+ import { layoutContextInjectionKey } from "../types/vue.js";
31
+ import { computed, inject } from "vue";
32
+ import LayoutDragEdgeHandle from "./LayoutDragEdgeHandle.vue";
33
+ import LayoutDragEdgeVisible from "./LayoutDragEdgeVisible.vue";
34
+ import { getVisualEdgesCss } from "../helpers/getVisualEdgesCss.js";
35
+ import { isEdgeEqual } from "../helpers/isEdgeEqual.js";
36
+ import { toRef } from "vue";
37
+ import { cssToKey } from "../utils/cssToKey.js";
38
+ import {} from "../types/index.js";
39
+ import { dragContextInjectionKey } from "../types/vue.js";
40
+ defineOptions({
41
+ inheritAttrs: false
42
+ });
43
+ const ctx = inject(layoutContextInjectionKey, void 0);
44
+ if (!ctx) throw new Error("LayoutEdges must be used wivisible a LayoutWindow");
45
+ const dragCtx = inject(dragContextInjectionKey, void 0);
46
+ if (!dragCtx) throw new Error("LayoutEdges must be used within a LayoutWindow");
47
+ const visualEdges = toRef(dragCtx, "visualEdges");
48
+ const draggingEdge = computed(() => dragCtx.draggingEdges.value.length === 1 ? dragCtx.draggingEdges.value[0] : void 0);
49
+ const cssDragEdges = computed(() => {
50
+ const handleEdges = getVisualEdgesCss(
51
+ draggingEdge.value ? dragCtx.visualEdges.value.filter((_) => !isEdgeEqual(draggingEdge.value, _)) : dragCtx.visualEdges.value,
52
+ {
53
+ edgeWidth: `var(--layoutHandleWidth, 8px)`,
54
+ padLongAxis: `var(--layoutEdgeWidth, 2px)`
55
+ }
56
+ );
57
+ const visibleEdges = getVisualEdgesCss(dragCtx.visualEdges.value, {
58
+ edgeWidth: `var(--layoutEdgeWidth, 2px)`,
59
+ padLongAxis: `(var(--layoutEdgeWidth, 2px) + var(--layoutExtraDragEdgePadding, 0px))`
60
+ });
61
+ const edges = [];
62
+ for (let i = 0; i < handleEdges.length; i++) {
63
+ edges.push({ visible: visibleEdges[i], handle: handleEdges[i] });
64
+ }
65
+ return edges;
66
+ });
67
+ </script>