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

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 (106) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +265 -83
  3. package/dist/modules/drupal/graphql/base/fragment.blokkliProps.graphql +1 -1
  4. package/dist/modules/drupal/graphql/features/comments.graphql +11 -8
  5. package/dist/modules/drupal/runtime/adapter/index.js +2 -2
  6. package/dist/runtime/blokkliPlugins/ItemAction/index.vue +1 -3
  7. package/dist/runtime/components/Blocks/FromLibrary/index.vue +4 -2
  8. package/dist/runtime/components/BlokkliEditable.vue +22 -4
  9. package/dist/runtime/components/BlokkliProvider.vue +29 -20
  10. package/dist/runtime/components/BlokkliProvider.vue.d.ts +2 -1
  11. package/dist/runtime/components/Edit/Actions/index.vue +9 -4
  12. package/dist/runtime/components/Edit/AnimationCanvas/index.vue +420 -25
  13. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +80 -0
  14. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue.d.ts +32 -0
  15. package/dist/runtime/components/Edit/Banner/index.vue +51 -0
  16. package/dist/runtime/components/Edit/Banner/index.vue.d.ts +18 -0
  17. package/dist/runtime/components/Edit/EditIndicator.vue +118 -44
  18. package/dist/runtime/components/Edit/EditIndicator.vue.d.ts +3 -0
  19. package/dist/runtime/components/Edit/EditProvider.vue +79 -22
  20. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +2 -0
  21. package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +19 -20
  22. package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +1 -1
  23. package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +2 -0
  24. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue +35 -20
  25. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue.d.ts +5 -3
  26. package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue +29 -0
  27. package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue.d.ts +13 -0
  28. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue +22 -16
  29. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue.d.ts +1 -0
  30. package/dist/runtime/components/Edit/Features/Comments/Overlay/index.vue +15 -6
  31. package/dist/runtime/components/Edit/Features/Comments/index.vue +20 -8
  32. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +26 -35
  33. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue +240 -0
  34. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue.d.ts +6 -0
  35. package/dist/runtime/components/Edit/Features/Debug/index.vue +4 -165
  36. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +1 -1
  37. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +41 -37
  38. package/dist/runtime/components/Edit/Features/Edit/index.vue +1 -1
  39. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +63 -3
  40. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Plaintext/index.vue +13 -9
  41. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +17 -76
  42. package/dist/runtime/components/Edit/Features/EditableField/index.vue +1 -1
  43. package/dist/runtime/components/Edit/Features/History/index.vue +5 -2
  44. package/dist/runtime/components/Edit/Features/Hover/Overlay/fragment.glsl +139 -0
  45. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +270 -0
  46. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue.d.ts +6 -0
  47. package/dist/runtime/components/Edit/Features/Hover/Overlay/vertex.glsl +117 -0
  48. package/dist/runtime/components/Edit/Features/Hover/index.vue +25 -0
  49. package/dist/runtime/components/Edit/Features/Library/LibraryDialog/index.vue +19 -27
  50. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +27 -23
  51. package/dist/runtime/components/Edit/Features/Library/index.vue +2 -1
  52. package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +34 -27
  53. package/dist/runtime/components/Edit/Features/MultiSelect/index.vue +2 -4
  54. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +6 -1
  55. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +1 -0
  56. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue +35 -0
  57. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue.d.ts +6 -0
  58. package/dist/runtime/components/Edit/Features/Ownership/index.vue +7 -25
  59. package/dist/runtime/components/Edit/Features/ProxyView/index.vue +5 -1
  60. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +39 -74
  61. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +4 -2
  62. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/fragment.glsl +106 -0
  63. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +417 -0
  64. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue.d.ts +32 -0
  65. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/vertex.glsl +102 -0
  66. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +33 -106
  67. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +88 -29
  68. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +2 -0
  69. package/dist/runtime/components/Edit/Features/Selection/Overlay/vertex.glsl +11 -2
  70. package/dist/runtime/components/Edit/Features/Selection/index.vue +5 -12
  71. package/dist/runtime/components/Edit/Features/Translations/Banner/index.vue +17 -11
  72. package/dist/runtime/components/Edit/Features/Translations/index.vue +13 -16
  73. package/dist/runtime/components/Edit/Form/Text/index.vue +2 -1
  74. package/dist/runtime/components/Edit/Form/Text/index.vue.d.ts +1 -0
  75. package/dist/runtime/components/Edit/Indicators/index.vue +1 -1
  76. package/dist/runtime/components/Edit/Konami/Game/index.vue +5 -5
  77. package/dist/runtime/components/Edit/index.d.ts +5 -3
  78. package/dist/runtime/components/Edit/index.js +8 -4
  79. package/dist/runtime/composables/defineBlokkli.js +4 -2
  80. package/dist/runtime/css/output.css +1 -1
  81. package/dist/runtime/helpers/animationProvider.d.ts +34 -1
  82. package/dist/runtime/helpers/animationProvider.js +175 -48
  83. package/dist/runtime/helpers/composables/defineRenderer.d.ts +8 -0
  84. package/dist/runtime/helpers/composables/defineRenderer.js +8 -0
  85. package/dist/runtime/helpers/composables/useStickyToolbar.d.ts +4 -1
  86. package/dist/runtime/helpers/composables/useStickyToolbar.js +53 -35
  87. package/dist/runtime/helpers/dom/index.d.ts +1 -0
  88. package/dist/runtime/helpers/domProvider.d.ts +46 -0
  89. package/dist/runtime/helpers/domProvider.js +95 -6
  90. package/dist/runtime/helpers/editableProvider.d.ts +14 -0
  91. package/dist/runtime/helpers/editableProvider.js +144 -0
  92. package/dist/runtime/helpers/stateProvider.d.ts +6 -2
  93. package/dist/runtime/helpers/stateProvider.js +66 -3
  94. package/dist/runtime/helpers/storageProvider.d.ts +3 -2
  95. package/dist/runtime/helpers/storageProvider.js +6 -2
  96. package/dist/runtime/helpers/symbols.d.ts +1 -0
  97. package/dist/runtime/helpers/symbols.js +1 -0
  98. package/dist/runtime/helpers/uiProvider.d.ts +8 -1
  99. package/dist/runtime/helpers/uiProvider.js +34 -2
  100. package/dist/runtime/plugins/blokkliEditable.js +74 -3
  101. package/dist/runtime/types/index.d.ts +13 -1
  102. package/package.json +1 -1
  103. package/dist/runtime/components/Edit/DragInteractions/index.vue +0 -401
  104. package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue +0 -54
  105. package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue.d.ts +0 -14
  106. /package/dist/runtime/components/Edit/{DragInteractions → Features/Hover}/index.vue.d.ts +0 -0
@@ -1,58 +1,12 @@
1
1
  <template>
2
- <Teleport to="#bk-indicators">
3
- <div
4
- v-if="shouldRender"
5
- v-show="showOverlay"
6
- class="bk-selection-add"
7
- :class="orientationClass"
8
- :style="containerStyle"
9
- >
10
- <button
11
- ref="before"
12
- :key="'before' + orientationClass"
13
- class="bk-selection-add-button bk-before"
14
- :style="beforeAfterStyle"
15
- :data-title="beforeTooltip"
16
- tabindex="-1"
17
- @click="onClickBefore"
18
- >
19
- <div>
20
- <Icon name="plus" />
21
- </div>
22
- </button>
23
-
24
- <button
25
- ref="after"
26
- :key="'after' + orientationClass"
27
- class="bk-selection-add-button bk-after"
28
- :style="beforeAfterStyle"
29
- :data-title="afterTooltip"
30
- tabindex="-1"
31
- @click="onClickAfter"
32
- >
33
- <div>
34
- <Icon name="plus" />
35
- </div>
36
- </button>
37
- </div>
38
- <AddButtonsField
39
- v-for="(slot, index) in fieldButtonSlots"
40
- v-show="showOverlay"
41
- :key="index"
42
- :field-key="slot.fieldKey"
43
- :container-rect="containerRect"
44
- :title="fieldTooltips[index] || ''"
45
- @click="(el) => onClickEmptyField(index, el)"
46
- />
47
- </Teleport>
48
-
49
- <Teleport to="body">
2
+ <Teleport to="#bk-canvas-overlay">
50
3
  <BlokkliTransition name="caret-tooltip">
51
4
  <Overlay
52
5
  v-if="addData"
53
6
  :key="addData.key"
54
7
  :bundles="addData.allowedBundles"
55
8
  :anchor-el="addData.anchorEl"
9
+ :anchor-coordinates="addData.anchorCoordinates"
56
10
  :label="addData.label"
57
11
  @select="onSelectBundle"
58
12
  @close="closeOverlay"
@@ -60,12 +14,14 @@
60
14
  />
61
15
  </BlokkliTransition>
62
16
  </Teleport>
17
+
18
+ <Renderer @toggle="onRendererToggle" @toggle-field="onRendererToggleField" />
63
19
  </template>
64
20
 
65
21
  <script setup>
66
22
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
67
- import { computed, useBlokkli, ref, watch, useTemplateRef } from "#imports";
68
- import { Icon, BlokkliTransition } from "#blokkli/components";
23
+ import { computed, useBlokkli, ref, watch } from "#imports";
24
+ import { BlokkliTransition } from "#blokkli/components";
69
25
  import {
70
26
  getChildrenOrientation,
71
27
  getGapSize,
@@ -73,19 +29,14 @@ import {
73
29
  determineCanAddChildren
74
30
  } from "#blokkli/helpers/dropTargets";
75
31
  import Overlay from "./Overlay/index.vue";
76
- import AddButtonsField from "./AddButtonsField.vue";
77
32
  import { renderCycle } from "#blokkli/helpers/renderCycle";
78
33
  import { getFieldKey } from "#blokkli/helpers";
79
34
  import { isInternalBundle } from "#blokkli/helpers/bundles";
35
+ import Renderer from "./Renderer/index.vue";
80
36
  const props = defineProps({
81
37
  blocks: { type: Array, required: true }
82
38
  });
83
- const { dom, state, eventBus, types, ui, selection, $t } = useBlokkli();
84
- const showOverlay = computed(
85
- () => !ui.isTransforming.value && !ui.isAnalyzing.value && !selection.isMultiSelecting.value && !selection.isDragging.value && !ui.hasTransformOverlayOpen.value && !selection.isChangingOptions.value
86
- );
87
- const afterEl = useTemplateRef("after");
88
- const beforeEL = useTemplateRef("before");
39
+ const { dom, state, eventBus, types, $t } = useBlokkli();
89
40
  const shouldRender = computed(() => {
90
41
  return props.blocks.length === 1;
91
42
  });
@@ -241,13 +192,8 @@ function onSelectAction(id) {
241
192
  closeOverlay();
242
193
  }
243
194
  const cache = /* @__PURE__ */ new Map();
244
- const canShowBeforeAfter = ref(false);
245
- const beforeAfterStyle = computed(() => ({
246
- visibility: canShowBeforeAfter.value ? "visible" : "hidden"
247
- }));
248
195
  function clearAllCache() {
249
196
  cache.clear();
250
- canShowBeforeAfter.value = false;
251
197
  containerStyle.value = { visibility: "hidden" };
252
198
  orientationClass.value = "";
253
199
  }
@@ -284,7 +230,6 @@ function updateCache(uuid2) {
284
230
  };
285
231
  cache.set(uuid2, cachedState);
286
232
  }
287
- canShowBeforeAfter.value = cachedState.canShowBeforeAfter;
288
233
  orientationClass.value = cachedState.orientation === "vertical" ? "bk-is-vertical" : "bk-is-horizontal";
289
234
  }
290
235
  watch(
@@ -292,7 +237,6 @@ watch(
292
237
  async (newUuid) => {
293
238
  closeOverlay();
294
239
  if (!shouldRender.value) {
295
- canShowBeforeAfter.value = false;
296
240
  containerStyle.value = { visibility: "hidden" };
297
241
  return;
298
242
  }
@@ -303,7 +247,7 @@ watch(
303
247
  },
304
248
  { immediate: true }
305
249
  );
306
- onBlokkliEvent("canvas:draw", () => {
250
+ onBlokkliEvent("animationFrame:after", () => {
307
251
  if (!shouldRender.value || !uuid.value) {
308
252
  containerStyle.value = { visibility: "hidden" };
309
253
  containerRect.value = null;
@@ -337,8 +281,10 @@ onBlokkliEvent("state:reloaded", () => {
337
281
  updateCache(uuid.value);
338
282
  }
339
283
  });
340
- function setAddData(key, field, anchorEl, label, preceedingUuid) {
341
- const allowedBundles = field.allowedBundles;
284
+ function setAddData(key, field, label, preceedingUuid, anchorEl, anchorCoordinates) {
285
+ const allowedBundles = field.allowedBundles.filter(
286
+ (bundle) => !isInternalBundle(bundle)
287
+ );
342
288
  if (allowedBundles.length === 0) {
343
289
  return;
344
290
  }
@@ -362,6 +308,7 @@ function setAddData(key, field, anchorEl, label, preceedingUuid) {
362
308
  preceedingUuid,
363
309
  host,
364
310
  anchorEl,
311
+ anchorCoordinates,
365
312
  label,
366
313
  field
367
314
  };
@@ -382,34 +329,9 @@ function getPreceedingUuidBefore(uuid2, field) {
382
329
  }
383
330
  return void 0;
384
331
  }
385
- function onClickBefore() {
386
- if (addData.value?.key === "before") {
387
- return closeOverlay();
388
- }
389
- if (!uuid.value) {
390
- return;
391
- }
392
- const cachedState = cache.get(uuid.value);
393
- if (!cachedState) {
394
- return;
395
- }
396
- const block2 = dom.findBlock(uuid.value);
397
- if (!block2) {
398
- return;
399
- }
400
- const field = dom.findField(block2.hostUuid, block2.hostFieldName);
401
- if (!field) {
402
- return;
403
- }
404
- const preceedingUuid = getPreceedingUuidBefore(uuid.value, field);
405
- if (!beforeEL.value) {
406
- return;
407
- }
408
- const label = beforeTooltip.value.replace("...", "");
409
- setAddData("before", field, beforeEL.value, label, preceedingUuid);
410
- }
411
- function onClickAfter() {
412
- if (addData.value?.key === "after") {
332
+ function onRendererToggle(data) {
333
+ const key = data.position;
334
+ if (addData.value?.key === key) {
413
335
  return closeOverlay();
414
336
  }
415
337
  if (!uuid.value) {
@@ -427,24 +349,29 @@ function onClickAfter() {
427
349
  if (!field) {
428
350
  return;
429
351
  }
430
- if (!afterEl.value) {
431
- return;
432
- }
433
352
  if (!field.allowedBundles.length) {
434
353
  return;
435
354
  }
436
- const label = afterTooltip.value.replace("...", "");
437
- setAddData("after", field, afterEl.value, label, uuid.value);
355
+ let preceedingUuid;
356
+ let label;
357
+ if (data.position === "before") {
358
+ preceedingUuid = getPreceedingUuidBefore(uuid.value, field);
359
+ label = beforeTooltip.value.replace("...", "");
360
+ } else {
361
+ preceedingUuid = uuid.value;
362
+ label = afterTooltip.value.replace("...", "");
363
+ }
364
+ setAddData(key, field, label, preceedingUuid, void 0, data.coordinates);
438
365
  }
439
- function onClickEmptyField(index, element) {
440
- const key = "field:" + index;
366
+ function onRendererToggleField(data) {
367
+ const key = "field:" + data.index;
441
368
  if (addData.value?.key === key) {
442
369
  return closeOverlay();
443
370
  }
444
371
  if (!uuid.value) {
445
372
  return;
446
373
  }
447
- const emptyField = emptyBlockFields.value[index];
374
+ const emptyField = emptyBlockFields.value[data.index];
448
375
  if (!emptyField) {
449
376
  return;
450
377
  }
@@ -452,8 +379,8 @@ function onClickEmptyField(index, element) {
452
379
  if (!field) {
453
380
  return;
454
381
  }
455
- const label = (fieldTooltips.value[index] || "").replace("...", "");
456
- setAddData(key, field, element, label);
382
+ const label = (fieldTooltips.value[data.index] || "").replace("...", "");
383
+ setAddData(key, field, label, void 0, void 0, data.coordinates);
457
384
  }
458
- onBlokkliEvent("mouse:up", closeOverlay);
385
+ onBlokkliEvent("dragging:start", closeOverlay);
459
386
  </script>
@@ -4,7 +4,8 @@
4
4
 
5
5
  <script setup>
6
6
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
7
- import { useBlokkli, onBeforeUnmount, computed } from "#imports";
7
+ import defineRenderer from "#blokkli/helpers/composables/defineRenderer";
8
+ import { useBlokkli, computed } from "#imports";
8
9
  import {
9
10
  setBuffersAndAttributes,
10
11
  drawBufferInfo,
@@ -17,9 +18,10 @@ import { useTransitionedValue } from "#blokkli/helpers/useTransitionedValue";
17
18
  import { toShaderColor } from "#blokkli/helpers";
18
19
  const props = defineProps({
19
20
  blocks: { type: Array, required: true },
20
- gl: { type: null, required: true }
21
+ gl: { type: null, required: true },
22
+ hasHostSelected: { type: Boolean, required: true }
21
23
  });
22
- const { animation, theme, dom, ui } = useBlokkli();
24
+ const { animation, theme, dom, ui, state } = useBlokkli();
23
25
  const programInfo = animation.registerProgram("selection", props.gl, [vs, fs]);
24
26
  class SelectionRectangleBufferCollector extends RectangleBufferCollector {
25
27
  uuids = [];
@@ -33,11 +35,28 @@ class SelectionRectangleBufferCollector extends RectangleBufferCollector {
33
35
  return uuid + "no_rect";
34
36
  }
35
37
  return uuid + rect.time;
36
- }).join("_");
38
+ }).join("_") + "_host_" + props.hasHostSelected;
37
39
  const hasChanged = force || this.prevKey !== key;
38
40
  if (hasChanged) {
39
41
  this.reset();
40
42
  this.lastCount = 0;
43
+ if (props.hasHostSelected) {
44
+ this.addRectangle(
45
+ {
46
+ id: "host",
47
+ height: ui.artboardSize.value.height,
48
+ width: ui.artboardSize.value.width,
49
+ x: 0,
50
+ y: 0,
51
+ radius: [0, 0, 0, 0],
52
+ isInverted: false,
53
+ isFromLibrary: false
54
+ },
55
+ 3
56
+ // Type 3 = host selection
57
+ );
58
+ this.lastCount++;
59
+ }
41
60
  for (let i = 0; i < props.blocks.length; i++) {
42
61
  const block = props.blocks[i];
43
62
  if (this.added.has(block.uuid)) {
@@ -49,7 +68,14 @@ class SelectionRectangleBufferCollector extends RectangleBufferCollector {
49
68
  if (!rect || !el) {
50
69
  continue;
51
70
  }
52
- const style = theme.getDraggableStyle(el);
71
+ const style = ui.lowPerformanceMode.value ? null : theme.getDraggableStyle(el);
72
+ const isFromLibrary = state.fromLibraryUuids.value.includes(block.uuid);
73
+ let type = 0;
74
+ if (isFromLibrary) {
75
+ type = 2;
76
+ } else if (style?.isInverted) {
77
+ type = 1;
78
+ }
53
79
  this.addRectangle(
54
80
  {
55
81
  id: block.uuid,
@@ -57,10 +83,11 @@ class SelectionRectangleBufferCollector extends RectangleBufferCollector {
57
83
  width: rect.width,
58
84
  x: rect.x,
59
85
  y: rect.y,
60
- radius: style.radius,
61
- isInverted: style.isInverted
86
+ radius: style?.radius ?? [0, 0, 0, 0],
87
+ isInverted: !!style?.isInverted,
88
+ isFromLibrary
62
89
  },
63
- style.isInverted ? 1 : 0
90
+ type
64
91
  );
65
92
  this.lastCount++;
66
93
  }
@@ -76,40 +103,75 @@ const collector = new SelectionRectangleBufferCollector(props.gl);
76
103
  const hasTransformingStyle = computed(
77
104
  () => ui.hasTransformOverlayOpen.value || ui.isTransforming.value
78
105
  );
106
+ const selectionColorOverride = computed(() => {
107
+ const color = ui.selectionColor.value;
108
+ if (!color) {
109
+ return null;
110
+ }
111
+ if (color === "mono") {
112
+ return toShaderColor(theme.getColor(color, "500"));
113
+ } else if (color === "accent") {
114
+ return toShaderColor(theme.getColor(color, "700"));
115
+ }
116
+ return toShaderColor(theme.getColor(color, "normal"));
117
+ });
79
118
  const getColorDefault = useTransitionedValue(() => {
119
+ if (selectionColorOverride.value) {
120
+ return selectionColorOverride.value;
121
+ }
80
122
  if (hasTransformingStyle.value) {
81
123
  return toShaderColor(theme.orange.value.normal);
82
124
  }
83
125
  return toShaderColor(theme.accent.value[600]);
84
126
  });
85
127
  const getColorInverted = useTransitionedValue(() => {
128
+ if (selectionColorOverride.value) {
129
+ return selectionColorOverride.value;
130
+ }
86
131
  if (hasTransformingStyle.value) {
87
132
  return toShaderColor(theme.orange.value.normal);
88
133
  }
89
134
  return toShaderColor([255, 255, 255]);
90
135
  });
136
+ const getColorLibrary = useTransitionedValue(() => {
137
+ if (selectionColorOverride.value) {
138
+ return selectionColorOverride.value;
139
+ }
140
+ if (hasTransformingStyle.value) {
141
+ return toShaderColor(theme.orange.value.normal);
142
+ }
143
+ return toShaderColor(theme.lime.value.normal);
144
+ });
145
+ const getColorHost = useTransitionedValue(() => {
146
+ return toShaderColor(theme.mono.value[700]);
147
+ });
91
148
  const getTransforming = useTransitionedValue(() => {
92
149
  return ui.isTransforming.value ? 1 : 0;
93
150
  });
94
- onBlokkliEvent("canvas:draw", (e) => {
95
- props.gl.useProgram(programInfo.program);
96
- const { info, hasChanged } = collector.getBufferInfo();
97
- if (!info) {
98
- return;
151
+ defineRenderer("selection-overlay", {
152
+ zIndex: 100,
153
+ render: (ctx) => {
154
+ props.gl.useProgram(programInfo.program);
155
+ const { info } = collector.getBufferInfo();
156
+ if (!info) {
157
+ return;
158
+ }
159
+ setUniforms(programInfo, {
160
+ u_color_default: getColorDefault(),
161
+ u_color_inverted: getColorInverted(),
162
+ u_color_library: getColorLibrary(),
163
+ u_color_host: getColorHost(),
164
+ u_artboard_size: [
165
+ ui.artboardSize.value.width,
166
+ ui.artboardSize.value.height
167
+ ],
168
+ u_is_transforming: getTransforming(),
169
+ u_time: ctx.time
170
+ });
171
+ animation.setSharedUniforms(props.gl, programInfo);
172
+ setBuffersAndAttributes(props.gl, programInfo, info);
173
+ drawBufferInfo(props.gl, info, props.gl.TRIANGLES);
99
174
  }
100
- setUniforms(programInfo, {
101
- u_color_default: getColorDefault(),
102
- u_color_inverted: getColorInverted(),
103
- u_artboard_size: [
104
- ui.artboardSize.value.width,
105
- ui.artboardSize.value.height
106
- ],
107
- u_is_transforming: getTransforming(),
108
- u_time: e.time
109
- });
110
- animation.setSharedUniforms(props.gl, programInfo);
111
- setBuffersAndAttributes(props.gl, programInfo, info);
112
- drawBufferInfo(props.gl, info, props.gl.TRIANGLES);
113
175
  });
114
176
  onBlokkliEvent("ui:resized", function() {
115
177
  collector.reset();
@@ -117,9 +179,6 @@ onBlokkliEvent("ui:resized", function() {
117
179
  onBlokkliEvent("state:reloaded", function() {
118
180
  collector.reset();
119
181
  });
120
- onBeforeUnmount(() => {
121
- props.gl.clear(props.gl.COLOR_BUFFER_BIT);
122
- });
123
182
  </script>
124
183
 
125
184
  <script>
@@ -2,8 +2,10 @@ import type { DraggableExistingBlock } from '#blokkli/types';
2
2
  declare const _default: import("vue").DefineComponent<{
3
3
  blocks: DraggableExistingBlock[];
4
4
  gl: WebGLRenderingContext;
5
+ hasHostSelected: boolean;
5
6
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
6
7
  blocks: DraggableExistingBlock[];
7
8
  gl: WebGLRenderingContext;
9
+ hasHostSelected: boolean;
8
10
  }> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
11
  export default _default;
@@ -18,6 +18,8 @@ uniform float u_offset_y;
18
18
  uniform vec2 u_resolution;
19
19
  uniform vec3 u_color_default;
20
20
  uniform vec3 u_color_inverted;
21
+ uniform vec3 u_color_library;
22
+ uniform vec3 u_color_host;
21
23
 
22
24
  // The transformed quad for the fragment shader.
23
25
  varying vec4 v_quad;
@@ -79,8 +81,15 @@ void main() {
79
81
 
80
82
  v_rect_width = adjusted_quad.x;
81
83
 
82
- // Set color and other varying variables
83
- v_color = a_rect_type > 0.5 ? u_color_inverted : u_color_default;
84
+ // Set color based on type: 0=default, 1=inverted, 2=library, 3=host
85
+ v_color = u_color_default;
86
+ if (a_rect_type > 2.5) {
87
+ v_color = u_color_host;
88
+ } else if (a_rect_type > 1.5) {
89
+ v_color = u_color_library;
90
+ } else if (a_rect_type > 0.5) {
91
+ v_color = u_color_inverted;
92
+ }
84
93
  v_rect_radius = a_rect_radius * u_dpi;
85
94
  v_thickness = thickness;
86
95
  v_rect_id = a_rect_id;
@@ -4,17 +4,9 @@
4
4
  :blocks="selection.blocks.value"
5
5
  :uuids="selection.uuids.value"
6
6
  :gl="gl"
7
+ :has-host-selected="selection.hasHostSelected.value"
7
8
  />
8
9
  <OverlayFallback v-if="isVisible && !gl" :uuids="selection.uuids.value" />
9
- <Teleport :to="artboardElement">
10
- <div
11
- class="bk bk-host-selection-overlay"
12
- :style="{
13
- visibility: selection.hasHostSelected.value ? 'visible' : 'hidden'
14
- }"
15
- />
16
- </Teleport>
17
-
18
10
  <PluginItemDropdown
19
11
  v-if="itemDropdownItems.length"
20
12
  id="selection"
@@ -105,7 +97,6 @@ function onSelectDropdownItem(item) {
105
97
  selectAllBlocks();
106
98
  }
107
99
  }
108
- const artboardElement = ui.artboardElement();
109
100
  const gl = animation.gl();
110
101
  const hasSelectedOnce = ref(false);
111
102
  const stop = watch(
@@ -254,8 +245,10 @@ onBlokkliEvent("keyPressed", (e) => {
254
245
  return;
255
246
  }
256
247
  if (e.code === "Escape") {
257
- eventBus.emit("select:end", []);
258
- eventBus.emit("select:host:unselect");
248
+ if (!ui.openTooltip.value) {
249
+ eventBus.emit("select:end", []);
250
+ eventBus.emit("select:host:unselect");
251
+ }
259
252
  } else if (e.code === "Tab") {
260
253
  if (tour.isTouring.value || ui.hasDialogOpen.value) {
261
254
  return;
@@ -1,21 +1,21 @@
1
1
  <template>
2
- <div class="bk bk-translations-banner">
3
- <Icon name="translate" />
4
- <p v-html="text" />
5
- <button class="bk-translations-banner-close" @click="onClick">
6
- {{ $t("translationsBannerButton", "Edit source language instead") }}
7
- <Icon name="close" />
8
- </button>
9
- </div>
2
+ <Banner
3
+ id="translate"
4
+ icon="translate"
5
+ :text
6
+ :button="$t('translationsBannerButton', 'Edit source language instead')"
7
+ scheme="yellow"
8
+ @click="onClick"
9
+ />
10
10
  </template>
11
11
 
12
12
  <script setup>
13
- import { computed, useBlokkli } from "#imports";
14
- import { Icon } from "#blokkli/components";
13
+ import { computed, useBlokkli, onMounted, onBeforeUnmount } from "#imports";
14
+ import { Banner } from "#blokkli/components";
15
15
  const props = defineProps({
16
16
  activeLanguage: { type: Object, required: true }
17
17
  });
18
- const { $t, adapter, state } = useBlokkli();
18
+ const { $t, adapter, state, ui } = useBlokkli();
19
19
  const onClick = () => {
20
20
  const sourceLanguage = state.translation.value.sourceLanguage;
21
21
  if (!sourceLanguage) {
@@ -39,4 +39,10 @@ const text = computed(() => {
39
39
  "You are currently editing the <strong>@language</strong> translation. Some features like adding, moving or deleting blocks are not available."
40
40
  ).replace("@language", props.activeLanguage.name);
41
41
  });
42
+ onMounted(() => {
43
+ ui.setSelectionColor("translating", "mono");
44
+ });
45
+ onBeforeUnmount(() => {
46
+ ui.removeSelectionColor("translating");
47
+ });
42
48
  </script>
@@ -48,11 +48,8 @@
48
48
  </PluginTourItem>
49
49
  </Teleport>
50
50
 
51
- <Teleport to="#bk-banner-container">
52
- <Banner
53
- v-if="state.editMode.value === 'translating'"
54
- :active-language="activeLanguage"
55
- />
51
+ <Teleport to="#bk-banner-list">
52
+ <Banner v-if="isTranslating" :active-language />
56
53
  </Teleport>
57
54
 
58
55
  <PluginMenuButton
@@ -61,14 +58,14 @@
61
58
  :description="
62
59
  $t('translationsBatchTranslateMenuDescription', 'Translate all blocks')
63
60
  "
64
- :disabled="editMode !== 'translating'"
61
+ :disabled="!isTranslating"
65
62
  :weight="60"
66
63
  icon="translate"
67
64
  @click="eventBus.emit('batchTranslate')"
68
65
  />
69
66
 
70
67
  <PluginItemAction
71
- v-if="editMode === 'translating'"
68
+ v-if="isTranslating"
72
69
  id="translate"
73
70
  :disabled="!canTranslateBlock"
74
71
  :title="$t('translationsItemAction', 'Translate')"
@@ -102,7 +99,7 @@ const { adapter } = defineBlokkliFeature({
102
99
  description: "Adds support for block translations."
103
100
  });
104
101
  const { eventBus, state, context, $t, ui, selection, types, definitions } = useBlokkli();
105
- const { translation, editMode } = state;
102
+ const isTranslating = computed(() => state.editMode.value === "translating");
106
103
  const isOpen = ref(false);
107
104
  const isDropdown = computed(() => {
108
105
  if (ui.isMobile.value) {
@@ -113,7 +110,7 @@ const isDropdown = computed(() => {
113
110
  });
114
111
  const activeLangcode = computed(() => context.value.language);
115
112
  const activeLanguage = computed(() => {
116
- return translation.value.availableLanguages?.find(
113
+ return state.translation.value.availableLanguages?.find(
117
114
  (v) => v.id === activeLangcode.value
118
115
  ) || {
119
116
  id: activeLangcode.value,
@@ -121,14 +118,14 @@ const activeLanguage = computed(() => {
121
118
  };
122
119
  });
123
120
  const items = computed(() => {
124
- return (translation.value.availableLanguages || []).map((language) => {
121
+ return (state.translation.value.availableLanguages || []).map((language) => {
125
122
  if (language && language.id) {
126
123
  return {
127
124
  id: language.id,
128
125
  code: language.id.toUpperCase(),
129
126
  label: language.name,
130
127
  checked: context.value.language === language.id,
131
- translation: (translation.value.translations || []).find(
128
+ translation: (state.translation.value.translations || []).find(
132
129
  (v) => v.id === language.id
133
130
  )
134
131
  };
@@ -180,12 +177,12 @@ function onTranslate(items2) {
180
177
  }
181
178
  }
182
179
  onBlokkliEvent("item:doubleClick", function(block) {
183
- if (editMode.value === "translating" && canTranslateBlock.value) {
180
+ if (isTranslating.value && canTranslateBlock.value) {
184
181
  onTranslate([block]);
185
182
  }
186
183
  });
187
184
  onBlokkliEvent("entity:translated", (langcode) => {
188
- const targetTranslation = translation.value.translations?.find(
185
+ const targetTranslation = state.translation.value.translations?.find(
189
186
  (v) => v.id === langcode
190
187
  );
191
188
  if (targetTranslation) {
@@ -193,12 +190,12 @@ onBlokkliEvent("entity:translated", (langcode) => {
193
190
  }
194
191
  });
195
192
  onMounted(() => {
196
- const translationExists = !!translation.value.translations?.find(
193
+ const translationExists = !!state.translation.value.translations?.find(
197
194
  (v) => v.id === context.value.language
198
195
  );
199
196
  if (!translationExists) {
200
- const sourceTranslation = translation.value.translations?.find(
201
- (v) => v.id === translation.value.sourceLanguage
197
+ const sourceTranslation = state.translation.value.translations?.find(
198
+ (v) => v.id === state.translation.value.sourceLanguage
202
199
  );
203
200
  if (sourceTranslation) {
204
201
  return adapter.changeLanguage(sourceTranslation);
@@ -27,7 +27,8 @@ defineProps({
27
27
  required: { type: Boolean, required: false },
28
28
  disabled: { type: Boolean, required: false },
29
29
  minlength: { type: [String, Number], required: false },
30
- maxlength: { type: [String, Number], required: false }
30
+ maxlength: { type: [String, Number], required: false },
31
+ type: { type: String, required: false }
31
32
  });
32
33
  const value = defineModel({ type: String });
33
34
  </script>
@@ -7,6 +7,7 @@ type __VLS_Props = {
7
7
  disabled?: boolean;
8
8
  minlength?: string | number;
9
9
  maxlength?: string | number;
10
+ type?: string;
10
11
  };
11
12
  type __VLS_PublicProps = __VLS_Props & {
12
13
  modelValue?: string;
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Teleport to="body">
2
+ <Teleport to="#bk-canvas-overlay">
3
3
  <div id="bk-indicators" class="bk bk-indicators" :style>
4
4
  <div id="bk-indicators-left" />
5
5
  <div id="bk-indicators-right" />