@blokkli/editor 2.0.0-alpha.23 → 2.0.0-alpha.24

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 (115) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +62 -66
  3. package/dist/runtime/blokkliPlugins/ContextMenu/index.vue +1 -1
  4. package/dist/runtime/blokkliPlugins/Sidebar/index.vue.d.ts +1 -1
  5. package/dist/runtime/blokkliPlugins/ToolbarButton/index.vue +5 -1
  6. package/dist/runtime/blokkliPlugins/ToolbarButton/index.vue.d.ts +2 -0
  7. package/dist/runtime/blokkliPlugins/TourItem/index.vue +22 -13
  8. package/dist/runtime/blokkliPlugins/TourItem/index.vue.d.ts +1 -0
  9. package/dist/runtime/blokkliPlugins/index.d.ts +1 -3
  10. package/dist/runtime/blokkliPlugins/index.js +0 -4
  11. package/dist/runtime/components/BlokkliProvider.vue.d.ts +1 -1
  12. package/dist/runtime/components/Edit/Actions/ItemDropdown.vue +1 -1
  13. package/dist/runtime/components/Edit/Actions/index.vue +77 -72
  14. package/dist/runtime/components/Edit/AddListItem/index.vue +8 -29
  15. package/dist/runtime/components/Edit/AddListItem/index.vue.d.ts +2 -3
  16. package/dist/runtime/components/Edit/AppMenu/MenuButton.vue +39 -0
  17. package/dist/runtime/{blokkliPlugins/MenuButton/index.vue.d.ts → components/Edit/AppMenu/MenuButton.vue.d.ts} +0 -4
  18. package/dist/runtime/components/Edit/AppMenu/index.vue +62 -40
  19. package/dist/runtime/components/Edit/Dialog/index.vue +26 -5
  20. package/dist/runtime/components/Edit/Dialog/index.vue.d.ts +2 -0
  21. package/dist/runtime/components/Edit/EditProvider.vue +48 -31
  22. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +1 -1
  23. package/dist/runtime/components/Edit/Features/AddList/Actions/Action.vue +52 -0
  24. package/dist/runtime/components/Edit/Features/AddList/Actions/Action.vue.d.ts +7 -0
  25. package/dist/runtime/components/Edit/Features/AddList/Actions/index.vue +41 -0
  26. package/dist/runtime/components/Edit/Features/AddList/Actions/index.vue.d.ts +5 -0
  27. package/dist/runtime/components/Edit/Features/AddList/Blocks/index.vue +11 -47
  28. package/dist/runtime/components/Edit/Features/AddList/Blocks/index.vue.d.ts +5 -0
  29. package/dist/runtime/components/Edit/Features/AddList/index.vue +68 -123
  30. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +41 -20
  31. package/dist/runtime/components/Edit/Features/Artboard/Scrollbar/index.vue +3 -2
  32. package/dist/runtime/components/Edit/Features/Assistant/Overlay/index.vue +2 -28
  33. package/dist/runtime/components/Edit/Features/Assistant/index.vue +18 -14
  34. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +1 -0
  35. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +2 -2
  36. package/dist/runtime/components/Edit/Features/Clipboard/List/index.vue +1 -1
  37. package/dist/runtime/components/Edit/Features/Clipboard/index.vue +52 -18
  38. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +0 -2
  39. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue.d.ts +6 -4
  40. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +77 -27
  41. package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +7 -4
  42. package/dist/runtime/components/Edit/Features/Comments/index.vue +2 -2
  43. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/DragItem.vue +113 -0
  44. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/DragItem.vue.d.ts +25 -0
  45. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +8 -97
  46. package/dist/runtime/components/Edit/Features/DraggingOverlay/Renderer/fragment.glsl +2 -5
  47. package/dist/runtime/components/Edit/Features/DraggingOverlay/Renderer/index.vue +38 -5
  48. package/dist/runtime/components/Edit/Features/DraggingOverlay/Renderer/vertex.glsl +10 -1
  49. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +1 -2
  50. package/dist/runtime/components/Edit/Features/EditForm/index.vue +2 -2
  51. package/dist/runtime/components/Edit/Features/EditableField/index.vue +2 -2
  52. package/dist/runtime/components/Edit/Features/Exit/index.vue +12 -9
  53. package/dist/runtime/components/Edit/Features/Fragments/index.vue +27 -31
  54. package/dist/runtime/components/Edit/Features/ImportExisting/Dialog/index.vue +1 -0
  55. package/dist/runtime/components/Edit/Features/ImportExisting/index.vue +25 -24
  56. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +2 -2
  57. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +1 -0
  58. package/dist/runtime/components/Edit/Features/Library/index.vue +26 -24
  59. package/dist/runtime/components/Edit/Features/MultiSelect/Renderer/index.vue +1 -3
  60. package/dist/runtime/components/Edit/Features/PreviewGrant/index.vue +2 -1
  61. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +1 -0
  62. package/dist/runtime/components/Edit/Features/Publish/index.vue +17 -15
  63. package/dist/runtime/components/Edit/Features/Revert/index.vue +24 -18
  64. package/dist/runtime/components/Edit/Features/Search/index.vue +1 -1
  65. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +21 -17
  66. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +6 -6
  67. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +3 -6
  68. package/dist/runtime/components/Edit/Features/Settings/Dialog/index.vue +1 -0
  69. package/dist/runtime/components/Edit/Features/Settings/index.vue +25 -17
  70. package/dist/runtime/components/Edit/Features/TouchActionBar/index.vue +2 -2
  71. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +1 -1
  72. package/dist/runtime/components/Edit/Features/Tour/Popup/index.vue +2 -2
  73. package/dist/runtime/components/Edit/Features/Tour/index.vue +12 -10
  74. package/dist/runtime/components/Edit/Features/Transform/index.vue +1 -1
  75. package/dist/runtime/components/Edit/Features/Translations/index.vue +18 -17
  76. package/dist/runtime/components/Edit/FormOverlay/index.vue +13 -4
  77. package/dist/runtime/components/Edit/ItemIconBox/index.vue +41 -0
  78. package/dist/runtime/components/Edit/{AddListItemIcon → ItemIconBox}/index.vue.d.ts +5 -5
  79. package/dist/runtime/components/Edit/Konami/Game/index.vue +0 -1
  80. package/dist/runtime/components/Edit/Konami/index.vue +3 -5
  81. package/dist/runtime/components/Edit/Messages/Item/index.vue +11 -2
  82. package/dist/runtime/components/Edit/Messages/index.vue +6 -1
  83. package/dist/runtime/components/Edit/Overlay/index.vue +66 -0
  84. package/dist/runtime/components/Edit/Overlay/index.vue.d.ts +2 -0
  85. package/dist/runtime/components/Edit/SystemRequirements/index.vue +36 -36
  86. package/dist/runtime/components/Edit/Toolbar/index.vue +47 -48
  87. package/dist/runtime/components/Edit/index.d.ts +2 -2
  88. package/dist/runtime/components/Edit/index.js +2 -2
  89. package/dist/runtime/css/output.css +1 -1
  90. package/dist/runtime/helpers/composables/defineAddAction.d.ts +2 -0
  91. package/dist/runtime/helpers/composables/defineAddAction.js +10 -0
  92. package/dist/runtime/helpers/composables/defineItemDropdownAction.js +2 -2
  93. package/dist/runtime/helpers/composables/defineMenuButton.d.ts +2 -0
  94. package/dist/runtime/helpers/composables/defineMenuButton.js +10 -0
  95. package/dist/runtime/helpers/composables/useDialog.d.ts +3 -0
  96. package/dist/runtime/helpers/composables/useDialog.js +16 -0
  97. package/dist/runtime/helpers/defineElementStyle.d.ts +2 -0
  98. package/dist/runtime/helpers/defineElementStyle.js +33 -0
  99. package/dist/runtime/helpers/domProvider.d.ts +1 -0
  100. package/dist/runtime/helpers/domProvider.js +7 -2
  101. package/dist/runtime/helpers/dropTargets/index.d.ts +1 -1
  102. package/dist/runtime/helpers/dropTargets/index.js +17 -3
  103. package/dist/runtime/helpers/pluginProvider.d.ts +25 -6
  104. package/dist/runtime/helpers/pluginProvider.js +48 -46
  105. package/dist/runtime/helpers/providers/blocks.js +10 -0
  106. package/dist/runtime/helpers/providers/fields.d.ts +9 -1
  107. package/dist/runtime/helpers/uiProvider.d.ts +9 -12
  108. package/dist/runtime/helpers/uiProvider.js +85 -83
  109. package/dist/runtime/icons/click.svg +1 -0
  110. package/dist/runtime/types/index.d.ts +12 -5
  111. package/package.json +1 -1
  112. package/dist/runtime/blokkliPlugins/AddAction/index.vue +0 -96
  113. package/dist/runtime/blokkliPlugins/AddAction/index.vue.d.ts +0 -26
  114. package/dist/runtime/blokkliPlugins/MenuButton/index.vue +0 -68
  115. package/dist/runtime/components/Edit/AddListItemIcon/index.vue +0 -19
@@ -16,40 +16,7 @@
16
16
  <Icon name="cursor-move" />
17
17
  <p v-html="currentActiveLabel" />
18
18
  </div>
19
- <div
20
- v-for="(rect, i) in rects"
21
- :key="i"
22
- class="bk-dragging-overlay-item"
23
- :class="{ 'bk-is-top': rect.isTop, 'bk-is-fallback': !rect.markup }"
24
- :style="{
25
- width: rect.width + 'px',
26
- height: rect.height + 'px',
27
- transform: `translate(${rect.x}px, ${rect.y}px) scale(${rect.scaleX}, ${rect.scaleY})`,
28
- opacity: rect.opacity,
29
- background: rect.background,
30
- transformOrigin: rect.transformOrigin,
31
- borderRadius: rect.borderRadius
32
- }"
33
- >
34
- <div
35
- v-if="rect.markup"
36
- class="bk-dragging-overlay-markup"
37
- v-html="rect.markup"
38
- />
39
- <div
40
- v-else
41
- class="bk-dragging-overlay-fallback"
42
- :style="{ color: rect.fallbackColor }"
43
- >
44
- <div :style="{ transform: `scale(${1 / rect.to.scaleX})` }">
45
- <template v-if="rect.isTop">
46
- <ItemIcon v-if="rect.bundle" :bundle="rect.bundle" />
47
- <Icon v-else-if="rect.icon" :name="rect.icon" />
48
- <div v-if="rect.label">{{ rect.label }}</div>
49
- </template>
50
- </div>
51
- </div>
52
- </div>
19
+ <DragItem v-for="(rect, i) in rects" :key="i" v-bind="rect" />
53
20
  </div>
54
21
  </template>
55
22
 
@@ -62,16 +29,10 @@ import {
62
29
  onMounted,
63
30
  onBeforeUnmount
64
31
  } from "#imports";
65
- import {
66
- isInsideRect,
67
- realBackgroundColor,
68
- lerp,
69
- falsy
70
- } from "#blokkli/helpers";
71
- import { Icon, ItemIcon } from "#blokkli/components";
72
- import { easeOutElastic } from "#blokkli/helpers/easing";
73
- import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
74
- const { dom, ui, animation, theme, types } = useBlokkli();
32
+ import { isInsideRect, realBackgroundColor, falsy } from "#blokkli/helpers";
33
+ import { Icon } from "#blokkli/components";
34
+ import DragItem, {} from "./DragItem.vue";
35
+ const { dom, ui, types } = useBlokkli();
75
36
  const props = defineProps({
76
37
  items: { type: Array, required: true },
77
38
  x: { type: Number, required: true },
@@ -136,51 +97,6 @@ function getRect() {
136
97
  }
137
98
  defineExpose({ getRect });
138
99
  const rects = ref([]);
139
- const animationStart = Date.now();
140
- const duration = 500;
141
- const isDone = ref(false);
142
- onBlokkliEvent("animationFrame", () => {
143
- if (isDone.value) {
144
- return;
145
- }
146
- const newRects = [];
147
- const elapsed = Date.now() - animationStart;
148
- const alphaX = easeOutElastic(elapsed / duration, 1.92, 0.91);
149
- const alphaY = easeOutElastic(elapsed / duration, 2.2, 0.76);
150
- const opacityAlpha = Math.min(Math.max(elapsed - 300, 0) / 200, 1);
151
- for (let i = 0; i < rects.value.length; i++) {
152
- const rect = rects.value[i];
153
- const newX = lerp(rect.from.x, rect.to.x, alphaX);
154
- const newY = lerp(rect.from.y, rect.to.y, alphaY);
155
- const newOpacity = lerp(rect.from.opacity, rect.to.opacity, opacityAlpha);
156
- const newScaleX = lerp(rect.from.scaleX, rect.to.scaleX, alphaX);
157
- const newScaleY = lerp(rect.from.scaleY, rect.to.scaleY, alphaY);
158
- animation.requestDraw();
159
- newRects.push({
160
- ...rect,
161
- x: newX,
162
- y: newY,
163
- scaleX: newScaleX,
164
- scaleY: newScaleY,
165
- opacity: newOpacity
166
- });
167
- }
168
- if (elapsed > duration || !ui.useAnimations.value || ui.lowPerformanceMode.value) {
169
- rects.value = newRects.map((v) => {
170
- return {
171
- ...v,
172
- opacity: v.to.opacity,
173
- scaleX: v.to.scaleX,
174
- scaleY: v.to.scaleY,
175
- x: v.to.x,
176
- y: v.to.y
177
- };
178
- });
179
- isDone.value = true;
180
- return;
181
- }
182
- rects.value = newRects;
183
- });
184
100
  function getDraggingBounds(mouse, rect, maxWidth) {
185
101
  const aspectRatio = rect.width / rect.height;
186
102
  const effectiveWidth = Math.min(rect.width, maxWidth);
@@ -223,7 +139,7 @@ onMounted(() => {
223
139
  props.startCoords,
224
140
  boundRect.rect,
225
141
  // Limit width to 250px
226
- 340
142
+ 351
227
143
  );
228
144
  const boundsX = props.isTouch ? 0 : bounds.x;
229
145
  const boundsY = props.isTouch ? translateY.value : bounds.y;
@@ -258,7 +174,6 @@ onMounted(() => {
258
174
  scaleX: targetScaleX,
259
175
  scaleY: targetScaleY
260
176
  };
261
- const style2 = theme.getDraggableStyle(element);
262
177
  const markup = (elRects.length < 6 || isTop) && !ui.lowPerformanceMode.value ? dom.getDropElementMarkup(item.item, true) : "";
263
178
  let bundle;
264
179
  let label = "";
@@ -277,19 +192,15 @@ onMounted(() => {
277
192
  isTop,
278
193
  from: ui.lowPerformanceMode.value ? to : from,
279
194
  to,
280
- ...from,
281
195
  width: item.element.offsetWidth,
282
196
  height: item.element.offsetHeight,
283
- opacity: 1,
284
197
  transformOrigin: `${originX}px ${originY}px`,
285
198
  markup,
286
- background: realBackgroundColor(item.element),
199
+ background: item.item.itemType === "existing" ? realBackgroundColor(item.element) : "",
287
200
  prevVisibility: item.item.itemType === "existing" || item.item.itemType === "existing_structure" ? item.element.style.visibility : void 0,
288
201
  element: item.element,
289
- borderRadius: style2.radiusString,
290
202
  bundle,
291
- label,
292
- fallbackColor: style2.textColor
203
+ label
293
204
  };
294
205
  }).filter(falsy);
295
206
  elRects.forEach((item) => {
@@ -15,6 +15,7 @@ in float v_thickness;
15
15
  in float v_edge_softness;
16
16
  in float v_radius_outer;
17
17
  in float v_radius_inner;
18
+ in float v_fill_alpha;
18
19
 
19
20
  out vec4 fragColor;
20
21
 
@@ -52,11 +53,7 @@ void main() {
52
53
  // Alpha value for the border.
53
54
  float alphaBorder = clamp(alphaOuter - alphaInner, 0.0, 1.0);
54
55
 
55
- // Adjust alphas based on intersection.
56
- float adjustedAlphaFill =
57
- v_intersecting >= 0.5
58
- ? alphaInner * 0.95
59
- : alphaInner * 0.2;
56
+ float adjustedAlphaFill = alphaInner * v_fill_alpha;
60
57
 
61
58
  if (v_is_hover_area >= 1.0) {
62
59
  // If nesting level is 0, don't render the fill (border only)
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Teleport to="body">
2
+ <Teleport :to="ui.mainLayoutElement.value">
3
3
  <slot :color="activeColorHex" :label="active?.label" />
4
4
  </Teleport>
5
5
  </template>
@@ -153,10 +153,20 @@ const draggingBundles = computed(
153
153
  }
154
154
  } else if (item.itemBundle) {
155
155
  bundles.push(item.itemBundle);
156
+ } else if (item.itemType === "action" && item.action.itemBundle) {
157
+ bundles.push(item.action.itemBundle);
156
158
  }
157
159
  return bundles;
158
160
  }).filter(falsy)
159
161
  );
162
+ const draggingFragments = computed(
163
+ () => props.items.flatMap((item) => {
164
+ if ((item.itemType === "existing" || item.itemType === "existing_structure") && item.block.bundle === "blokkli_fragment" && item.block.fragment?.name) {
165
+ return [item.block.fragment.name];
166
+ }
167
+ return [];
168
+ }).filter(falsy)
169
+ );
160
170
  const selectionUuids = computed(
161
171
  () => props.items.map((item) => {
162
172
  if (item.itemType === "existing") {
@@ -178,6 +188,8 @@ const buildChildren = (field, visible) => {
178
188
  const children = [];
179
189
  let prevWasInSelection = false;
180
190
  let prevUuid = "";
191
+ let prevElOffsetTop = 0;
192
+ let prevElHeight = 0;
181
193
  for (let i = 0; i < field.childrenElements.length; i++) {
182
194
  const childrenForUuid = [];
183
195
  const isLast = i === field.childrenElements.length - 1;
@@ -190,11 +202,17 @@ const buildChildren = (field, visible) => {
190
202
  continue;
191
203
  }
192
204
  if (!visible.includes(uuid)) {
205
+ const elRect2 = dom.getBlockRect(uuid) || ui.getAbsoluteElementRect(dom.getBoundingClientRect(el));
206
+ prevElOffsetTop = elRect2.y - field.y;
207
+ prevElHeight = el.scrollHeight;
193
208
  prevUuid = uuid;
194
209
  continue;
195
210
  }
196
211
  const cached = fieldChildCache[uuid];
197
212
  if (cached) {
213
+ const elRect2 = dom.getBlockRect(uuid) || ui.getAbsoluteElementRect(dom.getBoundingClientRect(el));
214
+ prevElOffsetTop = elRect2.y - field.y;
215
+ prevElHeight = el.scrollHeight;
198
216
  children.push(...cached);
199
217
  prevUuid = uuid;
200
218
  continue;
@@ -204,9 +222,10 @@ const buildChildren = (field, visible) => {
204
222
  prevUuid = uuid;
205
223
  continue;
206
224
  }
207
- const elRect = dom.getBlockRect(uuid) || ui.getAbsoluteElementRect(el.getBoundingClientRect());
225
+ const elRect = dom.getBlockRect(uuid) || ui.getAbsoluteElementRect(dom.getBoundingClientRect(el));
208
226
  const elOffsetTop = elRect.y - field.y;
209
227
  const elOffsetLeft = elRect.x - field.x;
228
+ const elHeight = el.scrollHeight;
210
229
  if (isLast) {
211
230
  const id2 = buildChildId(field.field, uuid, "last", uuid);
212
231
  if (field.orientation === "vertical") {
@@ -215,7 +234,7 @@ const buildChildren = (field, visible) => {
215
234
  width: field.width,
216
235
  height: MIN_GAP,
217
236
  x: 0,
218
- y: elOffsetTop + el.scrollHeight,
237
+ y: elOffsetTop + elHeight,
219
238
  label: field.label
220
239
  });
221
240
  } else {
@@ -232,17 +251,28 @@ const buildChildren = (field, visible) => {
232
251
  if (prevWasInSelection) {
233
252
  prevWasInSelection = false;
234
253
  prevUuid = uuid;
254
+ prevElOffsetTop = elOffsetTop;
255
+ prevElHeight = elHeight;
235
256
  children.push(...childrenForUuid);
236
257
  continue;
237
258
  }
238
259
  const id = buildChildId(field.field, prevUuid, "between", uuid);
239
260
  if (field.orientation === "vertical") {
261
+ let dropTargetY;
262
+ if (prevElHeight > 0) {
263
+ const prevBlockBottom = prevElOffsetTop + prevElHeight;
264
+ const gapMiddle = (prevBlockBottom + elOffsetTop) / 2;
265
+ dropTargetY = gapMiddle - MIN_GAP / 2;
266
+ } else {
267
+ const gapMiddle = elOffsetTop / 2;
268
+ dropTargetY = gapMiddle - MIN_GAP / 2;
269
+ }
240
270
  childrenForUuid.push({
241
271
  id,
242
272
  width: field.width,
243
273
  height: MIN_GAP,
244
274
  x: 0,
245
- y: elOffsetTop - field.gap / 2,
275
+ y: dropTargetY,
246
276
  label: field.label
247
277
  });
248
278
  } else {
@@ -257,6 +287,8 @@ const buildChildren = (field, visible) => {
257
287
  }
258
288
  fieldChildCache[uuid] = childrenForUuid;
259
289
  children.push(...childrenForUuid);
290
+ prevElOffsetTop = elOffsetTop;
291
+ prevElHeight = elHeight;
260
292
  prevUuid = uuid;
261
293
  }
262
294
  return children;
@@ -316,7 +348,8 @@ const buildFieldRect = (key) => {
316
348
  selectionUuids.value,
317
349
  currentCount,
318
350
  props.items.length,
319
- draggingBundles.value
351
+ draggingBundles.value,
352
+ draggingFragments.value
320
353
  );
321
354
  const orientation = field.dropAlignment || getChildrenOrientation(field.element);
322
355
  const rect = dom.getFieldRect(field.key);
@@ -35,6 +35,7 @@ out float v_thickness;
35
35
  out float v_edge_softness;
36
36
  out float v_radius_outer;
37
37
  out float v_radius_inner;
38
+ out float v_fill_alpha;
38
39
 
39
40
  vec4 getQuad() {
40
41
  if (a_rect_type >= 5.0) {
@@ -72,6 +73,8 @@ void main() {
72
73
 
73
74
  v_is_hover_area = a_rect_type >= 5.0 ? 1.0 : 0.0;
74
75
 
76
+ bool is_drop_target = a_rect_type <= 0.5;
77
+
75
78
  // Set correct colors based on type.
76
79
  if (a_rect_type < 1.0) {
77
80
  v_color = u_color_area;
@@ -89,7 +92,7 @@ void main() {
89
92
 
90
93
  // Compute values that are constant per quad (optimization)
91
94
  bool isHoverArea = v_is_hover_area >= 1.0;
92
- float stroke = isHoverArea ? 0.75 : 2.0;
95
+ float stroke = isHoverArea ? 0.5 : 1.0;
93
96
  float radiusBase = stroke * u_scale;
94
97
 
95
98
  v_thickness = max(min(1.0 * u_scale, 3.0), 0.5);
@@ -118,4 +121,10 @@ void main() {
118
121
  v_radius_inner = v_radius_outer - borderWidth;
119
122
 
120
123
  v_size_inner = v_size - 2.0 * borderWidth;
124
+
125
+ if (is_drop_target) {
126
+ v_fill_alpha = v_intersecting >= 0.5 ? 0.5 : 0.2;
127
+ } else {
128
+ v_fill_alpha = v_intersecting >= 0.5 ? 1.0 : 0.2;
129
+ }
121
130
  }
@@ -188,8 +188,7 @@ const onDropSearchContentItem = async (item, host, afterUuid) => {
188
188
  }
189
189
  };
190
190
  const onDropAction = (action, host, field, afterUuid) => {
191
- eventBus.emit("action:placed", {
192
- id: action.actionType,
191
+ action.action.callback({
193
192
  preceedingUuid: afterUuid,
194
193
  host,
195
194
  field
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Teleport to="body">
2
+ <Teleport :to="ui.mainLayoutElement.value">
3
3
  <BlokkliTransition name="slide-in">
4
4
  <FormOverlay
5
5
  v-if="form"
@@ -32,7 +32,7 @@ const { adapter } = defineBlokkliFeature({
32
32
  description: "Listens to edit events and renders an iframe containing the edit form.",
33
33
  requiredAdapterMethods: ["formFrameBuilder"]
34
34
  });
35
- const { types, state, context, $t, dom, definitions, blocks } = useBlokkli();
35
+ const { types, state, context, $t, dom, definitions, blocks, ui } = useBlokkli();
36
36
  const form = ref(null);
37
37
  const formUrl = computed(() => {
38
38
  if (form.value) {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Teleport to="body">
2
+ <Teleport :to="ui.mainLayoutElement.value">
3
3
  <BlokkliTransition name="caret-tooltip" :enabled="hasTransition">
4
4
  <Overlay
5
5
  v-if="selectedEditable"
@@ -32,7 +32,7 @@ defineBlokkliFeature({
32
32
  requiredAdapterMethods: ["updateFieldValue", "getEditableFieldConfig"],
33
33
  description: "Implements a form overlay to edit a single field of a block."
34
34
  });
35
- const { selection, adapter, types, $t, state, directive, blocks, context } = useBlokkli();
35
+ const { selection, adapter, types, $t, state, directive, blocks, context, ui } = useBlokkli();
36
36
  const selectedEditable = ref(null);
37
37
  const hasTransition = ref(false);
38
38
  const key = computed(() => {
@@ -1,17 +1,10 @@
1
1
  <template>
2
- <PluginMenuButton
3
- id="exit"
4
- :title="$t('exitTitle', 'Close')"
5
- :description="$t('exitDescription', 'Close editor without publishing')"
6
- :weight="100"
7
- icon="exit"
8
- @click="onClick"
9
- />
2
+ <div />
10
3
  </template>
11
4
 
12
5
  <script setup>
13
6
  import { useBlokkli, useRoute, nextTick, defineBlokkliFeature } from "#imports";
14
- import { PluginMenuButton } from "#blokkli/plugins";
7
+ import defineMenuButton from "#blokkli/helpers/composables/defineMenuButton";
15
8
  defineBlokkliFeature({
16
9
  id: "exit",
17
10
  label: "Exit",
@@ -26,6 +19,16 @@ function onClick() {
26
19
  window.location.href = route.path;
27
20
  });
28
21
  }
22
+ defineMenuButton(() => {
23
+ return {
24
+ id: "exit",
25
+ title: $t("exitTitle", "Close"),
26
+ description: $t("exitDescription", "Close editor without publishing"),
27
+ icon: "exit",
28
+ weight: 100,
29
+ callback: onClick
30
+ };
31
+ });
29
32
  </script>
30
33
 
31
34
  <script>
@@ -1,27 +1,8 @@
1
1
  <template>
2
- <PluginAddAction
3
- v-if="
4
- adapter.addLibraryItem && adapter.getLibraryItems && isSupportedOnEntity
5
- "
6
- type="fragment"
7
- :title="$t('fragmentsAddFragmentAction', 'Add fragment')"
8
- :description="
9
- $t(
10
- 'fragmentsAddFragmentDescription',
11
- '<p>Drag the icon into the page to add a fragment block.</p><p>Fragments are reusable blocks that always render the same content.</p>'
12
- )
13
- "
14
- :disabled="!isEnabled"
15
- item-bundle="blokkli_fragment"
16
- icon="fragment"
17
- color="accent"
18
- @placed="placedAction = $event"
19
- />
20
-
21
- <Teleport to="body">
2
+ <Teleport :to="ui.mainLayoutElement.value">
22
3
  <BlokkliTransition name="slide-in">
23
4
  <FragmentsDialog
24
- v-if="placedAction && adapter.getLibraryItems"
5
+ v-if="placedAction"
25
6
  :field="placedAction.field"
26
7
  @close="placedAction = null"
27
8
  @submit="onAddFragment"
@@ -32,9 +13,9 @@
32
13
 
33
14
  <script setup>
34
15
  import { ref, useBlokkli, defineBlokkliFeature, computed } from "#imports";
35
- import { PluginAddAction } from "#blokkli/plugins";
36
16
  import FragmentsDialog from "./Dialog/index.vue";
37
17
  import { BlokkliTransition } from "#blokkli/components";
18
+ import defineAddAction from "#blokkli/helpers/composables/defineAddAction";
38
19
  const { adapter } = defineBlokkliFeature({
39
20
  id: "fragments",
40
21
  icon: "fragment",
@@ -43,15 +24,7 @@ const { adapter } = defineBlokkliFeature({
43
24
  requiredAdapterMethods: ["fragmentsAddBlock"],
44
25
  dependencies: ["add-list"]
45
26
  });
46
- const { state, $t, types, selection, dom } = useBlokkli();
47
- const isEnabled = computed(() => {
48
- const item = selection.item.value;
49
- if (item) {
50
- const field = dom.getRegisteredField(item.host.uuid, item.host.fieldName);
51
- return !!field?.allowedFragments.length;
52
- }
53
- return true;
54
- });
27
+ const { state, $t, types, dom, ui } = useBlokkli();
55
28
  const placedAction = ref(null);
56
29
  const onAddFragment = async (name) => {
57
30
  if (!placedAction.value || !adapter.fragmentsAddBlock) {
@@ -69,6 +42,29 @@ const onAddFragment = async (name) => {
69
42
  const isSupportedOnEntity = computed(
70
43
  () => types.generallyAvailableBundles.find((v) => v.id === "blokkli_fragment")
71
44
  );
45
+ defineAddAction(() => {
46
+ if (!isSupportedOnEntity.value) {
47
+ return;
48
+ }
49
+ return {
50
+ id: "fragment",
51
+ icon: "fragment",
52
+ color: "accent",
53
+ itemBundle: "blokkli_fragment",
54
+ title: $t("fragmentsAddFragmentAction", "Add fragment"),
55
+ description: $t(
56
+ "fragmentsAddFragmentDescription",
57
+ "<p>Drag the icon into the page to add a fragment block.</p><p>Fragments are reusable blocks that always render the same content.</p>"
58
+ ),
59
+ callback: (action) => {
60
+ placedAction.value = action;
61
+ },
62
+ enabled: (item) => {
63
+ const field = dom.getRegisteredField(item.host.uuid, item.host.fieldName);
64
+ return !!field?.allowedFragments.length;
65
+ }
66
+ };
67
+ });
72
68
  </script>
73
69
 
74
70
  <script>
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <DialogModal
3
+ id="import-existing"
3
4
  :title="$t('importExistingDialogTitle', 'Import from existing page')"
4
5
  :lead="
5
6
  $t(
@@ -1,18 +1,5 @@
1
1
  <template>
2
- <PluginMenuButton
3
- v-if="state.mutatedFields.value.length"
4
- id="import_existing"
5
- :title="$t('importExistingTitle', 'Import...')"
6
- :description="
7
- $t('importExistingDescription', 'Import from an existing page')
8
- "
9
- :disabled="state.editMode.value !== 'editing'"
10
- :weight="50"
11
- icon="import"
12
- @click="showModal = true"
13
- />
14
-
15
- <Teleport to="body">
2
+ <Teleport :to="ui.mainLayoutElement.value">
16
3
  <BlokkliTransition name="slide-up">
17
4
  <ExistingDialog
18
5
  v-if="showModal"
@@ -24,16 +11,11 @@
24
11
  </template>
25
12
 
26
13
  <script setup>
27
- import {
28
- ref,
29
- computed,
30
- useBlokkli,
31
- onMounted,
32
- defineBlokkliFeature
33
- } from "#imports";
34
- import { PluginMenuButton } from "#blokkli/plugins";
14
+ import { computed, useBlokkli, onMounted, defineBlokkliFeature } from "#imports";
35
15
  import { BlokkliTransition } from "#blokkli/components";
36
16
  import ExistingDialog from "./Dialog/index.vue";
17
+ import defineMenuButton from "#blokkli/helpers/composables/defineMenuButton";
18
+ import { useDialog } from "#blokkli/helpers/composables/useDialog";
37
19
  const { adapter, settings } = defineBlokkliFeature({
38
20
  id: "import-existing",
39
21
  label: "Import existing content",
@@ -50,11 +32,11 @@ const { adapter, settings } = defineBlokkliFeature({
50
32
  }
51
33
  }
52
34
  });
53
- const { state, $t } = useBlokkli();
35
+ const { ui, state, $t } = useBlokkli();
54
36
  const isEmpty = computed(
55
37
  () => !state.mutatedFields.value.find((v) => v.list?.length)
56
38
  );
57
- const showModal = ref(false);
39
+ const showModal = useDialog("import-existing", "center");
58
40
  function onSubmit(sourceUuid, sourceFields) {
59
41
  showModal.value = false;
60
42
  state.mutateWithLoadingState(
@@ -71,6 +53,25 @@ onMounted(() => {
71
53
  showModal.value = true;
72
54
  }
73
55
  });
56
+ defineMenuButton(() => {
57
+ if (!state.mutatedFields.value.length) {
58
+ return void 0;
59
+ }
60
+ return {
61
+ id: "import_existing",
62
+ title: $t("importExistingTitle", "Import..."),
63
+ description: $t(
64
+ "importExistingDescription",
65
+ "Import from an existing page"
66
+ ),
67
+ icon: "import",
68
+ disabled: state.editMode.value !== "editing",
69
+ weight: 50,
70
+ callback: () => {
71
+ showModal.value = true;
72
+ }
73
+ };
74
+ });
74
75
  </script>
75
76
 
76
77
  <script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Teleport to="body">
2
+ <Teleport :to="ui.mainLayoutElement.value">
3
3
  <Loading v-if="isLoading" />
4
4
  <Transition name="bk-library-edit-header">
5
5
  <header v-show="isLoaded" class="bk bk-library-edit-overlay-header">
@@ -46,7 +46,7 @@ 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
+ const { $t, element, ui } = useBlokkli();
50
50
  const DURATION = 530;
51
51
  const emit = defineEmits(["submit", "close"]);
52
52
  function getOriginatingElement() {
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <DialogModal
3
+ id="library-reusable"
3
4
  :title="$t('libraryDialogTitle', 'Add to library')"
4
5
  :lead="
5
6
  $t(