@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
@@ -40,7 +40,18 @@ const { adapter } = defineBlokkliFeature({
40
40
  description: "Renders an overlay when dragging or placing a block.",
41
41
  screenshot: "feature-dragging-overlay.jpg"
42
42
  });
43
- const { eventBus, state, ui, animation, dom, selection, definitions } = useBlokkli();
43
+ const {
44
+ eventBus,
45
+ state,
46
+ ui,
47
+ animation,
48
+ dom,
49
+ selection,
50
+ definitions,
51
+ blocks,
52
+ directive,
53
+ fields
54
+ } = useBlokkli();
44
55
  const dragItemsComponent = ref(null);
45
56
  const isVisible = ref(false);
46
57
  const isTouching = ref(false);
@@ -77,7 +88,7 @@ function filterItemType(items) {
77
88
  return { itemType, item: items[0] };
78
89
  }
79
90
  const onDropNew = async (bundle, host, afterUuid) => {
80
- const field = dom.findField(host.uuid, host.fieldName);
91
+ const field = fields.find(host.uuid, host.fieldName);
81
92
  if (!field) {
82
93
  throw new Error(
83
94
  `Failed to locate field with name "${host.fieldName}" on UUID "${host.uuid}"`
@@ -106,7 +117,7 @@ const onDropNew = async (bundle, host, afterUuid) => {
106
117
  }
107
118
  };
108
119
  const onDropExisting = async (items, host, afterUuid) => {
109
- const uuids = items.map((v) => v.uuid);
120
+ const uuids = items.map((v) => v.block.uuid);
110
121
  await state.mutateWithLoadingState(
111
122
  () => adapter.moveMultipleBlocks({
112
123
  uuids,
@@ -224,15 +235,15 @@ onBlokkliEvent("state:reloaded", async function() {
224
235
  }
225
236
  eventBus.emit("select", newUuid);
226
237
  await renderCycle();
227
- const newBlock = dom.findBlock(newUuid);
238
+ const newBlock = blocks.getBlock(newUuid);
228
239
  if (!newBlock) {
229
240
  return;
230
241
  }
231
242
  const allSelected = [...selection.uuids.value, newBlock.uuid];
232
243
  eventBus.emit("select", allSelected);
233
244
  const definition = definitions.getBlockDefinition(
234
- newBlock.itemBundle,
235
- newBlock.hostFieldListType
245
+ newBlock.bundle,
246
+ newBlock.fieldListType
236
247
  );
237
248
  if (!definition?.editor?.addBehaviour?.startsWith("editable:")) {
238
249
  return;
@@ -241,8 +252,8 @@ onBlokkliEvent("state:reloaded", async function() {
241
252
  if (!editableField) {
242
253
  return;
243
254
  }
244
- const editableFieldElement = newBlock.element().querySelector(`[data-blokkli-editable-field="${editableField}"]`);
245
- if (!(editableFieldElement instanceof HTMLElement)) {
255
+ const editableFieldElement = directive.getEditablesForBlock(newUuid).find((v) => v.fieldName === editableField);
256
+ if (!editableFieldElement) {
246
257
  return;
247
258
  }
248
259
  eventBus.emit("editable:focus", {
@@ -283,17 +294,15 @@ onBlokkliEvent("dragging:start", (e) => {
283
294
  mouseY.value = e.coords.y;
284
295
  dom.updateVisibleRects();
285
296
  dragItems.value = e.items;
286
- if ("element" in item) {
287
- if (!isTouching.value) {
288
- document.removeEventListener("pointerup", onMouseUp);
289
- document.addEventListener("pointerup", onMouseUp);
290
- document.removeEventListener("pointermove", onMouseMove, {
291
- capture: true
292
- });
293
- document.addEventListener("pointermove", onMouseMove, { capture: true });
294
- }
295
- eventBus.on("animationFrame", loop);
297
+ if (!isTouching.value) {
298
+ document.removeEventListener("pointerup", onMouseUp);
299
+ document.addEventListener("pointerup", onMouseUp);
300
+ document.removeEventListener("pointermove", onMouseMove, {
301
+ capture: true
302
+ });
303
+ document.addEventListener("pointermove", onMouseMove, { capture: true });
296
304
  }
305
+ eventBus.on("animationFrame", loop);
297
306
  });
298
307
  onBlokkliEvent("dragging:end", () => {
299
308
  isVisible.value = false;
@@ -303,6 +312,9 @@ onBlokkliEvent("dragging:end", () => {
303
312
  document.removeEventListener("pointermove", onMouseMove, { capture: true });
304
313
  });
305
314
  onBlokkliEvent("keyPressed", (e) => {
315
+ if (ui.hasDialogOpen.value) {
316
+ return;
317
+ }
306
318
  if (e.code === "Escape") {
307
319
  eventBus.emit("dragging:end");
308
320
  }
@@ -3,6 +3,7 @@
3
3
  id="duplicate"
4
4
  :title="$t('duplicate', 'Duplicate')"
5
5
  :disabled="!canDuplicate"
6
+ edit-only
6
7
  meta
7
8
  key-code="D"
8
9
  multiple
@@ -31,22 +32,19 @@ function onClick(items) {
31
32
  );
32
33
  }
33
34
  const canDuplicate = computed(() => {
34
- if (state.editMode.value !== "editing") {
35
- return false;
36
- }
37
35
  const blocksByField = {};
38
36
  const fieldsByKey = {};
39
- const selectedCount = selection.blocks.value.length;
37
+ const selectedCount = selection.items.value.length;
40
38
  for (let i = 0; i < selectedCount; i++) {
41
- const block = selection.blocks.value[i];
42
- const field = state.getMutatedField(block.hostUuid, block.hostFieldName);
39
+ const block = selection.items.value[i];
40
+ const field = state.getMutatedField(block.host.uuid, block.host.fieldName);
43
41
  if (!field) {
44
42
  continue;
45
43
  }
46
44
  const fieldKey = getFieldKey(field.entityUuid, field.name);
47
45
  const fieldConfig = types.getFieldConfig(
48
46
  field.entityType,
49
- block.hostBundle,
47
+ block.host.bundle,
50
48
  field.name
51
49
  );
52
50
  if (!fieldConfig) {
@@ -77,7 +75,7 @@ const canDuplicate = computed(() => {
77
75
  if (field.cardinality !== -1 && count + blocks.length > field.cardinality) {
78
76
  return false;
79
77
  }
80
- const bundles = blocks.map((v) => v.itemBundle);
78
+ const bundles = blocks.map((v) => v.bundle);
81
79
  if (!field.allowedBundles.length || bundles.some((bundle) => !field.allowedBundles.includes(bundle))) {
82
80
  return false;
83
81
  }
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <PluginItemAction
3
- v-if="isEditing"
4
3
  id="edit"
5
- :title="$t('edit', 'Edit')"
4
+ edit-only
5
+ :title="$t('edit', 'Edit...')"
6
6
  :disabled="!canEdit"
7
7
  meta
8
8
  key-code="E"
@@ -24,27 +24,21 @@ defineBlokkliFeature({
24
24
  requiredAdapterMethods: ["formFrameBuilder"]
25
25
  });
26
26
  const { eventBus, selection, state, $t, adapter, definitions } = useBlokkli();
27
- const block = computed(() => {
28
- if (selection.blocks.value.length !== 1) {
29
- return null;
30
- }
31
- return selection.blocks.value[0];
32
- });
33
- const isEditing = computed(() => state.editMode.value === "editing");
34
27
  const canEdit = computed(() => {
35
- if (!block.value) {
28
+ const item = selection.item.value;
29
+ if (!item) {
36
30
  return false;
37
31
  }
38
32
  const definition = definitions.getBlockDefinition(
39
- block.value.itemBundle,
40
- block.value.hostFieldListType,
41
- block.value.parentBlockBundle
33
+ item.bundle,
34
+ item.fieldListType,
35
+ item.parentBlockBundle
42
36
  );
43
37
  if (definition?.editor?.disableEdit) {
44
38
  return false;
45
39
  }
46
- if (block.value.libraryItemUuid) {
47
- return !!adapter.getLibraryItemEditUrl && (state.editMode.value === "editing" || state.editMode.value === "translating") && !block.value.isNew;
40
+ if (item.library?.libraryItemUuid) {
41
+ return !!adapter.getLibraryItemEditUrl && (state.editMode.value === "editing" || state.editMode.value === "translating") && !item.isNew;
48
42
  }
49
43
  return state.editMode.value === "editing";
50
44
  });
@@ -56,22 +50,22 @@ function onClick(items) {
56
50
  return;
57
51
  }
58
52
  const item = items[0];
59
- if (item.libraryItemUuid && adapter.getLibraryItemEditUrl) {
60
- const url = adapter.getLibraryItemEditUrl(item.libraryItemUuid);
53
+ if (item.library?.libraryItemUuid && adapter.getLibraryItemEditUrl) {
54
+ const url = adapter.getLibraryItemEditUrl(item.library.libraryItemUuid);
61
55
  eventBus.emit("library:edit-item", {
62
56
  url,
63
- label: item.editTitle,
64
- uuid: item.libraryItemUuid
57
+ label: item.library.label,
58
+ uuid: item.library.libraryItemUuid
65
59
  });
66
60
  return;
67
61
  }
68
62
  eventBus.emit("item:edit", {
69
63
  uuid: item.uuid,
70
- bundle: item.itemBundle
64
+ bundle: item.bundle
71
65
  });
72
66
  }
73
- onBlokkliEvent("item:doubleClick", function(block2) {
74
- onClick([block2]);
67
+ onBlokkliEvent("item:doubleClick", function(block) {
68
+ onClick([block]);
75
69
  });
76
70
  </script>
77
71
 
@@ -24,6 +24,7 @@ import { ref, computed, useBlokkli, defineBlokkliFeature } from "#imports";
24
24
  import { FormOverlay, BlokkliTransition } from "#blokkli/components";
25
25
  import FormFrame from "./Frame/index.vue";
26
26
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
27
+ import { itemEntityType } from "#blokkli-build/config";
27
28
  const { adapter } = defineBlokkliFeature({
28
29
  id: "edit-form",
29
30
  icon: "form",
@@ -31,7 +32,7 @@ const { adapter } = defineBlokkliFeature({
31
32
  description: "Listens to edit events and renders an iframe containing the edit form.",
32
33
  requiredAdapterMethods: ["formFrameBuilder"]
33
34
  });
34
- const { types, state, context, $t, dom, definitions } = useBlokkli();
35
+ const { types, state, context, $t, dom, definitions, blocks } = useBlokkli();
35
36
  const form = ref(null);
36
37
  const formUrl = computed(() => {
37
38
  if (form.value) {
@@ -99,13 +100,13 @@ onBlokkliEvent("item:edit", (e) => {
99
100
  if (!state.canEdit.value) {
100
101
  return;
101
102
  }
102
- const block = dom.findBlock(e.uuid);
103
+ const block = blocks.getBlock(e.uuid);
103
104
  if (!block) {
104
105
  return;
105
106
  }
106
107
  const definition = definitions.getBlockDefinition(
107
108
  e.bundle,
108
- block.hostFieldListType,
109
+ block.fieldListType,
109
110
  block.parentBlockBundle
110
111
  );
111
112
  if (definition?.editor?.disableEdit) {
@@ -156,12 +157,12 @@ onBlokkliEvent("add:block:new", (e) => {
156
157
  if (!state.canEdit.value) {
157
158
  return;
158
159
  }
159
- const field = dom.findField(e.host.uuid, e.host.fieldName);
160
- if (field) {
160
+ const field = dom.getRegisteredField(e.host.uuid, e.host.fieldName);
161
+ if (field?.entity.type === itemEntityType) {
161
162
  const definition = definitions.getBlockDefinition(
162
163
  e.bundle,
163
164
  field.fieldListType,
164
- field.hostEntityBundle
165
+ field.entity.bundle
165
166
  );
166
167
  if (definition?.editor?.disableEdit) {
167
168
  return;
@@ -4,13 +4,24 @@
4
4
  ref="iframe"
5
5
  :style="{ height: Math.max(height, 150) + 'px' }"
6
6
  :src="url"
7
+ @load="onIframeLoad"
7
8
  />
8
9
  </div>
9
10
  </template>
10
11
 
11
12
  <script setup>
12
- import { useBlokkli, ref, computed, onMounted, onBeforeUnmount } from "#imports";
13
- const { adapter } = useBlokkli();
13
+ import {
14
+ useBlokkli,
15
+ ref,
16
+ computed,
17
+ onMounted,
18
+ onBeforeUnmount,
19
+ useTemplateRef
20
+ } from "#imports";
21
+ import { itemEntityType } from "#blokkli-build/config";
22
+ const { adapter, ui, element } = useBlokkli();
23
+ const PROPAGATE_WHEEL = false;
24
+ const rootElement = ui.rootElement();
14
25
  const props = defineProps({
15
26
  modelValue: { type: String, required: true },
16
27
  type: { type: String, required: true },
@@ -18,9 +29,63 @@ const props = defineProps({
18
29
  host: { type: Object, required: true },
19
30
  initialHeight: { type: Number, required: true }
20
31
  });
32
+ const iframe = useTemplateRef("iframe");
33
+ function onIframeLoad() {
34
+ if (!iframe.value || !PROPAGATE_WHEEL) {
35
+ return;
36
+ }
37
+ const iframeDoc = iframe.value.contentDocument;
38
+ if (!iframeDoc) {
39
+ return;
40
+ }
41
+ let ckEditor = null;
42
+ iframe.value.contentDocument.addEventListener("wheel", (e) => {
43
+ if (!ckEditor) {
44
+ const el = element.query(
45
+ iframeDoc.documentElement,
46
+ ".ck-editor__editable",
47
+ "Find CKEditor in editable iframe."
48
+ );
49
+ if (el) {
50
+ ckEditor = el;
51
+ }
52
+ }
53
+ if (!ckEditor) {
54
+ return;
55
+ }
56
+ const scrollTop = ckEditor.scrollTop;
57
+ const scrollHeight = ckEditor.scrollHeight;
58
+ const clientHeight = ckEditor.clientHeight;
59
+ const isScrolledToTop = scrollTop === 0;
60
+ const isScrolledToBottom = scrollTop + clientHeight >= scrollHeight - 1;
61
+ const isScrollingDown = e.deltaY > 0;
62
+ const isScrollingUp = e.deltaY < 0;
63
+ const shouldPropagate = isScrollingUp && isScrolledToTop || isScrollingDown && isScrolledToBottom;
64
+ if (!shouldPropagate) {
65
+ return;
66
+ }
67
+ const wheelEvent = new WheelEvent("wheel", {
68
+ deltaX: e.deltaX,
69
+ deltaY: e.deltaY,
70
+ deltaZ: e.deltaZ,
71
+ deltaMode: e.deltaMode,
72
+ clientX: e.clientX,
73
+ clientY: e.clientY,
74
+ screenX: e.screenX,
75
+ screenY: e.screenY,
76
+ bubbles: true,
77
+ cancelable: true,
78
+ ctrlKey: e.ctrlKey,
79
+ shiftKey: e.shiftKey,
80
+ altKey: e.altKey,
81
+ metaKey: e.metaKey
82
+ });
83
+ rootElement?.dispatchEvent(wheelEvent);
84
+ });
85
+ }
21
86
  const height = ref(props.initialHeight);
22
87
  const url = computed(() => {
23
- if ("itemBundle" in props.host) {
88
+ if (props.host.type === itemEntityType) {
24
89
  return adapter.buildEditableFrameUrl({
25
90
  uuid: props.host.uuid,
26
91
  fieldName: props.fieldName
@@ -43,7 +108,7 @@ const onMessage = (e) => {
43
108
  };
44
109
  onMounted(() => {
45
110
  original.value = props.modelValue;
46
- height.value = props.initialHeight + 48;
111
+ height.value = props.initialHeight;
47
112
  window.addEventListener("message", onMessage);
48
113
  });
49
114
  onBeforeUnmount(() => {
@@ -1,9 +1,9 @@
1
- import type { DraggableExistingBlock, EditableFieldType, EntityContext } from '#blokkli/types';
1
+ import type { EditableFieldType, EntityContext } from '#blokkli/types';
2
2
  type __VLS_Props = {
3
3
  modelValue: string;
4
4
  type: EditableFieldType;
5
5
  fieldName: string;
6
- host: DraggableExistingBlock | EntityContext;
6
+ host: EntityContext;
7
7
  initialHeight: number;
8
8
  };
9
9
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
@@ -1,11 +1,16 @@
1
1
  <template>
2
- <div class="bk bk-editable-field-textarea">
2
+ <div
3
+ class="bk bk-editable-field-textarea"
4
+ :style="{
5
+ height: height + 'px'
6
+ }"
7
+ >
3
8
  <textarea
9
+ id="bk-editable-field-textarea"
4
10
  ref="input"
5
11
  :value="modelValue"
6
12
  enterkeyhint="done"
7
13
  rows="2"
8
- :style="inputStyle"
9
14
  v-bind="inputAttributes"
10
15
  @keydown.stop.capture="onKeyDown"
11
16
  @blur="onBlur"
@@ -13,12 +18,12 @@
13
18
  $emit('update:modelValue', $event.target.value)
14
19
  "
15
20
  />
16
- <div :style="inputStyle" class="bk-textarea" v-html="modelValue" />
17
21
  </div>
18
22
  </template>
19
23
 
20
24
  <script setup>
21
- import { useBlokkli, computed } from "#imports";
25
+ import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
26
+ import { useBlokkli, computed, useTemplateRef, ref } from "#imports";
22
27
  const { ui, selection } = useBlokkli();
23
28
  const props = defineProps({
24
29
  element: { type: null, required: true },
@@ -27,6 +32,8 @@ const props = defineProps({
27
32
  modelValue: { type: String, required: true }
28
33
  });
29
34
  const emit = defineEmits(["close", "save", "update:modelValue"]);
35
+ const input = useTemplateRef("input");
36
+ const height = ref(20);
30
37
  const onKeyDown = (e) => {
31
38
  if (e.code === "Escape") {
32
39
  e.preventDefault();
@@ -61,10 +68,7 @@ const onBlur = (e) => {
61
68
  emit("save");
62
69
  }, 100);
63
70
  };
64
- const inputStyle = computed(() => {
65
- const computedStyle = window.getComputedStyle(props.element);
66
- return {
67
- textAlign: computedStyle.textAlign
68
- };
71
+ onBlokkliEvent("animationFrame", () => {
72
+ height.value = Math.max(input.value?.scrollHeight ?? 20, 20);
69
73
  });
70
74
  </script>
@@ -1,26 +1,15 @@
1
1
  <template>
2
- <div
2
+ <ArtboardTooltip
3
3
  v-if="loaded"
4
- ref="root"
5
- :style="style"
6
- class="bk-editable-field bk-control"
4
+ id="editable"
5
+ :title
6
+ :anchor-el="element"
7
+ placement-y="top"
8
+ class="bk-editable-field"
9
+ close-icon="check"
10
+ @close="save"
7
11
  >
8
12
  <form ref="form" class="bk-editable-field-input" @submit.prevent="close">
9
- <div class="bk bk-editable-field-buttons">
10
- <h3>
11
- <ItemIcon :bundle="itemBundle" />
12
- <span>{{ title }}</span>
13
- </h3>
14
- <button @click.prevent="cancel">
15
- <Icon name="close" />
16
- <span>{{ $t("cancel", "Cancel") }}</span>
17
- </button>
18
- <button :disabled="!hasChanged" type="submit" @click.prevent="save">
19
- <Icon name="save" />
20
- <span>{{ $t("save", "Save") }}</span>
21
- </button>
22
- </div>
23
-
24
13
  <div ref="input">
25
14
  <InputContenteditable
26
15
  v-if="config.type === 'markup'"
@@ -50,21 +39,24 @@
50
39
  />
51
40
  </div>
52
41
 
53
- <div v-if="!isMarkup" class="bk bk-editable-field-info">
42
+ <div class="bk bk-editable-field-info">
43
+ <button :disabled="!hasChanged" @click.prevent="cancel">
44
+ {{ $t("editableFieldDiscard", "Discard") }}
45
+ </button>
54
46
  <div v-if="errorText" class="bk-editable-field-info-error">
55
47
  {{ errorText }}
56
48
  </div>
57
- <div class="bk-editable-field-info-count">
49
+ <div v-if="!isMarkup" class="bk-editable-field-info-count">
58
50
  <span>{{ count }}</span>
59
51
  <span v-if="maxlength >= 1">&nbsp;/&nbsp;{{ maxlength }}</span>
60
52
  </div>
61
53
  </div>
62
54
  </form>
63
- </div>
55
+ </ArtboardTooltip>
64
56
  </template>
65
57
 
66
58
  <script setup>
67
- import { Icon, ItemIcon } from "#blokkli/components";
59
+ import { ArtboardTooltip } from "#blokkli/components";
68
60
  import {
69
61
  computed,
70
62
  ref,
@@ -74,12 +66,21 @@ import {
74
66
  useBlokkli,
75
67
  nextTick
76
68
  } from "#imports";
77
- import { falsy, findIdealRectPosition } from "#blokkli/helpers";
69
+ import { falsy } from "#blokkli/helpers";
78
70
  import InputPlaintext from "./Plaintext/index.vue";
79
71
  import InputContenteditable from "./Contenteditable/index.vue";
80
72
  import InputFrame from "./Frame/index.vue";
81
73
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
82
- const { eventBus, ui, selection, state, adapter, $t, types } = useBlokkli();
74
+ import { itemEntityType } from "#blokkli-build/config";
75
+ const {
76
+ eventBus,
77
+ selection,
78
+ state,
79
+ adapter,
80
+ $t,
81
+ types,
82
+ element: elementProvider
83
+ } = useBlokkli();
83
84
  const props = defineProps({
84
85
  fieldName: { type: String, required: true },
85
86
  host: { type: Object, required: true },
@@ -102,48 +103,15 @@ const save = () => {
102
103
  };
103
104
  onBlokkliEvent("window:clickAway", save);
104
105
  const getElement = () => props.element;
105
- const alignment = computed(() => {
106
- if (props.element) {
107
- const style2 = window.getComputedStyle(props.element);
108
- if (style2.textAlign === "left" || style2.textAlign === "center" || style2.textAlign === "right") {
109
- return style2.textAlign;
110
- } else if (style2.textAlign === "start") {
111
- return "left";
112
- } else if (style2.textAlign === "end") {
113
- return "right";
114
- }
115
- }
116
- return "center";
117
- });
118
106
  const scrollHeight = ref(0);
119
107
  const loaded = ref(false);
120
108
  const originalText = ref(props.value || "");
121
109
  const modelValue = ref("");
122
- const width = ref(320);
123
110
  const inputStyle = ref({});
124
111
  const form = ref(null);
125
- const root = ref(null);
126
112
  const input = ref(null);
127
- const x = ref(0);
128
- const y = ref(0);
129
- const style = computed(() => {
130
- if (ui.isMobile.value) {
131
- return {};
132
- } else {
133
- return {
134
- width: width.value + "px",
135
- top: y.value + "px",
136
- left: x.value + "px"
137
- };
138
- }
139
- });
140
113
  const hasChanged = computed(() => modelValue.value !== originalText.value);
141
- const itemBundle = computed(() => {
142
- if ("itemBundle" in props.host) {
143
- return props.host.itemBundle;
144
- }
145
- return void 0;
146
- });
114
+ const itemBundle = computed(() => props.host.bundle);
147
115
  const maxlength = computed(() => props.config.maxLength);
148
116
  const required = computed(() => !!props.config.required);
149
117
  const title = computed(() => {
@@ -174,7 +142,7 @@ const close = async () => {
174
142
  }
175
143
  const el = getElement();
176
144
  if (shouldSave.value && modelValue.value !== originalText.value) {
177
- if ("itemBundle" in props.host) {
145
+ if (props.host.type === itemEntityType) {
178
146
  await state.mutateWithLoadingState(
179
147
  () => adapter.updateFieldValue({
180
148
  uuid: props.host.uuid,
@@ -223,44 +191,34 @@ const focusInput = (el) => {
223
191
  if (!el) {
224
192
  return;
225
193
  }
226
- const textarea = el.querySelector("textarea");
194
+ const queryEl = el instanceof Document ? el.documentElement : el;
195
+ const textarea = elementProvider.query(
196
+ queryEl,
197
+ "textarea",
198
+ "Focus editable field textarea"
199
+ );
227
200
  if (textarea) {
228
201
  textarea.focus();
229
202
  return;
230
203
  }
231
- const editable = el.querySelector("[contenteditable]");
232
- if (editable instanceof HTMLElement) {
204
+ const editable = elementProvider.query(
205
+ queryEl,
206
+ "[contenteditable]",
207
+ "Focus editable field contenteditable"
208
+ );
209
+ if (editable) {
233
210
  editable.focus();
234
211
  return;
235
212
  }
236
- const iframe = el.querySelector("iframe");
213
+ const iframe = elementProvider.query(
214
+ queryEl,
215
+ "iframe",
216
+ "Find iframe in editable field"
217
+ );
237
218
  if (iframe?.contentDocument) {
238
219
  focusInput(iframe.contentDocument);
239
220
  }
240
221
  };
241
- const onAnimationFrame = () => {
242
- if (ui.isMobile.value) {
243
- return;
244
- }
245
- const elementRect = props.element.getBoundingClientRect();
246
- const height = form.value?.scrollHeight || 100;
247
- const newWidth = Math.min(Math.max(elementRect.width, 360), 1e3);
248
- const ideal = findIdealRectPosition(
249
- ui.viewportBlockingRects.value,
250
- {
251
- x: alignment.value === "left" ? elementRect.x : elementRect.x + (Math.max(elementRect.width, 360) - newWidth) / 2,
252
- y: elementRect.y - height - 20,
253
- height,
254
- width: newWidth
255
- },
256
- ui.visibleViewportPadded.value
257
- );
258
- x.value = ideal.x;
259
- y.value = ideal.y + height;
260
- width.value = newWidth;
261
- };
262
- onAnimationFrame();
263
- onBlokkliEvent("animationFrame", onAnimationFrame);
264
222
  onMounted(() => {
265
223
  const el = getElement();
266
224
  if (props.isComponent) {
@@ -1,7 +1,7 @@
1
- import type { DraggableExistingBlock, EntityContext, EditableFieldConfig } from '#blokkli/types';
1
+ import type { EntityContext, EditableFieldConfig } from '#blokkli/types';
2
2
  type __VLS_Props = {
3
3
  fieldName: string;
4
- host: DraggableExistingBlock | EntityContext;
4
+ host: EntityContext;
5
5
  element: HTMLElement;
6
6
  config: EditableFieldConfig;
7
7
  isComponent?: boolean;