@blokkli/editor 2.0.0-alpha.16 → 2.0.0-alpha.18

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 (194) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +640 -137
  3. package/dist/modules/drupal/graphql/base/fragment.blokkliProps.graphql +1 -1
  4. package/dist/modules/drupal/graphql/base/fragment.paragraphsFieldItem.graphql +3 -1
  5. package/dist/modules/drupal/graphql/base/query.pbConfig.graphql +1 -10
  6. package/dist/modules/drupal/graphql/features/comments.graphql +11 -8
  7. package/dist/modules/drupal/graphql/mutations/set_paragraph_schedule.graphql +15 -0
  8. package/dist/modules/drupal/index.mjs +33 -0
  9. package/dist/modules/drupal/runtime/adapter/index.js +12 -4
  10. package/dist/runtime/adapter/index.d.ts +21 -0
  11. package/dist/runtime/blokkliPlugins/ContextMenu/Menu/index.vue +3 -0
  12. package/dist/runtime/blokkliPlugins/ItemAction/index.vue +23 -15
  13. package/dist/runtime/blokkliPlugins/ItemAction/index.vue.d.ts +20 -44
  14. package/dist/runtime/blokkliPlugins/TourItem/index.vue +10 -5
  15. package/dist/runtime/components/Blocks/FromLibrary/index.vue +4 -2
  16. package/dist/runtime/components/BlokkliEditable.vue +32 -14
  17. package/dist/runtime/components/BlokkliField.vue +3 -0
  18. package/dist/runtime/components/BlokkliField.vue.d.ts +3 -3
  19. package/dist/runtime/components/BlokkliItem.vue +1 -1
  20. package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
  21. package/dist/runtime/components/BlokkliProvider.vue +41 -28
  22. package/dist/runtime/components/BlokkliProvider.vue.d.ts +2 -1
  23. package/dist/runtime/components/Edit/Actions/index.vue +36 -20
  24. package/dist/runtime/components/Edit/AnimationCanvas/index.vue +436 -25
  25. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +83 -0
  26. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue.d.ts +32 -0
  27. package/dist/runtime/components/Edit/Banner/index.vue +51 -0
  28. package/dist/runtime/components/Edit/Banner/index.vue.d.ts +18 -0
  29. package/dist/runtime/components/Edit/Dialog/index.vue +6 -4
  30. package/dist/runtime/components/Edit/DraggableList.vue +15 -7
  31. package/dist/runtime/components/Edit/DraggableList.vue.d.ts +5 -5
  32. package/dist/runtime/components/Edit/EditIndicator.vue +118 -44
  33. package/dist/runtime/components/Edit/EditIndicator.vue.d.ts +3 -0
  34. package/dist/runtime/components/Edit/EditProvider.vue +101 -31
  35. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +3 -0
  36. package/dist/runtime/components/Edit/Features/AddList/index.vue +9 -11
  37. package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +28 -26
  38. package/dist/runtime/components/Edit/Features/Analyze/Renderer.vue +1 -1
  39. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +15 -11
  40. package/dist/runtime/components/Edit/Features/Anchors/Renderer.vue +19 -102
  41. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +3 -0
  42. package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +29 -53
  43. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue +154 -0
  44. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue.d.ts +27 -0
  45. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +222 -0
  46. package/dist/runtime/components/Edit/Features/{Selection/AddButtons/AddButtonsField.vue.d.ts → BlockScheduler/Dialog/index.vue.d.ts} +6 -9
  47. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +96 -0
  48. package/dist/runtime/components/Edit/Features/Clipboard/index.vue +15 -16
  49. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +51 -0
  50. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/{Group → Item}/index.vue.d.ts +9 -13
  51. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +46 -66
  52. package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +2 -0
  53. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue +35 -20
  54. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue.d.ts +5 -3
  55. package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue +29 -0
  56. package/dist/runtime/components/Edit/Features/{Publish/Dialog/ScheduleDate.vue.d.ts → Comments/CommentInput/index.vue.d.ts} +2 -2
  57. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue +22 -16
  58. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue.d.ts +1 -0
  59. package/dist/runtime/components/Edit/Features/Comments/Overlay/index.vue +15 -6
  60. package/dist/runtime/components/Edit/Features/Comments/index.vue +21 -9
  61. package/dist/runtime/components/Edit/Features/Conversions/index.vue +4 -7
  62. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +26 -35
  63. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue +240 -0
  64. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue.d.ts +6 -0
  65. package/dist/runtime/components/Edit/Features/Debug/index.vue +7 -165
  66. package/dist/runtime/components/Edit/Features/Delete/index.vue +1 -1
  67. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +14 -6
  68. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +55 -48
  69. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +30 -18
  70. package/dist/runtime/components/Edit/Features/Duplicate/index.vue +6 -8
  71. package/dist/runtime/components/Edit/Features/Edit/index.vue +16 -22
  72. package/dist/runtime/components/Edit/Features/EditForm/index.vue +7 -6
  73. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +69 -4
  74. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue.d.ts +2 -2
  75. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Plaintext/index.vue +13 -9
  76. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +45 -87
  77. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue.d.ts +2 -2
  78. package/dist/runtime/components/Edit/Features/EditableField/index.vue +41 -43
  79. package/dist/runtime/components/Edit/Features/Fragments/Dialog/index.vue +11 -9
  80. package/dist/runtime/components/Edit/Features/Fragments/index.vue +3 -3
  81. package/dist/runtime/components/Edit/Features/History/index.vue +5 -2
  82. package/dist/runtime/components/Edit/Features/Hover/Overlay/fragment.glsl +139 -0
  83. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +261 -0
  84. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue.d.ts +6 -0
  85. package/dist/runtime/components/Edit/Features/Hover/Overlay/vertex.glsl +117 -0
  86. package/dist/runtime/components/Edit/Features/Hover/index.vue +25 -0
  87. package/dist/runtime/components/Edit/Features/Hover/index.vue.d.ts +2 -0
  88. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +5 -7
  89. package/dist/runtime/components/Edit/Features/Library/LibraryDialog/index.vue +19 -27
  90. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +32 -28
  91. package/dist/runtime/components/Edit/Features/Library/index.vue +28 -23
  92. package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +6 -3
  93. package/dist/runtime/components/Edit/Features/MediaLibrary/index.vue +15 -12
  94. package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +36 -29
  95. package/dist/runtime/components/Edit/Features/MultiSelect/index.vue +2 -4
  96. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +6 -1
  97. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +8 -6
  98. package/dist/runtime/components/Edit/Features/Options/index.vue +6 -6
  99. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue +35 -0
  100. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue.d.ts +6 -0
  101. package/dist/runtime/components/Edit/Features/Ownership/index.vue +7 -25
  102. package/dist/runtime/components/Edit/Features/ProxyView/index.vue +5 -1
  103. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +68 -15
  104. package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +15 -15
  105. package/dist/runtime/components/Edit/Features/Search/index.vue +4 -1
  106. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +39 -74
  107. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +7 -5
  108. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/fragment.glsl +106 -0
  109. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +440 -0
  110. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue.d.ts +32 -0
  111. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/vertex.glsl +102 -0
  112. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +53 -125
  113. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue.d.ts +2 -2
  114. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +88 -29
  115. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +5 -3
  116. package/dist/runtime/components/Edit/Features/Selection/Overlay/vertex.glsl +11 -2
  117. package/dist/runtime/components/Edit/Features/Selection/OverlayFallback/index.vue +2 -2
  118. package/dist/runtime/components/Edit/Features/Selection/index.vue +66 -39
  119. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +2 -2
  120. package/dist/runtime/components/Edit/Features/Structure/List/Item/index.vue +13 -6
  121. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +3 -0
  122. package/dist/runtime/components/Edit/Features/Transform/index.vue +2 -27
  123. package/dist/runtime/components/Edit/Features/Translations/Banner/index.vue +17 -11
  124. package/dist/runtime/components/Edit/Features/Translations/index.vue +20 -23
  125. package/dist/runtime/components/Edit/Features/Validations/SidebarItem/index.vue +5 -5
  126. package/dist/runtime/components/Edit/Features/index.vue +17 -7
  127. package/dist/runtime/components/Edit/Form/Text/index.vue +2 -1
  128. package/dist/runtime/components/Edit/Form/Text/index.vue.d.ts +1 -0
  129. package/dist/runtime/components/Edit/Form/Toggle/index.vue +4 -3
  130. package/dist/runtime/components/Edit/Form/Toggle/index.vue.d.ts +12 -2
  131. package/dist/runtime/components/Edit/Indicators/index.vue +1 -1
  132. package/dist/runtime/components/Edit/InfoBox/index.vue +6 -2
  133. package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +12 -2
  134. package/dist/runtime/components/Edit/Konami/Game/index.vue +5 -5
  135. package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue → ScheduleDate/index.vue} +6 -58
  136. package/dist/runtime/components/Edit/ScheduleDate/index.vue.d.ts +23 -0
  137. package/dist/runtime/components/Edit/ShortcutIndicator/index.vue +3 -0
  138. package/dist/runtime/components/Edit/Transition/Height.vue +95 -0
  139. package/dist/runtime/components/Edit/Transition/Height.vue.d.ts +36 -0
  140. package/dist/runtime/components/Edit/index.d.ts +7 -3
  141. package/dist/runtime/components/Edit/index.js +12 -4
  142. package/dist/runtime/composables/defineBlokkli.js +4 -2
  143. package/dist/runtime/css/output.css +1 -1
  144. package/dist/runtime/helpers/animationProvider.d.ts +35 -1
  145. package/dist/runtime/helpers/animationProvider.js +179 -48
  146. package/dist/runtime/helpers/composables/defineRenderer.d.ts +8 -0
  147. package/dist/runtime/helpers/composables/defineRenderer.js +8 -0
  148. package/dist/runtime/helpers/composables/useStateBasedCache.d.ts +4 -0
  149. package/dist/runtime/helpers/composables/useStateBasedCache.js +13 -0
  150. package/dist/runtime/helpers/composables/useStickyToolbar.d.ts +4 -1
  151. package/dist/runtime/helpers/composables/useStickyToolbar.js +53 -35
  152. package/dist/runtime/helpers/definitionProvider.d.ts +1 -1
  153. package/dist/runtime/helpers/dom/index.d.ts +1 -0
  154. package/dist/runtime/helpers/domProvider.d.ts +54 -14
  155. package/dist/runtime/helpers/domProvider.js +168 -134
  156. package/dist/runtime/helpers/index.d.ts +1 -8
  157. package/dist/runtime/helpers/index.js +1 -84
  158. package/dist/runtime/helpers/providers/blocks.d.ts +10 -0
  159. package/dist/runtime/helpers/providers/blocks.js +91 -0
  160. package/dist/runtime/helpers/providers/directive.d.ts +24 -0
  161. package/dist/runtime/helpers/providers/directive.js +205 -0
  162. package/dist/runtime/helpers/providers/element.d.ts +6 -0
  163. package/dist/runtime/helpers/providers/element.js +35 -0
  164. package/dist/runtime/helpers/providers/fields.d.ts +8 -0
  165. package/dist/runtime/helpers/providers/fields.js +47 -0
  166. package/dist/runtime/helpers/selectionProvider.d.ts +11 -11
  167. package/dist/runtime/helpers/selectionProvider.js +38 -45
  168. package/dist/runtime/helpers/stateProvider.d.ts +7 -2
  169. package/dist/runtime/helpers/stateProvider.js +83 -14
  170. package/dist/runtime/helpers/storageProvider.d.ts +3 -2
  171. package/dist/runtime/helpers/storageProvider.js +6 -2
  172. package/dist/runtime/helpers/symbols.d.ts +1 -0
  173. package/dist/runtime/helpers/symbols.js +1 -0
  174. package/dist/runtime/helpers/themeProvider.d.ts +2 -1
  175. package/dist/runtime/helpers/themeProvider.js +24 -14
  176. package/dist/runtime/helpers/typesProvider.js +10 -26
  177. package/dist/runtime/helpers/uiProvider.d.ts +11 -3
  178. package/dist/runtime/helpers/uiProvider.js +45 -17
  179. package/dist/runtime/icons/calendar.svg +1 -0
  180. package/dist/runtime/icons/clock.svg +1 -0
  181. package/dist/runtime/icons/comment_add.svg +1 -5
  182. package/dist/runtime/icons/delete.svg +1 -8
  183. package/dist/runtime/icons/duplicate.svg +1 -12
  184. package/dist/runtime/icons/edit.svg +1 -8
  185. package/dist/runtime/icons/reusable.svg +1 -5
  186. package/dist/runtime/plugins/blokkliDirectives.js +96 -0
  187. package/dist/runtime/types/index.d.ts +66 -35
  188. package/package.json +1 -1
  189. package/dist/runtime/components/Edit/DragInteractions/index.vue +0 -401
  190. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Group/index.vue +0 -63
  191. package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue +0 -54
  192. package/dist/runtime/plugins/blokkliEditable.js +0 -31
  193. /package/dist/runtime/components/Edit/{DragInteractions → Features/BlockScheduler}/index.vue.d.ts +0 -0
  194. /package/dist/runtime/plugins/{blokkliEditable.d.ts → blokkliDirectives.d.ts} +0 -0
@@ -0,0 +1,117 @@
1
+ precision highp float;
2
+
3
+ // [x, y] position.
4
+ attribute vec2 a_position;
5
+ // The [x,y,width, height] of the quad the vertex belongs to.
6
+ attribute vec4 a_quad;
7
+ attribute float a_rect_id;
8
+ attribute float a_rect_type;
9
+ attribute vec4 a_rect_radius;
10
+
11
+ // The global scaling applied to all quads.
12
+ uniform float u_scale;
13
+ uniform float u_dpi;
14
+ // The amount of pixels to offset on the x axis.
15
+ uniform float u_offset_x;
16
+ // The amount of pixels to offset on the y axis.
17
+ uniform float u_offset_y;
18
+ uniform vec2 u_resolution;
19
+
20
+ // Hover state uniforms (11 rectangles)
21
+ uniform vec4 u_hover_positions[11]; // x, y, width, height
22
+ uniform vec4 u_hover_radii[11]; // topLeft, topRight, bottomRight, bottomLeft
23
+ uniform float u_hover_types[11]; // 0=mono, 1=accent, 2=teal fill
24
+ uniform float u_hover_visible[11]; // 0=hidden, 1=visible
25
+
26
+ // The transformed quad for the fragment shader.
27
+ varying vec4 v_quad;
28
+ varying vec4 v_rect_radius;
29
+ varying vec2 v_rect_size;
30
+ varying vec2 v_rect_center;
31
+ varying float v_rect_type;
32
+ varying vec2 v_quad_artboard_pos;
33
+
34
+ void main() {
35
+ int rectIndex = int(a_rect_id);
36
+
37
+ // If not visible, move off-screen
38
+ if (u_hover_visible[rectIndex] < 0.5) {
39
+ gl_Position = vec4(-2.0, -2.0, 0.0, 1.0);
40
+ return;
41
+ }
42
+
43
+ // Get rect data from uniforms
44
+ vec4 hoverPos = u_hover_positions[rectIndex]; // x, y, width, height
45
+ vec4 hoverRadius = u_hover_radii[rectIndex];
46
+ float hoverType = u_hover_types[rectIndex];
47
+
48
+ // Define the increase size to prevent border clipping
49
+ float borderThickness = 2.0 * u_dpi;
50
+ float increaseSize = max(borderThickness, 10.0) + 4.0;
51
+
52
+ // Calculate the new dimensions of the quad
53
+ vec4 adjusted_quad = hoverPos;
54
+ adjusted_quad.z += 2.0 * increaseSize; // increase width
55
+ adjusted_quad.w += 2.0 * increaseSize; // increase height
56
+
57
+ // Adjust vertex positions to scale from the center of the rectangle
58
+ // Calculate the center of the original quad
59
+ vec2 center = vec2(
60
+ hoverPos.x + hoverPos.z / 2.0,
61
+ hoverPos.y + hoverPos.w / 2.0
62
+ );
63
+
64
+ // Calculate vertex offset relative to dummy quad center
65
+ vec2 dummyCenter = vec2(a_quad.x + a_quad.z / 2.0, a_quad.y + a_quad.w / 2.0);
66
+ vec2 vertexOffset = a_position - dummyCenter;
67
+
68
+ // Map vertex offset to new rect
69
+ vec2 newOffset =
70
+ vertexOffset *
71
+ (vec2(adjusted_quad.z, adjusted_quad.w) / vec2(a_quad.z, a_quad.w));
72
+
73
+ // New position is center plus the new offset
74
+ vec2 newPosition = center + newOffset;
75
+
76
+ // Apply global scale and offsets
77
+ vec2 offsetPosition = newPosition * u_scale;
78
+ offsetPosition.x += u_offset_x;
79
+ offsetPosition.y += u_offset_y;
80
+
81
+ // Normalize position for rendering
82
+ vec2 normalizedPosition = offsetPosition / u_resolution;
83
+
84
+ // Transform to screen space (-1 to 1)
85
+ vec2 screenSpacePosition = normalizedPosition * 2.0 - vec2(1.0, 1.0);
86
+ screenSpacePosition.y = -screenSpacePosition.y;
87
+
88
+ // Output final position in clip space
89
+ gl_Position = vec4(screenSpacePosition, 0.0, 1.0) * u_dpi;
90
+
91
+ // Pass the dimensions to fragment shader for SDF calculations
92
+ vec4 transformed_quad = vec4(
93
+ (hoverPos.x * u_scale + u_offset_x) * u_dpi,
94
+ (u_resolution.y -
95
+ hoverPos.y * u_scale -
96
+ hoverPos.w * u_scale -
97
+ u_offset_y) *
98
+ u_dpi,
99
+ hoverPos.z * u_scale * u_dpi,
100
+ hoverPos.w * u_scale * u_dpi
101
+ );
102
+ v_quad = transformed_quad;
103
+
104
+ // Expand the rect by 2px for border rendering
105
+ float borderExpansion = 2.0 * u_dpi;
106
+
107
+ // Set varying variables
108
+ v_rect_radius = hoverRadius * u_dpi;
109
+ v_rect_size = vec2(
110
+ v_quad.z + 2.0 * borderExpansion,
111
+ v_quad.w + 2.0 * borderExpansion
112
+ );
113
+ v_rect_center = vec2(v_quad.x + v_quad.z / 2.0, v_quad.y + v_quad.w / 2.0);
114
+ v_rect_type = hoverType;
115
+ // Pass the original artboard-space quad position for stable dash pattern
116
+ v_quad_artboard_pos = vec2(hoverPos.x, hoverPos.y);
117
+ }
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <Overlay v-if="isVisible && gl && animation.webglEnabled.value" :gl="gl" />
3
+ </template>
4
+
5
+ <script setup>
6
+ import Overlay from "./Overlay/index.vue";
7
+ import { computed, useBlokkli, defineBlokkliFeature } from "#imports";
8
+ defineBlokkliFeature({
9
+ id: "hover",
10
+ icon: "selection",
11
+ label: "Hover",
12
+ description: "Renders a border around blocks that are currently being hovered."
13
+ });
14
+ const { selection, ui, animation, dom } = useBlokkli();
15
+ const gl = animation.gl();
16
+ const isVisible = computed(
17
+ () => dom.isReady.value && !selection.isMultiSelecting.value && !selection.editableActive.value && !selection.isDragging.value && !ui.hasTransformOverlayOpen.value && !ui.hasDialogOpen.value && !ui.isAnimating.value
18
+ );
19
+ </script>
20
+
21
+ <script>
22
+ export default {
23
+ name: "Hover"
24
+ };
25
+ </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;
@@ -46,16 +46,15 @@ const props = defineProps({
46
46
  uuid: { type: String, required: true },
47
47
  label: { type: String, required: false }
48
48
  });
49
+ const { $t, element } = useBlokkli();
49
50
  const DURATION = 530;
50
51
  const emit = defineEmits(["submit", "close"]);
51
52
  function getOriginatingElement() {
52
- const el = document.querySelector(
53
- `[data-bk-library-item-uuid="${props.uuid}"]`
53
+ return element.query(
54
+ document.documentElement,
55
+ `[data-bk-library-item-uuid="${props.uuid}"]`,
56
+ "Get originating library item element"
54
57
  );
55
- if (el instanceof HTMLElement) {
56
- return el;
57
- }
58
- return null;
59
58
  }
60
59
  function onEnter(el, done) {
61
60
  if (el instanceof HTMLElement) {
@@ -125,7 +124,6 @@ function onAfterLeave(el) {
125
124
  emit("close");
126
125
  }
127
126
  }
128
- const { $t } = useBlokkli();
129
127
  const iframe = ref(null);
130
128
  const isLoaded = ref(false);
131
129
  const isLoading = ref(true);
@@ -17,15 +17,11 @@
17
17
  </p>
18
18
  <div class="bk">
19
19
  <div class="bk-form-group">
20
- <div>
21
- <label class="bk-form-label" for="library_search">
22
- {{ $t("libraryPlaceSearchLabel", "Filter library items") }}
23
- </label>
24
- <input
20
+ <FormItem>
21
+ <FormText
25
22
  id="library_search"
26
23
  v-model.lazy="searchText"
27
- type="text"
28
- class="bk-form-input"
24
+ :label="$t('libraryPlaceSearchLabel', 'Filter library items')"
29
25
  :placeholder="
30
26
  $t(
31
27
  'libraryPlaceSearchInputPlaceholder',
@@ -34,25 +30,15 @@
34
30
  "
35
31
  required
36
32
  />
37
- </div>
38
- <div>
39
- <label class="bk-form-label" for="library_bundle">
40
- {{ $t("libraryPlaceBundleSelectLabel", "Bundle") }}
41
- </label>
42
- <select
33
+ </FormItem>
34
+ <FormItem>
35
+ <FormSelect
43
36
  id="library_bundle"
44
37
  v-model="selectedBundle"
45
- class="bk-form-input"
46
- >
47
- <option
48
- v-for="v in bundleOptions"
49
- :key="v.bundle"
50
- :value="v.bundle"
51
- >
52
- {{ v.label }}
53
- </option>
54
- </select>
55
- </div>
38
+ :label="$t('libraryPlaceBundleSelectLabel', 'Bundle')"
39
+ :options="bundleOptions"
40
+ />
41
+ </FormItem>
56
42
  </div>
57
43
  </div>
58
44
  <div class="bk-library-dialog-content">
@@ -85,7 +71,13 @@
85
71
  </template>
86
72
 
87
73
  <script setup>
88
- import { FormOverlay, Pagination } from "#blokkli/components";
74
+ import {
75
+ FormOverlay,
76
+ Pagination,
77
+ FormText,
78
+ FormItem,
79
+ FormSelect
80
+ } from "#blokkli/components";
89
81
  import Loading from "./../../../Loading/index.vue";
90
82
  import { ref, useBlokkli, useAsyncData, computed, watch } from "#imports";
91
83
  import LibraryListItem from "./Item/index.vue";
@@ -147,10 +139,10 @@ const bundleOptions = computed(() => {
147
139
  const bundles = allowedBundles.value.map((bundle) => {
148
140
  const definition = types.getBlockBundleDefinition(bundle);
149
141
  return {
150
- bundle,
142
+ value: bundle,
151
143
  label: definition?.label || bundle
152
144
  };
153
145
  });
154
- return [{ bundle: "all", label: $t("all", "All") }, ...bundles];
146
+ return [{ value: "all", label: $t("all", "All") }, ...bundles];
155
147
  });
156
148
  </script>
@@ -23,39 +23,43 @@
23
23
  )
24
24
  "
25
25
  />
26
- <label for="reusable_label" class="bk-form-label">{{
27
- $t("libraryDialogDescriptionLabel", "Description")
28
- }}</label>
29
- <input
30
- id="reusable_label"
31
- v-model="label"
32
- type="text"
33
- class="bk-form-input"
34
- :placeholder="
35
- $t('libraryDialogTitleInputPlaceholder', 'e.g. Teaser Campaign 2024')
26
+ <FormItem>
27
+ <FormText
28
+ id="reusable_label"
29
+ v-model="label"
30
+ :label="$t('libraryDialogDescriptionLabel', 'Description')"
31
+ type="text"
32
+ :placeholder="
33
+ $t(
34
+ 'libraryDialogTitleInputPlaceholder',
35
+ 'e.g. Teaser Campaign 2024'
36
+ )
36
37
  "
37
- required
38
- />
39
- </div>
40
- <div class="bk-form-label">
41
- {{ $t("libraryPreviewLabel", "Preview") }}
42
- </div>
43
- <div
44
- class="bk-dialog-content-element"
45
- :class="[backgroundClass, { 'bk-default-bg': !backgroundClass }]"
46
- :style="backgroundClass ? {} : { backgroundColor }"
47
- >
48
- <div ref="previewEl" />
38
+ required
39
+ />
40
+ </FormItem>
41
+ <FormItem>
42
+ <div class="bk-form-label">
43
+ {{ $t("libraryPreviewLabel", "Preview") }}
44
+ </div>
45
+ <div
46
+ class="bk-dialog-content-element"
47
+ :class="[backgroundClass, { 'bk-default-bg': !backgroundClass }]"
48
+ :style="backgroundClass ? {} : { backgroundColor }"
49
+ >
50
+ <div ref="previewEl" />
51
+ </div>
52
+ </FormItem>
49
53
  </div>
50
54
  </DialogModal>
51
55
  </template>
52
56
 
53
57
  <script setup>
54
58
  import { ref, useBlokkli, onMounted } from "#imports";
55
- import { DialogModal, InfoBox } from "#blokkli/components";
59
+ import { DialogModal, InfoBox, FormText, FormItem } from "#blokkli/components";
56
60
  import { realBackgroundColor } from "#blokkli/helpers";
57
61
  defineEmits(["confirm", "cancel"]);
58
- const { dom, $t } = useBlokkli();
62
+ const { dom, $t, blocks } = useBlokkli();
59
63
  const props = defineProps({
60
64
  uuid: { type: String, required: true },
61
65
  backgroundClass: { type: String, required: false }
@@ -66,14 +70,14 @@ const previewEl = ref(null);
66
70
  const backgroundColor = ref("");
67
71
  onMounted(() => {
68
72
  if (previewEl.value) {
69
- const item = dom.findBlock(props.uuid);
73
+ const item = blocks.getBlock(props.uuid);
70
74
  if (!item) {
71
75
  return;
72
76
  }
73
- if (item.editTitle) {
74
- label.value = item.editTitle.substring(0, 40);
77
+ const element = dom.getDragElement(item);
78
+ if (!element) {
79
+ return;
75
80
  }
76
- const element = item.element();
77
81
  const markup = dom.getDropElementMarkup(item);
78
82
  width.value = element.getBoundingClientRect().width + 40;
79
83
  const clone = document.createElement("div");
@@ -4,6 +4,7 @@
4
4
  id="library_detach"
5
5
  :title="$t('libraryDetach', 'Detach from library')"
6
6
  icon="detach"
7
+ edit-only
7
8
  multiple
8
9
  :weight="-70"
9
10
  @click="onDetach"
@@ -11,8 +12,9 @@
11
12
  <PluginItemAction
12
13
  v-else-if="!isReusable"
13
14
  id="library_make_reusable"
14
- :title="$t('libraryAdd', 'Add to library')"
15
- :disabled="!canMakeReusable || state.editMode.value !== 'editing'"
15
+ :title="$t('libraryAdd', 'Add to library...')"
16
+ :disabled="!canMakeReusable"
17
+ edit-only
16
18
  icon="reusable"
17
19
  :weight="-70"
18
20
  @click="showReusableDialog = true"
@@ -40,8 +42,8 @@
40
42
  <Teleport to="body">
41
43
  <BlokkliTransition name="slide-up">
42
44
  <ReusableDialog
43
- v-if="showReusableDialog && selectedItem"
44
- :uuid="selectedItem.uuid"
45
+ v-if="showReusableDialog && selection.item.value"
46
+ :uuid="selection.item.value.uuid"
45
47
  :background-class="definition?.editor?.previewBackgroundClass"
46
48
  @confirm="onMakeReusable"
47
49
  @cancel="showReusableDialog = false"
@@ -86,12 +88,6 @@ const { adapter } = defineBlokkliFeature({
86
88
  });
87
89
  const { selection, state, types, $t, eventBus, definitions } = useBlokkli();
88
90
  const showReusableDialog = ref(false);
89
- const selectedItem = computed(() => {
90
- if (selection.blocks.value.length !== 1) {
91
- return;
92
- }
93
- return selection.blocks.value[0];
94
- });
95
91
  const onDetach = async () => {
96
92
  if (!adapter.detachReusableBlock || !selection.uuids.value.length) {
97
93
  return;
@@ -117,28 +113,37 @@ const onAddLibraryItem = async (uuid) => {
117
113
  );
118
114
  placedAction.value = null;
119
115
  };
120
- const definition = computed(
121
- () => selectedItem?.value ? definitions.getBlockDefinition(
122
- selectedItem.value.itemBundle,
123
- selectedItem.value.hostFieldListType,
124
- selectedItem.value.parentBlockBundle
125
- ) : null
126
- );
127
- const itemBundle = computed(
128
- () => selectedItem?.value ? types.getBlockBundleDefinition(selectedItem.value.itemBundle) : null
129
- );
116
+ const definition = computed(() => {
117
+ const item = selection.item.value;
118
+ if (!item) {
119
+ return null;
120
+ }
121
+ return definitions.getBlockDefinition(
122
+ item.bundle,
123
+ item.fieldListType,
124
+ item.parentBlockBundle
125
+ );
126
+ });
127
+ const itemBundle = computed(() => {
128
+ const item = selection.item.value;
129
+ if (!item) {
130
+ return null;
131
+ }
132
+ return types.getBlockBundleDefinition(item.bundle);
133
+ });
130
134
  const isReusable = computed(
131
- () => selection.blocks.value.length && selection.blocks.value.every((v) => v.itemBundle === BUNDLE_FROM_LIBRARY)
135
+ () => selection.bundles.value.every((bundle) => bundle === BUNDLE_FROM_LIBRARY)
132
136
  );
133
137
  async function onMakeReusable(label) {
134
138
  showReusableDialog.value = false;
135
- if (!selectedItem?.value?.uuid) {
139
+ const item = selection.item.value;
140
+ if (!item) {
136
141
  return;
137
142
  }
138
143
  await state.mutateWithLoadingState(
139
144
  () => adapter.makeBlockReusable({
140
145
  label,
141
- uuid: selectedItem.value.uuid
146
+ uuid: item.uuid
142
147
  }),
143
148
  $t("libraryError", "Failed to add block to library.")
144
149
  );
@@ -88,7 +88,7 @@ defineProps({
88
88
  isSortli: { type: Boolean, required: false },
89
89
  modelValue: { type: String, required: false }
90
90
  });
91
- const { adapter, storage, $t } = useBlokkli();
91
+ const { adapter, storage, $t, element } = useBlokkli();
92
92
  const selected = ref([]);
93
93
  const listEl = ref(null);
94
94
  const page = ref(0);
@@ -97,10 +97,13 @@ function getDragItems(activeItem) {
97
97
  if (!selected.value.length || !listEl.value) {
98
98
  return null;
99
99
  }
100
+ const listElement = listEl.value;
100
101
  const activeId = activeItem?.itemType === "media_library" ? activeItem.mediaId : null;
101
102
  const items2 = selected.value.map((id) => {
102
- const el = listEl.value?.querySelector(
103
- `[data-sortli-id="media_library_${id}"]`
103
+ const el = element.query(
104
+ listElement,
105
+ `[data-sortli-id="media_library_${id}"]`,
106
+ "Find media library drag item."
104
107
  );
105
108
  if (!(el instanceof HTMLElement)) {
106
109
  return null;
@@ -32,6 +32,7 @@ import { PluginSidebar, PluginDroppableEdit } from "#blokkli/plugins";
32
32
  import Library from "./Library/index.vue";
33
33
  import defineDropAreas from "#blokkli/helpers/composables/defineDropAreas";
34
34
  import { falsy } from "#blokkli/helpers";
35
+ import { itemEntityType } from "#blokkli-build/config";
35
36
  defineBlokkliFeature({
36
37
  id: "media-library",
37
38
  icon: "image",
@@ -39,7 +40,7 @@ defineBlokkliFeature({
39
40
  description: "Implements a media library to easily drag and drop media like images or videos.",
40
41
  requiredAdapterMethods: ["mediaLibraryGetResults", "mediaLibraryAddBlock"]
41
42
  });
42
- const { $t, dom, adapter, state, runtimeConfig, types } = useBlokkli();
43
+ const { $t, adapter, state, runtimeConfig, types, directive } = useBlokkli();
43
44
  const selected = ref("");
44
45
  const ERROR_MESSAGE = $t(
45
46
  "mediaLibraryReplaceFailed",
@@ -49,11 +50,12 @@ const onDroppableEditSave = async (e) => {
49
50
  if (!selected.value) {
50
51
  return;
51
52
  }
52
- if ("itemBundle" in e.host && adapter.mediaLibraryReplaceMedia) {
53
+ if ("itemType" in e.host && adapter.mediaLibraryReplaceMedia) {
54
+ const host = e.host;
53
55
  await state.mutateWithLoadingState(
54
56
  () => adapter.mediaLibraryReplaceMedia({
55
57
  host: {
56
- uuid: e.host.uuid,
58
+ uuid: host.block.uuid,
57
59
  type: runtimeConfig.itemEntityType,
58
60
  fieldName: e.fieldName
59
61
  },
@@ -62,11 +64,12 @@ const onDroppableEditSave = async (e) => {
62
64
  ERROR_MESSAGE
63
65
  );
64
66
  } else if ("type" in e.host && adapter.mediaLibraryReplaceEntityMedia) {
65
- const type = e.host.type;
67
+ const host = e.host;
68
+ const type = host.type;
66
69
  await state.mutateWithLoadingState(
67
70
  () => adapter.mediaLibraryReplaceEntityMedia({
68
71
  host: {
69
- uuid: e.host.uuid,
72
+ uuid: host.uuid,
70
73
  type,
71
74
  fieldName: e.fieldName
72
75
  },
@@ -87,18 +90,18 @@ defineDropAreas((dragItems) => {
87
90
  if (item.itemType !== "media_library") {
88
91
  return;
89
92
  }
90
- return dom.getAllDroppableFields().map((field) => {
91
- const config = types.getDroppableFieldConfig(field.fieldName, field.host);
93
+ return directive.getDroppableElements().map((field) => {
94
+ const config = types.getDroppableFieldConfig(field.fieldName, field);
92
95
  if (config.allowedEntityType !== "media") {
93
96
  return;
94
97
  }
95
98
  if (!config.allowedBundles.includes(item.mediaBundle)) {
96
99
  return;
97
100
  }
98
- const isBlock = "itemBundle" in field.host;
101
+ const isBlock = field.type === itemEntityType;
99
102
  const draggableHost = {
100
- uuid: field.host.uuid,
101
- type: "itemBundle" in field.host ? runtimeConfig.itemEntityType : field.host.type,
103
+ uuid: field.uuid,
104
+ type: field.type,
102
105
  fieldName: field.fieldName
103
106
  };
104
107
  const label = $t("mediaLibraryReplaceMedia", "Replace @field").replace(
@@ -107,7 +110,7 @@ defineDropAreas((dragItems) => {
107
110
  );
108
111
  if (adapter.mediaLibraryReplaceMedia && isBlock) {
109
112
  return {
110
- id: `replace-media:${field.host.uuid}:${field.fieldName}`,
113
+ id: `replace-media:${field.uuid}:${field.fieldName}`,
111
114
  label,
112
115
  element: field.element,
113
116
  icon: "swap-horizontal",
@@ -123,7 +126,7 @@ defineDropAreas((dragItems) => {
123
126
  };
124
127
  } else if (adapter.mediaLibraryReplaceEntityMedia && !isBlock) {
125
128
  return {
126
- id: `replace-entity-media:${field.host.uuid}:${field.fieldName}`,
129
+ id: `replace-entity-media:${field.uuid}:${field.fieldName}`,
127
130
  label,
128
131
  element: field.element,
129
132
  icon: "swap-horizontal",
@@ -7,7 +7,7 @@
7
7
  <script setup>
8
8
  import { useBlokkli, onBeforeUnmount } from "#imports";
9
9
  import { intersects, toShaderColor } from "#blokkli/helpers";
10
- import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
10
+ import defineRenderer from "#blokkli/helpers/composables/defineRenderer";
11
11
  import vs from "./vertex.glsl?raw";
12
12
  import fs from "./fragment.glsl?raw";
13
13
  import {
@@ -17,7 +17,7 @@ import {
17
17
  } from "twgl.js";
18
18
  import { RectangleBufferCollector } from "#blokkli/helpers/webgl";
19
19
  import useDebugLogger from "#blokkli/helpers/composables/useDebugLogger";
20
- const { eventBus, dom, theme, animation, ui } = useBlokkli();
20
+ const { eventBus, dom, theme, animation, ui, blocks } = useBlokkli();
21
21
  const logger = useDebugLogger();
22
22
  const props = defineProps({
23
23
  startX: { type: Number, required: true },
@@ -39,7 +39,7 @@ class MultiSelectRectangleBufferCollector extends RectangleBufferCollector {
39
39
  if (this.added.has(uuid)) {
40
40
  continue;
41
41
  }
42
- const block = dom.findBlock(uuid);
42
+ const block = blocks.getBlock(uuid);
43
43
  if (!block) {
44
44
  continue;
45
45
  }
@@ -181,32 +181,40 @@ function getSelectRect(offset, scale) {
181
181
  };
182
182
  return { shader, check };
183
183
  }
184
- onBlokkliEvent("canvas:draw", (e) => {
185
- mouseX = e.mouseX;
186
- mouseY = e.mouseY;
187
- const { shader, check } = getSelectRect(e.artboardOffset, e.artboardScale);
188
- const { nested } = collector.getSelectedUuids(check);
189
- const shouldSelectAll = props.isPressingControl || !nested.length;
190
- props.gl.useProgram(programInfo.program);
191
- const time = (Date.now() - startTimestamp) / 1e3;
192
- setUniforms(programInfo, uniforms);
193
- setUniforms(programInfo, {
194
- u_select_all: shouldSelectAll ? 1 : 0,
195
- u_select_rect: [shader.x, shader.y, shader.width, shader.height],
196
- u_time: time
197
- });
198
- animation.setSharedUniforms(props.gl, programInfo);
199
- const { info, hasChanged } = collector.getBufferInfo(
200
- e.artboardOffset,
201
- e.artboardScale
202
- );
203
- if (!info) {
204
- return;
205
- }
206
- if (hasChanged) {
207
- setBuffersAndAttributes(props.gl, programInfo, info);
184
+ defineRenderer("multiselect-overlay", {
185
+ zIndex: 450,
186
+ only: true,
187
+ cursor: () => "crosshair",
188
+ render: (ctx) => {
189
+ mouseX = ctx.mouseX;
190
+ mouseY = ctx.mouseY;
191
+ const { shader, check } = getSelectRect(
192
+ ctx.artboardOffset,
193
+ ctx.artboardScale
194
+ );
195
+ const { nested } = collector.getSelectedUuids(check);
196
+ const shouldSelectAll = props.isPressingControl || !nested.length;
197
+ ctx.gl.useProgram(programInfo.program);
198
+ const time = (Date.now() - startTimestamp) / 1e3;
199
+ setUniforms(programInfo, uniforms);
200
+ setUniforms(programInfo, {
201
+ u_select_all: shouldSelectAll ? 1 : 0,
202
+ u_select_rect: [shader.x, shader.y, shader.width, shader.height],
203
+ u_time: time
204
+ });
205
+ animation.setSharedUniforms(ctx.gl, programInfo);
206
+ const { info, hasChanged } = collector.getBufferInfo(
207
+ ctx.artboardOffset,
208
+ ctx.artboardScale
209
+ );
210
+ if (!info) {
211
+ return;
212
+ }
213
+ if (hasChanged) {
214
+ setBuffersAndAttributes(ctx.gl, programInfo, info);
215
+ }
216
+ drawBufferInfo(ctx.gl, info, ctx.gl.TRIANGLES);
208
217
  }
209
- drawBufferInfo(props.gl, info, props.gl.TRIANGLES);
210
218
  });
211
219
  function getUuidsToSelect() {
212
220
  const { check } = getSelectRect(
@@ -222,7 +230,6 @@ function getUuidsToSelect() {
222
230
  return nested;
223
231
  }
224
232
  onBeforeUnmount(() => {
225
- props.gl.clear(props.gl.COLOR_BUFFER_BIT);
226
233
  const diff = Date.now() - startTimestamp;
227
234
  if (diff > 175) {
228
235
  eventBus.emit("select:end", getUuidsToSelect());
@@ -20,11 +20,9 @@ defineBlokkliFeature({
20
20
  description: "Implements support for selecting multiple blocks using a select rectangle.",
21
21
  viewports: ["desktop"]
22
22
  });
23
- const { keyboard, eventBus, selection, state, animation } = useBlokkli();
23
+ const { keyboard, eventBus, selection, animation } = useBlokkli();
24
24
  const gl = animation.gl();
25
- const enabled = computed(
26
- () => !selection.editableActive.value && (state.editMode.value === "editing" || state.editMode.value === "translating") && gl
27
- );
25
+ const enabled = computed(() => !selection.editableActive.value && gl);
28
26
  const shouldRender = ref(false);
29
27
  const downX = ref(0);
30
28
  const downY = ref(0);