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

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 (182) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +191 -27
  3. package/dist/runtime/blokkliPlugins/BlockIndicator/index.vue.d.ts +38 -0
  4. package/dist/runtime/blokkliPlugins/ContextMenu/index.vue.d.ts +15 -0
  5. package/dist/runtime/blokkliPlugins/DebugOverlay/index.vue.d.ts +6 -0
  6. package/dist/runtime/blokkliPlugins/ItemAction/index.vue.d.ts +28 -3
  7. package/dist/runtime/blokkliPlugins/Sidebar/Detached/index.vue +6 -4
  8. package/dist/runtime/blokkliPlugins/Sidebar/index.vue +11 -3
  9. package/dist/runtime/blokkliPlugins/Sidebar/index.vue.d.ts +138 -3
  10. package/dist/runtime/blokkliPlugins/ToolbarButton/index.vue.d.ts +114 -0
  11. package/dist/runtime/blokkliPlugins/TourItem/index.vue.d.ts +21 -0
  12. package/dist/runtime/blokkliPlugins/ViewOption/index.vue.d.ts +98 -0
  13. package/dist/runtime/components/Blocks/NotImplemented/index.vue +24 -0
  14. package/dist/runtime/components/Blocks/NotImplemented/index.vue.d.ts +6 -0
  15. package/dist/runtime/components/BlokkliEditable.vue.d.ts +11 -0
  16. package/dist/runtime/components/BlokkliItem.vue +16 -3
  17. package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
  18. package/dist/runtime/components/Edit/Actions/index.vue +1 -1
  19. package/dist/runtime/components/Edit/AddListItem/index.vue +1 -6
  20. package/dist/runtime/components/Edit/AddListItem/index.vue.d.ts +5 -13
  21. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +6 -0
  22. package/dist/runtime/components/Edit/BlockProxy/index.vue +2 -2
  23. package/dist/runtime/components/Edit/BlokkliErrorBoundary.vue +3 -0
  24. package/dist/runtime/components/Edit/BlokkliRootErrorBoundary.vue +4 -1
  25. package/dist/runtime/components/Edit/Dialog/index.vue +15 -50
  26. package/dist/runtime/components/Edit/DraggableList.vue +12 -9
  27. package/dist/runtime/components/Edit/EditIndicator.vue +11 -4
  28. package/dist/runtime/components/Edit/EditProvider.vue +27 -24
  29. package/dist/runtime/components/Edit/Features/AddList/Actions/Action.vue +1 -0
  30. package/dist/runtime/components/Edit/Features/AddList/Blocks/index.vue +2 -3
  31. package/dist/runtime/components/Edit/Features/AddList/index.vue +17 -5
  32. package/dist/runtime/components/Edit/Features/Analyze/Icon.vue +85 -0
  33. package/dist/runtime/components/Edit/Features/Analyze/Icon.vue.d.ts +5 -0
  34. package/dist/runtime/components/Edit/Features/Analyze/Main.vue +288 -59
  35. package/dist/runtime/components/Edit/Features/Analyze/Main.vue.d.ts +8 -1
  36. package/dist/runtime/components/Edit/Features/Analyze/Renderer/fragment.glsl +25 -13
  37. package/dist/runtime/components/Edit/Features/Analyze/Renderer/index.vue +114 -52
  38. package/dist/runtime/components/Edit/Features/Analyze/Renderer/index.vue.d.ts +16 -2
  39. package/dist/runtime/components/Edit/Features/Analyze/Renderer/vertex.glsl +31 -11
  40. package/dist/runtime/components/Edit/Features/Analyze/Results/Results.vue +2 -0
  41. package/dist/runtime/components/Edit/Features/Analyze/Results/Results.vue.d.ts +8 -1
  42. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItem.vue +4 -4
  43. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItem.vue.d.ts +20 -2
  44. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodes.vue +11 -18
  45. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodes.vue.d.ts +10 -3
  46. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +46 -40
  47. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue.d.ts +10 -4
  48. package/dist/runtime/components/Edit/Features/Analyze/Summary/Chart.vue +8 -4
  49. package/dist/runtime/components/Edit/Features/Analyze/analyzers/axe.js +1 -0
  50. package/dist/runtime/components/Edit/Features/Analyze/analyzers/helpers/Context.d.ts +4 -3
  51. package/dist/runtime/components/Edit/Features/Analyze/analyzers/helpers/Context.js +2 -1
  52. package/dist/runtime/components/Edit/Features/Analyze/analyzers/readability.js +61 -20
  53. package/dist/runtime/components/Edit/Features/Analyze/analyzers/types.d.ts +15 -1
  54. package/dist/runtime/components/Edit/Features/Analyze/index.vue +23 -2
  55. package/dist/runtime/components/Edit/Features/Artboard/Overview/index.vue +22 -8
  56. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +1 -1
  57. package/dist/runtime/components/Edit/Features/Artboard/Scrollbar/index.vue +8 -3
  58. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +10 -1
  59. package/dist/runtime/components/Edit/Features/Debug/Main.vue.d.ts +1 -1
  60. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +2 -2
  61. package/dist/runtime/components/Edit/Features/Debug/Section/Logging.vue.d.ts +1 -1
  62. package/dist/runtime/components/Edit/Features/EditForm/Frame/index.vue +8 -2
  63. package/dist/runtime/components/Edit/Features/EditForm/index.vue +1 -7
  64. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Plaintext/index.vue +1 -1
  65. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +4 -3
  66. package/dist/runtime/components/Edit/Features/EditableMask/index.vue +1 -1
  67. package/dist/runtime/components/Edit/Features/EntityTitle/index.vue +7 -2
  68. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +2 -2
  69. package/dist/runtime/components/Edit/Features/Library/LibraryDialog/index.vue +9 -2
  70. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +12 -3
  71. package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +3 -2
  72. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue.d.ts +1 -1
  73. package/dist/runtime/components/Edit/Features/PreviewGrant/index.vue +1 -0
  74. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +9 -0
  75. package/dist/runtime/components/Edit/Features/ResponsivePreview/Frame/index.vue +3 -2
  76. package/dist/runtime/components/Edit/Features/ResponsivePreview/index.vue +3 -2
  77. package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Content/index.vue +8 -2
  78. package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +12 -2
  79. package/dist/runtime/components/Edit/Features/Search/Overlay/index.vue +11 -3
  80. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +126 -33
  81. package/dist/runtime/components/Edit/Features/Selection/Renderer/index.vue +1 -1
  82. package/dist/runtime/components/Edit/Features/Settings/index.vue +1 -1
  83. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +3 -3
  84. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +2 -2
  85. package/dist/runtime/components/Edit/Features/Transform/Dialog/index.vue +7 -1
  86. package/dist/runtime/components/Edit/Form/Textarea/index.vue +1 -1
  87. package/dist/runtime/components/Edit/FormOverlay/index.vue +1 -1
  88. package/dist/runtime/components/Edit/Indicators/index.vue +1 -1
  89. package/dist/runtime/components/Edit/InfoBox/index.vue +3 -2
  90. package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +6 -1
  91. package/dist/runtime/components/Edit/Overlay/index.vue +4 -0
  92. package/dist/runtime/components/Edit/PreviewProvider.vue +3 -3
  93. package/dist/runtime/components/Edit/ScaleToFit/index.vue +4 -4
  94. package/dist/runtime/composables/defineBlokkliFeature.d.ts +1 -1
  95. package/dist/runtime/composables/useBlokkli.d.ts +6 -1
  96. package/dist/runtime/composables/useBlokkli.js +4 -1
  97. package/dist/runtime/css/output.css +1 -1
  98. package/dist/runtime/helpers/composables/defineItemDropdownAction.d.ts +1 -1
  99. package/dist/runtime/helpers/composables/defineMenuButton.d.ts +1 -1
  100. package/dist/runtime/helpers/composables/defineRenderer.d.ts +1 -1
  101. package/dist/runtime/helpers/composables/onBroadcastEvent.d.ts +1 -1
  102. package/dist/runtime/helpers/composables/useBlockRegistration.d.ts +1 -1
  103. package/dist/runtime/helpers/composables/useBlockRegistration.js +12 -1
  104. package/dist/runtime/helpers/composables/useDebugLogger.d.ts +1 -1
  105. package/dist/runtime/helpers/composables/useFocusTrap.d.ts +52 -0
  106. package/dist/runtime/helpers/composables/useFocusTrap.js +59 -0
  107. package/dist/runtime/helpers/composables/useGlobalBlokkliObject.d.ts +1 -1
  108. package/dist/runtime/helpers/{useTransitionedValue.js → composables/useTransitionedValue.js} +1 -1
  109. package/dist/runtime/helpers/imports/index.d.ts +2 -1
  110. package/dist/runtime/helpers/imports/index.js +10 -1
  111. package/dist/runtime/helpers/{animationProvider.d.ts → providers/animation.d.ts} +100 -7
  112. package/dist/runtime/helpers/{animationProvider.js → providers/animation.js} +21 -11
  113. package/dist/runtime/helpers/providers/blocks.d.ts +25 -3
  114. package/dist/runtime/helpers/providers/blocks.js +9 -0
  115. package/dist/runtime/helpers/providers/commands.d.ts +41 -0
  116. package/dist/runtime/helpers/{commandsProvider.js → providers/commands.js} +1 -1
  117. package/dist/runtime/helpers/providers/debug.d.ts +125 -0
  118. package/dist/runtime/helpers/{debugProvider.js → providers/debug.js} +2 -2
  119. package/dist/runtime/helpers/providers/definition.d.ts +87 -0
  120. package/dist/runtime/helpers/providers/directive.d.ts +88 -2
  121. package/dist/runtime/helpers/providers/directive.js +27 -3
  122. package/dist/runtime/helpers/providers/dom.d.ts +225 -0
  123. package/dist/runtime/helpers/{domProvider.js → providers/dom.js} +31 -75
  124. package/dist/runtime/helpers/providers/dropArea.d.ts +47 -0
  125. package/dist/runtime/helpers/{dropAreaProvider.js → providers/dropArea.js} +1 -1
  126. package/dist/runtime/helpers/providers/element.d.ts +58 -1
  127. package/dist/runtime/helpers/providers/features.d.ts +56 -0
  128. package/dist/runtime/helpers/{featuresProvider.js → providers/features.js} +1 -1
  129. package/dist/runtime/helpers/providers/fields.d.ts +18 -11
  130. package/dist/runtime/helpers/providers/fields.js +1 -1
  131. package/dist/runtime/helpers/providers/indicators.d.ts +44 -0
  132. package/dist/runtime/helpers/providers/keyboard.d.ts +76 -0
  133. package/dist/runtime/helpers/{keyboardProvider.js → providers/keyboard.js} +1 -8
  134. package/dist/runtime/helpers/{pluginProvider.d.ts → providers/plugin.d.ts} +36 -0
  135. package/dist/runtime/helpers/{selectionProvider.d.ts → providers/selection.d.ts} +4 -1
  136. package/dist/runtime/helpers/{selectionProvider.js → providers/selection.js} +1 -1
  137. package/dist/runtime/helpers/providers/state.d.ts +227 -0
  138. package/dist/runtime/helpers/{stateProvider.js → providers/state.js} +3 -3
  139. package/dist/runtime/helpers/providers/storage.d.ts +64 -0
  140. package/dist/runtime/helpers/{textProvider.d.ts → providers/texts.d.ts} +1 -1
  141. package/dist/runtime/helpers/providers/theme.d.ts +119 -0
  142. package/dist/runtime/helpers/{themeProvider.js → providers/theme.js} +3 -3
  143. package/dist/runtime/helpers/providers/tour.d.ts +49 -0
  144. package/dist/runtime/helpers/{tourProvider.js → providers/tour.js} +1 -1
  145. package/dist/runtime/helpers/providers/types.d.ts +170 -0
  146. package/dist/runtime/helpers/{typesProvider.js → providers/types.js} +45 -1
  147. package/dist/runtime/helpers/providers/ui.d.ts +339 -0
  148. package/dist/runtime/helpers/{uiProvider.js → providers/ui.js} +11 -5
  149. package/dist/runtime/helpers/runtimeHelpers/index.d.ts +1 -1
  150. package/dist/runtime/helpers/symbols.d.ts +1 -0
  151. package/dist/runtime/helpers/symbols.js +3 -0
  152. package/dist/runtime/types/blockOptions.d.ts +349 -0
  153. package/dist/runtime/types/index.d.ts +22 -26
  154. package/package.json +2 -2
  155. package/dist/runtime/helpers/commandsProvider.d.ts +0 -9
  156. package/dist/runtime/helpers/debugProvider.d.ts +0 -33
  157. package/dist/runtime/helpers/definitionProvider.d.ts +0 -19
  158. package/dist/runtime/helpers/domProvider.d.ts +0 -91
  159. package/dist/runtime/helpers/dropAreaProvider.d.ts +0 -9
  160. package/dist/runtime/helpers/featuresProvider.d.ts +0 -17
  161. package/dist/runtime/helpers/indicatorsProvider.d.ts +0 -10
  162. package/dist/runtime/helpers/keyboardProvider.d.ts +0 -20
  163. package/dist/runtime/helpers/stateProvider.d.ts +0 -47
  164. package/dist/runtime/helpers/storageProvider.d.ts +0 -17
  165. package/dist/runtime/helpers/themeProvider.d.ts +0 -30
  166. package/dist/runtime/helpers/tourProvider.d.ts +0 -11
  167. package/dist/runtime/helpers/typesProvider.d.ts +0 -36
  168. package/dist/runtime/helpers/uiProvider.d.ts +0 -57
  169. package/dist/runtime/types/blokkOptions.d.ts +0 -100
  170. /package/dist/runtime/helpers/{addElementClasses.d.ts → composables/addElementClasses.d.ts} +0 -0
  171. /package/dist/runtime/helpers/{addElementClasses.js → composables/addElementClasses.js} +0 -0
  172. /package/dist/runtime/helpers/{defineElementStyle.d.ts → composables/defineElementStyle.d.ts} +0 -0
  173. /package/dist/runtime/helpers/{defineElementStyle.js → composables/defineElementStyle.js} +0 -0
  174. /package/dist/runtime/helpers/{useTransitionedValue.d.ts → composables/useTransitionedValue.d.ts} +0 -0
  175. /package/dist/runtime/helpers/{broadcastProvider.d.ts → providers/broadcast.d.ts} +0 -0
  176. /package/dist/runtime/helpers/{broadcastProvider.js → providers/broadcast.js} +0 -0
  177. /package/dist/runtime/helpers/{definitionProvider.js → providers/definition.js} +0 -0
  178. /package/dist/runtime/helpers/{indicatorsProvider.js → providers/indicators.js} +0 -0
  179. /package/dist/runtime/helpers/{pluginProvider.js → providers/plugin.js} +0 -0
  180. /package/dist/runtime/helpers/{storageProvider.js → providers/storage.js} +0 -0
  181. /package/dist/runtime/helpers/{textProvider.js → providers/texts.js} +0 -0
  182. /package/dist/runtime/types/{blokkOptions.js → blockOptions.js} +0 -0
@@ -1,16 +1,15 @@
1
- import { reactive, ref, computed } from "#imports";
1
+ import { reactive, ref, computed, onMounted } from "#imports";
2
2
  import { falsy } from "#blokkli/helpers";
3
- import { cloneElementWithStyles } from "./dom/index.js";
4
- import onBlokkliEvent from "./composables/onBlokkliEvent.js";
5
- import useDelayedIntersectionObserver from "./composables/useDelayedIntersectionObserver.js";
6
- import { itemEntityType } from "#blokkli-build/config";
3
+ import { cloneElementWithStyles } from "../dom/index.js";
4
+ import onBlokkliEvent from "../composables/onBlokkliEvent.js";
5
+ import useDelayedIntersectionObserver from "../composables/useDelayedIntersectionObserver.js";
7
6
  function rectWithTime(rect, time) {
8
7
  return {
9
8
  ...rect,
10
9
  time: time || performance.now()
11
10
  };
12
11
  }
13
- export default function(ui, debug, definitions, state, element) {
12
+ export default function(ui, debug, state, element) {
14
13
  const logger = debug.createLogger("DomProvider");
15
14
  const mutationsReady = ref(true);
16
15
  const intersectionReady = ref(false);
@@ -23,10 +22,11 @@ export default function(ui, debug, definitions, state, element) {
23
22
  const blockRects = {};
24
23
  const fieldRects = {};
25
24
  const blockUuidCurrentKey = {};
26
- const observedElements = {};
27
25
  let initTimeout = null;
28
26
  const isInitalizing = ref(true);
29
- const observedElementCache = /* @__PURE__ */ new Map();
27
+ let settleTimeout = null;
28
+ const settleKey = ref(0);
29
+ const observedElements = {};
30
30
  function getBoundingClientRect(element2) {
31
31
  logger.log("getBoundingClientRect", element2);
32
32
  return element2.getBoundingClientRect();
@@ -154,6 +154,7 @@ export default function(ui, debug, definitions, state, element) {
154
154
  intersectionObserver.observe(element2);
155
155
  fieldElementToFieldKey.set(element2, key);
156
156
  doInitTimeout();
157
+ doSettleTimeout();
157
158
  };
158
159
  const updateFieldElement = (entity, fieldName, element2, data) => {
159
160
  const key = `${entity.uuid}:${fieldName}`;
@@ -179,36 +180,12 @@ export default function(ui, debug, definitions, state, element) {
179
180
  }
180
181
  visibleFields.delete(key);
181
182
  registeredFields[key] = void 0;
183
+ doSettleTimeout();
182
184
  };
183
185
  const getRegisteredField = (uuid, fieldName) => {
184
186
  const key = `${uuid}:${fieldName}`;
185
187
  return registeredFields[key];
186
188
  };
187
- function getElementToObserve(uuid, el, bundle, fieldListType, parentBlockBundle) {
188
- if (el.classList.contains("bk-block-proxy")) {
189
- return el;
190
- }
191
- const key = `${uuid}${bundle}${fieldListType}${parentBlockBundle ?? "none"}`;
192
- const cached = observedElementCache.get(key);
193
- if (cached) {
194
- return cached;
195
- }
196
- const definition = definitions.getBlockDefinition(
197
- bundle,
198
- fieldListType,
199
- parentBlockBundle
200
- );
201
- if (!definition) {
202
- throw new Error("Failed to load definition for bundle: " + bundle);
203
- }
204
- const observableElement = (definition.editor?.getDraggableElement ? definition.editor.getDraggableElement(el) : el) || el;
205
- if (observableElement instanceof HTMLElement) {
206
- observedElementCache.set(key, observableElement);
207
- return observableElement;
208
- }
209
- observedElementCache.set(key, el);
210
- return el;
211
- }
212
189
  const getDropElementMarkup = (item, checkSize) => {
213
190
  const getElement = () => {
214
191
  if ("itemType" in item) {
@@ -265,21 +242,8 @@ export default function(ui, debug, definitions, state, element) {
265
242
  if (!fieldList) {
266
243
  return;
267
244
  }
268
- const fieldListType = getRegisteredField(fieldList.entityUuid, fieldList.name)?.fieldListType ?? "default";
269
- const parentBundle = fieldList.entityType === itemEntityType ? state.getFieldListItem(fieldList.entityUuid)?.bundle ?? null : null;
270
- const observableElement = getElementToObserve(
271
- uuid,
272
- el,
273
- item.bundle,
274
- fieldListType,
275
- parentBundle
276
- );
277
245
  blockRects[uuid] = rectWithTime(
278
- ui.getAbsoluteElementRect(
279
- observableElement.getBoundingClientRect(),
280
- scale,
281
- offset
282
- )
246
+ ui.getAbsoluteElementRect(el.getBoundingClientRect(), scale, offset)
283
247
  );
284
248
  }
285
249
  function refreshFieldRect(key) {
@@ -322,11 +286,7 @@ export default function(ui, debug, definitions, state, element) {
322
286
  );
323
287
  }
324
288
  }
325
- onBlokkliEvent("state:reload:before", () => {
326
- observedElementCache.clear();
327
- });
328
289
  onBlokkliEvent("state:reloaded", () => {
329
- observedElementCache.clear();
330
290
  if (stateReloadTimeout) {
331
291
  window.clearTimeout(stateReloadTimeout);
332
292
  }
@@ -335,6 +295,7 @@ export default function(ui, debug, definitions, state, element) {
335
295
  updateVisibleRects();
336
296
  }
337
297
  stateReloadTimeout = window.setTimeout(updateVisibleRects, 300);
298
+ doSettleTimeout();
338
299
  });
339
300
  function forceRefresh() {
340
301
  updateVisibleRects();
@@ -355,17 +316,7 @@ export default function(ui, debug, definitions, state, element) {
355
316
  if (!item) {
356
317
  return;
357
318
  }
358
- const el = registeredBlocks[item.uuid];
359
- if (!el) {
360
- return;
361
- }
362
- return getElementToObserve(
363
- item.uuid,
364
- el,
365
- item.bundle,
366
- item.fieldListType,
367
- item.parentBlockBundle
368
- );
319
+ return registeredBlocks[item.uuid];
369
320
  }
370
321
  function isBlockVisible(uuid) {
371
322
  return visibleBlocks.has(uuid);
@@ -393,10 +344,19 @@ export default function(ui, debug, definitions, state, element) {
393
344
  }, 500);
394
345
  }
395
346
  }
347
+ function doSettleTimeout() {
348
+ if (settleTimeout) {
349
+ window.clearTimeout(settleTimeout);
350
+ }
351
+ settleTimeout = window.setTimeout(() => {
352
+ settleKey.value++;
353
+ }, 50);
354
+ }
396
355
  function registerBlock(key, uuid, el) {
397
356
  logger.log("registerBlock: " + uuid);
398
357
  blockUuidCurrentKey[uuid] = key;
399
358
  doInitTimeout();
359
+ doSettleTimeout();
400
360
  if (!(el instanceof HTMLElement)) {
401
361
  logger.log("registerBlock call unregisterBlock because no element", uuid);
402
362
  unregisterBlock(key, uuid);
@@ -423,26 +383,18 @@ export default function(ui, debug, definitions, state, element) {
423
383
  uuid
424
384
  );
425
385
  }
426
- const fieldListType = getRegisteredField(fieldList.entityUuid, fieldList.name)?.fieldListType ?? "default";
427
- const parentBundle = fieldList.entityType === itemEntityType ? state.getFieldListItem(fieldList.entityUuid)?.bundle ?? null : null;
428
- const observableElement = getElementToObserve(
429
- item.uuid,
430
- el,
431
- item.bundle,
432
- fieldListType,
433
- parentBundle
434
- );
435
- blockElementToUuid.set(observableElement, uuid);
386
+ blockElementToUuid.set(el, uuid);
436
387
  registeredBlocks[uuid] = el;
437
- observedElements[uuid] = observableElement;
438
- intersectionObserver.observe(observableElement);
439
- resizeObserver.observe(observableElement);
388
+ observedElements[uuid] = el;
389
+ intersectionObserver.observe(el);
390
+ resizeObserver.observe(el);
440
391
  }
441
392
  function unregisterBlock(key, uuid) {
442
393
  const currentKey = blockUuidCurrentKey[uuid];
443
394
  if (currentKey && currentKey !== key) {
444
395
  return;
445
396
  }
397
+ doSettleTimeout();
446
398
  logger.log("unregisterBlock: " + uuid);
447
399
  const el = registeredBlocks[uuid];
448
400
  const observedElement = observedElements[uuid];
@@ -531,6 +483,9 @@ export default function(ui, debug, definitions, state, element) {
531
483
  }
532
484
  };
533
485
  }
486
+ onMounted(() => {
487
+ doInitTimeout();
488
+ });
534
489
  return {
535
490
  getDropElementMarkup,
536
491
  getVisibleBlocks,
@@ -546,6 +501,7 @@ export default function(ui, debug, definitions, state, element) {
546
501
  isReady: computed(
547
502
  () => mutationsReady.value && intersectionReady.value && !isInitalizing.value
548
503
  ),
504
+ settleKey: computed(() => settleKey.value),
549
505
  init,
550
506
  getDragElement,
551
507
  updateVisibleRects,
@@ -0,0 +1,47 @@
1
+ import type { DraggableItem, DropArea } from '#blokkli/types';
2
+ type DropAreaProviderFunction = (items: DraggableItem[]) => DropArea[] | DropArea | undefined;
3
+ export type DropAreaProvider = {
4
+ /**
5
+ * Register a drop area provider function.
6
+ *
7
+ * The function will be called when drop areas are requested during drag operations.
8
+ * It receives the currently dragged items and can return drop areas where those items can be dropped.
9
+ *
10
+ * @param fn - Function that returns drop areas based on dragged items
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * dropArea.add((items) => {
15
+ * // Only provide drop area for text blocks
16
+ * if (items.every(item => item.bundle === 'text')) {
17
+ * return {
18
+ * id: 'custom-area',
19
+ * label: 'Text Only Area',
20
+ * accepts: (item) => item.bundle === 'text',
21
+ * }
22
+ * }
23
+ * })
24
+ * ```
25
+ */
26
+ add: (fn: DropAreaProviderFunction) => void;
27
+ /**
28
+ * Unregister a drop area provider function.
29
+ *
30
+ * Removes a previously registered function so it no longer provides drop areas.
31
+ *
32
+ * @param fn - The function to remove (must be the same reference used in add)
33
+ */
34
+ remove: (fn: DropAreaProviderFunction) => void;
35
+ /**
36
+ * Get all drop areas from all registered providers.
37
+ *
38
+ * Calls all registered provider functions with the dragged items,
39
+ * flattens the results, and filters out undefined values.
40
+ *
41
+ * @param items - The currently dragged items
42
+ * @returns Array of all available drop areas for these items
43
+ */
44
+ getDropAreas: (items: DraggableItem[]) => DropArea[];
45
+ };
46
+ export default function (): DropAreaProvider;
47
+ export {};
@@ -1,4 +1,4 @@
1
- import { falsy } from "./index.js";
1
+ import { falsy } from "../index.js";
2
2
  export default function() {
3
3
  let functions = [];
4
4
  const add = (fn) => {
@@ -1,6 +1,63 @@
1
- import type { DebugProvider } from '../debugProvider.js';
1
+ import type { DebugProvider } from './debug.js';
2
2
  export type ElementProvider = {
3
+ /**
4
+ * Query all matching elements with debug logging.
5
+ *
6
+ * Wrapper around `querySelectorAll` that:
7
+ * - Logs the query and reason to debug console
8
+ * - Filters out non-HTMLElement results
9
+ * - Optionally maps/transforms results
10
+ * - Filters out null/undefined mapped results
11
+ *
12
+ * @param target - Element or document to query within
13
+ * @param query - CSS selector string
14
+ * @param reason - Human-readable reason for the query (for debugging)
15
+ * @param map - Optional function to transform each matched element
16
+ * @returns Array of matched (and optionally transformed) elements
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Get all buttons
21
+ * const buttons = element.queryAll(document, 'button', 'Get all buttons')
22
+ *
23
+ * // Get all buttons with data attributes
24
+ * const buttonData = element.queryAll(
25
+ * document,
26
+ * 'button[data-action]',
27
+ * 'Get action buttons',
28
+ * (el) => el.dataset.action
29
+ * )
30
+ * ```
31
+ */
3
32
  queryAll: <T = HTMLElement>(target: HTMLElement | Document, query: string, reason: string, map?: (v: HTMLElement) => T | null | undefined) => T[];
33
+ /**
34
+ * Query the first matching element with debug logging.
35
+ *
36
+ * Wrapper around `querySelector` that:
37
+ * - Logs the query and reason to debug console
38
+ * - Returns null if no match or match is not HTMLElement
39
+ * - Optionally maps/transforms the result
40
+ *
41
+ * @param target - Element or document to query within
42
+ * @param query - CSS selector string
43
+ * @param reason - Human-readable reason for the query (for debugging)
44
+ * @param map - Optional function to transform the matched element
45
+ * @returns The first matched (and optionally transformed) element, or null
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * // Get first button
50
+ * const button = element.query(document, 'button', 'Get first button')
51
+ *
52
+ * // Get button action
53
+ * const action = element.query(
54
+ * document,
55
+ * 'button[data-action]',
56
+ * 'Get action button',
57
+ * (el) => el.dataset.action
58
+ * )
59
+ * ```
60
+ */
4
61
  query: <T = HTMLElement>(target: HTMLElement | Document, query: string, reason: string, map?: (v: HTMLElement) => T | null | undefined) => T | null;
5
62
  };
6
63
  export default function (debug: DebugProvider): ElementProvider;
@@ -0,0 +1,56 @@
1
+ import type { FeatureDefinition, AdapterMethods } from '#blokkli/types';
2
+ import { type ValidFeatureKey } from '#blokkli-build/features';
3
+ import { type ComputedRef } from '#imports';
4
+ import type { StorageProvider } from './storage.js';
5
+ export type FeaturesProvider = {
6
+ /**
7
+ * List of all registered feature definitions.
8
+ *
9
+ * Updates automatically via HMR during development.
10
+ */
11
+ features: ComputedRef<FeatureDefinition[]>;
12
+ /**
13
+ * List of currently mounted features.
14
+ *
15
+ * Features are mounted when their components are rendered in the editor.
16
+ * This list is used to track which features are active in the current session.
17
+ */
18
+ mountedFeatures: ComputedRef<FeatureDefinition<AdapterMethods[], ValidFeatureKey>[]>;
19
+ /**
20
+ * List of available beta features.
21
+ *
22
+ * Only includes features marked with `beta: true` in their definition.
23
+ * These features can be individually enabled/disabled by users.
24
+ */
25
+ betaFeatures: ComputedRef<{
26
+ id: ValidFeatureKey;
27
+ label: string;
28
+ description?: string;
29
+ }[]>;
30
+ /**
31
+ * List of beta features that are currently enabled.
32
+ *
33
+ * Derived from user settings stored in local storage.
34
+ * Users can toggle beta features on/off in the settings UI.
35
+ */
36
+ enabledBetaFeatures: ComputedRef<ValidFeatureKey[]>;
37
+ /**
38
+ * Mount a feature.
39
+ *
40
+ * Called when a feature component is mounted/rendered.
41
+ * Adds the feature to the mountedFeatures list.
42
+ *
43
+ * @param feature - The feature definition to mount
44
+ */
45
+ mount: (feature: FeatureDefinition<AdapterMethods[], ValidFeatureKey>) => void;
46
+ /**
47
+ * Unmount a feature.
48
+ *
49
+ * Called when a feature component is unmounted/destroyed.
50
+ * Removes the feature from the mountedFeatures list.
51
+ *
52
+ * @param id - The feature ID to unmount
53
+ */
54
+ unmount: (id: string) => void;
55
+ };
56
+ export default function (storage: StorageProvider): FeaturesProvider;
@@ -2,7 +2,7 @@ import {
2
2
  featureDefinitions
3
3
  } from "#blokkli-build/features";
4
4
  import { computed, ref } from "#imports";
5
- import { falsy } from "./index.js";
5
+ import { falsy } from "../index.js";
6
6
  export default function(storage) {
7
7
  const definitions = ref(featureDefinitions);
8
8
  const mountedFeatures = ref([]);
@@ -1,16 +1,23 @@
1
1
  import type { BlokkliFieldElement } from '#blokkli/types';
2
- import type { DomProvider } from '../domProvider.js';
3
- import type { StateProvider } from '../stateProvider.js';
4
- import type { BlockDefinitionProvider } from '../typesProvider.js';
2
+ import type { DomProvider } from './dom.js';
3
+ import type { BlockDefinitionProvider } from './types.js';
5
4
  export type FieldsProvider = {
6
- find: (
7
5
  /**
8
- * The host entity UUID.
6
+ * Find a field element by host entity UUID and field name.
7
+ *
8
+ * Returns a BlokkliFieldElement with complete field metadata including:
9
+ * - Field configuration (label, cardinality, allowed bundles)
10
+ * - Host entity information
11
+ * - Nesting level and field list type
12
+ * - HTML element reference
13
+ * - Drop alignment settings
14
+ *
15
+ * Results are cached and invalidated on state reload.
16
+ *
17
+ * @param uuid - The host entity UUID
18
+ * @param fieldName - The name of the field
19
+ * @returns The field element with metadata, or undefined if not found
9
20
  */
10
- uuid: string,
11
- /**
12
- * The name of the field.
13
- */
14
- fieldName: string) => BlokkliFieldElement | undefined;
21
+ find: (uuid: string, fieldName: string) => BlokkliFieldElement | undefined;
15
22
  };
16
- export default function (state: StateProvider, dom: DomProvider, types: BlockDefinitionProvider): FieldsProvider;
23
+ export default function (dom: DomProvider, types: BlockDefinitionProvider): FieldsProvider;
@@ -1,5 +1,5 @@
1
1
  import onBlokkliEvent from "../composables/onBlokkliEvent.js";
2
- export default function(state, dom, types) {
2
+ export default function(dom, types) {
3
3
  const fieldCache = /* @__PURE__ */ new Map();
4
4
  function find(uuid, fieldName) {
5
5
  const key = uuid + ":" + fieldName;
@@ -0,0 +1,44 @@
1
+ import { type Ref } from 'vue';
2
+ import type { BlockIndicator } from '../../types/index.js';
3
+ export type IndicatorsProvider = {
4
+ /**
5
+ * List of all active block indicators.
6
+ *
7
+ * Indicators are visual badges/icons that appear on blocks
8
+ * (e.g., anchor icons, schedule indicators, etc.).
9
+ */
10
+ indicators: Ref<BlockIndicator[]>;
11
+ /**
12
+ * UUID of the currently hovered block.
13
+ *
14
+ * Used to show/hide hover-specific indicators.
15
+ */
16
+ hovered: Ref<string>;
17
+ /**
18
+ * Add a block indicator.
19
+ *
20
+ * Registers a new indicator to be displayed on a block.
21
+ *
22
+ * @param indicator - The indicator configuration
23
+ */
24
+ addIndicator: (indicator: BlockIndicator) => void;
25
+ /**
26
+ * Remove a block indicator.
27
+ *
28
+ * Removes an indicator based on its ID and the block UUID.
29
+ * Both must match to remove the indicator.
30
+ *
31
+ * @param id - The indicator ID
32
+ * @param uuid - The block UUID
33
+ */
34
+ removeIndicator: (id: string, uuid: string) => void;
35
+ /**
36
+ * Set the currently hovered block.
37
+ *
38
+ * Updates the hovered state used to show hover-specific indicators.
39
+ *
40
+ * @param uuid - The block UUID, or null/undefined to clear
41
+ */
42
+ setHovered: (uuid?: string | null) => void;
43
+ };
44
+ export default function (): IndicatorsProvider;
@@ -0,0 +1,76 @@
1
+ import { type Ref, type ComputedRef } from 'vue';
2
+ import type { KeyboardShortcut } from '#blokkli/types';
3
+ type RegisteredShortcut = {
4
+ key: string;
5
+ shortcut: KeyboardShortcut;
6
+ };
7
+ export type KeyboardProvider = {
8
+ /**
9
+ * Whether the Space key is currently pressed.
10
+ *
11
+ * Commonly used to enable panning mode in the artboard.
12
+ */
13
+ isPressingSpace: Readonly<Ref<boolean>>;
14
+ /**
15
+ * Whether Control/Meta key is currently pressed.
16
+ *
17
+ * Meta is Cmd on macOS, Ctrl on Windows/Linux.
18
+ * Also true when CapsLock is active.
19
+ */
20
+ isPressingControl: Readonly<Ref<boolean>>;
21
+ /**
22
+ * Whether the Shift key is currently pressed.
23
+ */
24
+ isPressingShift: Readonly<Ref<boolean>>;
25
+ /**
26
+ * Update keyboard modifier state from a mouse/pointer event.
27
+ *
28
+ * Useful for updating modifier state during drag operations where
29
+ * keyboard events might not fire.
30
+ *
31
+ * @param e - The mouse or pointer event
32
+ */
33
+ setShortcutStateFromEvent: (e: MouseEvent | PointerEvent) => void;
34
+ /**
35
+ * List of all registered keyboard shortcuts.
36
+ *
37
+ * Shortcuts are registered by features, buttons, and actions to enable
38
+ * keyboard navigation and commands.
39
+ */
40
+ shortcuts: ComputedRef<RegisteredShortcut[]>;
41
+ /**
42
+ * Register a keyboard shortcut.
43
+ *
44
+ * Adds the shortcut to the global shortcuts list for display in help UI.
45
+ *
46
+ * @param shortcut - The keyboard shortcut configuration
47
+ */
48
+ registerShortcut: (shortcut: KeyboardShortcut) => void;
49
+ /**
50
+ * Unregister a keyboard shortcut.
51
+ *
52
+ * Removes the shortcut from the global shortcuts list.
53
+ *
54
+ * @param shortcut - The keyboard shortcut to remove
55
+ */
56
+ unregisterShortcut: (shortcut: KeyboardShortcut) => void;
57
+ /**
58
+ * Lock keyboard events.
59
+ *
60
+ * Prevents keyboard shortcuts from firing. Used when text input is focused
61
+ * or dialogs are open to avoid unintended actions.
62
+ *
63
+ * @param id - Unique identifier for this lock
64
+ */
65
+ lockKeyboardEvents: (id: string) => void;
66
+ /**
67
+ * Unlock keyboard events.
68
+ *
69
+ * Removes a keyboard lock, re-enabling shortcuts when all locks are removed.
70
+ *
71
+ * @param id - The lock identifier to remove
72
+ */
73
+ unlockKeyboardEvents: (id: string) => void;
74
+ };
75
+ export default function (): KeyboardProvider;
76
+ export {};
@@ -3,7 +3,6 @@ import {
3
3
  readonly,
4
4
  onMounted,
5
5
  onBeforeUnmount,
6
- watch,
7
6
  computed
8
7
  } from "vue";
9
8
  import { eventBus } from "#blokkli/helpers/eventBus";
@@ -13,7 +12,7 @@ function getControlState(e) {
13
12
  }
14
13
  return e.getModifierState("Control") || e.getModifierState("Meta");
15
14
  }
16
- export default function(animationProvider) {
15
+ export default function() {
17
16
  const isPressingControl = ref(false);
18
17
  const isPressingSpace = ref(false);
19
18
  const isPressingShift = ref(false);
@@ -62,12 +61,6 @@ export default function(animationProvider) {
62
61
  document.removeEventListener("keyup", onKeyUp);
63
62
  document.removeEventListener("visibilitychange", onVisibilityChange);
64
63
  });
65
- watch(isPressingSpace, () => {
66
- animationProvider.requestDraw();
67
- });
68
- watch(isPressingControl, () => {
69
- animationProvider.requestDraw();
70
- });
71
64
  const getShortcutKey = (shortcut) => [!!shortcut.meta, !!shortcut.shift, shortcut.code].join("-");
72
65
  const registerShortcut = (shortcut) => {
73
66
  registeredShortcuts.value.push({ key: getShortcutKey(shortcut), shortcut });
@@ -37,8 +37,44 @@ type PluginDataMap = {
37
37
  menuButton: MenuButtonPlugin;
38
38
  };
39
39
  export type PluginProvider = {
40
+ /**
41
+ * Register a plugin provider function.
42
+ *
43
+ * The function will be called when plugins of this type are requested.
44
+ * It can return a single plugin, an array of plugins, or undefined.
45
+ *
46
+ * @param type - The plugin type ('addAction', 'itemDropdownAction', 'menuButton')
47
+ * @param fn - Function that returns plugin(s)
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * plugin.add('addAction', () => ({
52
+ * id: 'custom-add',
53
+ * label: 'Add Custom',
54
+ * bundles: ['text'],
55
+ * callback: () => console.log('add'),
56
+ * }))
57
+ * ```
58
+ */
40
59
  add<T extends keyof PluginFunctionMap>(type: T, fn: PluginFunctionMap[T]): void;
60
+ /**
61
+ * Unregister a plugin provider function.
62
+ *
63
+ * Removes a previously registered function so it no longer provides plugins.
64
+ *
65
+ * @param type - The plugin type
66
+ * @param fn - The function to remove (must be the same reference used in add)
67
+ */
41
68
  remove<T extends keyof PluginFunctionMap>(type: T, fn: PluginFunctionMap[T]): void;
69
+ /**
70
+ * Get all plugins from all registered providers.
71
+ *
72
+ * Calls all registered provider functions for this type, flattens the results,
73
+ * and filters out undefined values.
74
+ *
75
+ * @param type - The plugin type to retrieve
76
+ * @returns Array of all available plugins of this type
77
+ */
42
78
  get<T extends keyof PluginDataMap>(type: T): PluginDataMap[T][];
43
79
  };
44
80
  export default function (): PluginProvider;
@@ -1,6 +1,6 @@
1
1
  import { type Ref, type ComputedRef } from '#imports';
2
2
  import type { DraggableItem, InteractionMode, RenderedFieldListItem } from '#blokkli/types';
3
- import type { BlocksProvider } from './providers/blocks.js';
3
+ import type { BlocksProvider } from './blocks.js';
4
4
  export type SelectionProvider = {
5
5
  /**
6
6
  * The currently selected UUIDs.
@@ -66,6 +66,9 @@ export type SelectionProvider = {
66
66
  * The block bundles of the items being dragged.
67
67
  */
68
68
  dragItemsBundles: ComputedRef<string[]>;
69
+ /**
70
+ * Determine if the given block UUID is currently selected.
71
+ */
69
72
  isBlockSelected(uuid: string): boolean;
70
73
  /**
71
74
  * Lock selection.
@@ -1,4 +1,4 @@
1
- import onBlokkliEvent from "./composables/onBlokkliEvent.js";
1
+ import onBlokkliEvent from "../composables/onBlokkliEvent.js";
2
2
  import { computed, ref } from "#imports";
3
3
  import { falsy, onlyUnique } from "#blokkli/helpers";
4
4
  export default function(blocks) {