@blokkli/editor 1.0.4 → 1.1.0

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 (77) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +334 -9
  3. package/dist/runtime/adapter/drupal/graphql/base.graphql +2 -1
  4. package/dist/runtime/adapter/drupal/graphqlMiddleware.js +4 -1
  5. package/dist/runtime/adapter/index.d.ts +12 -1
  6. package/dist/runtime/blokkliPlugins/Sidebar/Detached/index.vue +41 -39
  7. package/dist/runtime/blokkliPlugins/Sidebar/index.vue +10 -16
  8. package/dist/runtime/blokkliPlugins/ViewOption/index.vue +2 -0
  9. package/dist/runtime/components/BlokkliField.vue +75 -17
  10. package/dist/runtime/components/BlokkliItem.vue +34 -6
  11. package/dist/runtime/components/BlokkliProvider.vue +18 -1
  12. package/dist/runtime/components/Edit/BlockProxy/index.vue +102 -0
  13. package/dist/runtime/components/Edit/DragInteractions/index.vue +49 -25
  14. package/dist/runtime/components/Edit/DraggableList.vue +138 -28
  15. package/dist/runtime/components/Edit/EditProvider.vue +4 -0
  16. package/dist/runtime/components/Edit/Features/AddList/index.vue +3 -0
  17. package/dist/runtime/components/Edit/Features/Artboard/Overview/index.vue +111 -0
  18. package/dist/runtime/components/Edit/Features/Artboard/Scrollbar/index.vue +47 -0
  19. package/dist/runtime/components/Edit/Features/Artboard/index.vue +301 -9
  20. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +3 -4
  21. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +27 -0
  22. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +24 -3
  23. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/fragment.glsl +56 -24
  24. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +184 -29
  25. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/vertex.glsl +36 -16
  26. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +4 -0
  27. package/dist/runtime/components/Edit/Features/Duplicate/index.vue +1 -13
  28. package/dist/runtime/components/Edit/Features/EditableMask/index.vue +2 -2
  29. package/dist/runtime/components/Edit/Features/History/index.vue +1 -1
  30. package/dist/runtime/components/Edit/Features/Options/Form/Checkbox/index.vue +2 -2
  31. package/dist/runtime/components/Edit/Features/Options/Form/Checkboxes/index.vue +28 -25
  32. package/dist/runtime/components/Edit/Features/Options/Form/Color/index.vue +1 -1
  33. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +67 -39
  34. package/dist/runtime/components/Edit/Features/Options/Form/Number/index.vue +6 -2
  35. package/dist/runtime/components/Edit/Features/Options/Form/Radios/index.vue +1 -1
  36. package/dist/runtime/components/Edit/Features/Options/Form/Range/index.vue +2 -2
  37. package/dist/runtime/components/Edit/Features/Options/Form/Text/index.vue +2 -1
  38. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +83 -33
  39. package/dist/runtime/components/Edit/Features/ProxyView/index.vue +38 -0
  40. package/dist/runtime/components/Edit/Features/Publish/index.vue +53 -6
  41. package/dist/runtime/components/Edit/Features/Search/Overlay/index.vue +3 -13
  42. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +1 -1
  43. package/dist/runtime/components/Edit/Features/Settings/Dialog/index.vue +2 -0
  44. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +3 -3
  45. package/dist/runtime/components/Edit/Features/Structure/index.vue +3 -3
  46. package/dist/runtime/components/Edit/ScrollBoundary/index.vue +24 -0
  47. package/dist/runtime/components/Edit/index.d.ts +2 -1
  48. package/dist/runtime/components/Edit/index.js +3 -1
  49. package/dist/runtime/composables/defineBlokkli.js +10 -5
  50. package/dist/runtime/constants/index.d.ts +1 -1
  51. package/dist/runtime/constants/index.js +6 -1
  52. package/dist/runtime/css/output.css +1 -1
  53. package/dist/runtime/helpers/animationProvider.js +10 -4
  54. package/dist/runtime/helpers/domProvider.d.ts +4 -2
  55. package/dist/runtime/helpers/domProvider.js +42 -19
  56. package/dist/runtime/helpers/featuresProvider.d.ts +1 -1
  57. package/dist/runtime/helpers/runtimeHelpers/index.d.ts +6 -0
  58. package/dist/runtime/helpers/runtimeHelpers/index.js +25 -0
  59. package/dist/runtime/helpers/selectionProvider.d.ts +2 -1
  60. package/dist/runtime/helpers/selectionProvider.js +7 -8
  61. package/dist/runtime/helpers/symbols.d.ts +7 -0
  62. package/dist/runtime/helpers/symbols.js +7 -0
  63. package/dist/runtime/helpers/typesProvider.d.ts +1 -1
  64. package/dist/runtime/helpers/uiProvider.d.ts +1 -0
  65. package/dist/runtime/helpers/uiProvider.js +16 -3
  66. package/dist/runtime/helpers/webgl/index.d.ts +6 -1
  67. package/dist/runtime/helpers/webgl/index.js +38 -5
  68. package/dist/runtime/icons/eye.svg +1 -0
  69. package/dist/runtime/types/generatedModuleTypes.d.ts +12 -4
  70. package/dist/runtime/types/index.d.ts +30 -1
  71. package/package.json +7 -5
  72. package/dist/runtime/components/Edit/Features/Artboard/Manager/Artboard.d.ts +0 -204
  73. package/dist/runtime/components/Edit/Features/Artboard/Manager/Artboard.js +0 -748
  74. package/dist/runtime/components/Edit/Features/Artboard/Manager/Scrollbar/index.vue +0 -176
  75. package/dist/runtime/components/Edit/Features/Artboard/Manager/index.vue +0 -317
  76. package/dist/runtime/helpers/Artboard/index.d.ts +0 -16
  77. package/dist/runtime/helpers/Artboard/index.js +0 -20
@@ -13,25 +13,31 @@ export default function(ui) {
13
13
  let mouseY = 0;
14
14
  let iterator = 120;
15
15
  const webglSupported = ref(null);
16
- useAnimationFrame(() => {
16
+ useAnimationFrame((time) => {
17
17
  if (iterator < 1) {
18
18
  return;
19
19
  }
20
20
  iterator--;
21
- eventBus.emit("animationFrame:before");
21
+ eventBus.emit("animationFrame:before", time);
22
22
  eventBus.emit("animationFrame", {
23
23
  mouseX,
24
24
  mouseY,
25
25
  fieldAreas: []
26
26
  });
27
27
  });
28
+ function onWindowMouseMove(e) {
29
+ mouseX = e.clientX;
30
+ mouseY = e.clientY;
31
+ }
28
32
  onMounted(() => {
29
- document.addEventListener("scroll", requestDraw);
30
33
  document.body.addEventListener("wheel", requestDraw, { passive: false });
34
+ window.addEventListener("pointermove", onWindowMouseMove, { capture: true });
31
35
  });
32
36
  onBeforeUnmount(() => {
33
37
  document.body.removeEventListener("wheel", requestDraw);
34
- document.removeEventListener("scroll", requestDraw);
38
+ window.removeEventListener("pointermove", onWindowMouseMove, {
39
+ capture: true
40
+ });
35
41
  });
36
42
  const requestDraw = () => iterator = 120;
37
43
  onBlokkliEvent("select", requestDraw);
@@ -11,16 +11,16 @@ export type DomProvider = {
11
11
  findBlock(uuid: string): DraggableExistingBlock | undefined;
12
12
  getAllBlocks(): DraggableExistingBlock[];
13
13
  findClosestBlock(el: Element | EventTarget): DraggableExistingBlock | undefined;
14
- getAllFields(): BlokkliFieldElement[];
15
14
  /**
16
15
  * Return the droppable markup for a draggable item.
17
16
  */
18
17
  getDropElementMarkup(item: DraggableItem, checkSize?: boolean): string;
19
18
  getBlockField(uuid: string): BlokkliFieldElement;
20
19
  findField(entityUuid: string, fieldName: string): BlokkliFieldElement | undefined;
21
- registerBlock: (uuid: string, instance: ComponentInternalInstance | null, bundle: string, fieldListType: ValidFieldListTypes, parentBlockBundle?: BlockBundleWithNested) => void;
20
+ registerBlock: (uuid: string, instance: ComponentInternalInstance | null | HTMLElement, bundle: string, fieldListType: ValidFieldListTypes, parentBlockBundle?: BlockBundleWithNested) => void;
22
21
  unregisterBlock: (uuid: string) => void;
23
22
  registerField: (uuid: string, fieldName: string, instance: HTMLElement) => void;
23
+ updateFieldElement: (uuid: string, fieldName: string, element: HTMLElement) => void;
24
24
  unregisterField: (uuid: string, fieldName: string) => void;
25
25
  /**
26
26
  * Get all droppable entity fields.
@@ -30,11 +30,13 @@ export type DomProvider = {
30
30
  getBlockVisibilities(): Record<string, boolean>;
31
31
  getVisibleBlocks(): string[];
32
32
  getVisibleFields(): string[];
33
+ isBlockVisible(uuid: string): boolean;
33
34
  getActiveProviderElement: () => HTMLElement;
34
35
  getBlockRects: () => Record<string, MeasuredBlockRect>;
35
36
  getBlockRect: (uuid: string) => MeasuredBlockRect | undefined;
36
37
  refreshBlockRect: (uuid: string) => void;
37
38
  getFieldRect: (key: string) => Rectangle | undefined;
39
+ updateVisibleRects: () => void;
38
40
  isReady: ComputedRef<boolean>;
39
41
  init: () => void;
40
42
  /**
@@ -15,6 +15,7 @@ const buildFieldElement = (element) => {
15
15
  const name = element.dataset.fieldName;
16
16
  const label = element.dataset.fieldLabel;
17
17
  const isNested = element.dataset.fieldIsNested === "true";
18
+ const nestingLevel = Number.parseInt(element.dataset.bkNestingLevel || "0");
18
19
  const fieldListType = element.dataset.fieldListType;
19
20
  const hostEntityType = element.dataset.hostEntityType;
20
21
  const hostEntityBundle = element.dataset.hostEntityBundle;
@@ -29,6 +30,7 @@ const buildFieldElement = (element) => {
29
30
  name,
30
31
  label,
31
32
  isNested,
33
+ nestingLevel,
32
34
  hostEntityType,
33
35
  hostEntityUuid,
34
36
  hostEntityBundle,
@@ -42,6 +44,9 @@ const buildFieldElement = (element) => {
42
44
  }
43
45
  };
44
46
  const getVisibleBlockElement = (instance) => {
47
+ if (instance instanceof HTMLElement) {
48
+ return instance;
49
+ }
45
50
  if (instance.vnode.el instanceof HTMLElement) {
46
51
  return instance.vnode.el;
47
52
  } else if (instance?.vnode.el instanceof Text && instance?.vnode.el.nextElementSibling instanceof HTMLElement) {
@@ -102,7 +107,7 @@ export default function(ui, debug) {
102
107
  if (entry.target instanceof HTMLElement) {
103
108
  const uuid = entry.target.dataset.uuid || entry.target.closest("[data-uuid]")?.dataset.uuid;
104
109
  const fieldKey = entry.target.dataset.fieldKey;
105
- const rect = entry.boundingClientRect;
110
+ const rect = entry.target.getBoundingClientRect();
106
111
  if (fieldKey) {
107
112
  if (entry.isIntersecting) {
108
113
  visibleFields.add(fieldKey);
@@ -141,15 +146,28 @@ export default function(ui, debug) {
141
146
  registeredFields[key] = element;
142
147
  observer.observe(element);
143
148
  };
149
+ const updateFieldElement = (uuid, fieldName, element) => {
150
+ const key = `${uuid}:${fieldName}`;
151
+ const existingElement = registeredFields[key];
152
+ if (existingElement) {
153
+ observer.unobserve(existingElement);
154
+ }
155
+ registeredFields[key] = element;
156
+ observer.observe(element);
157
+ };
144
158
  const unregisterField = (uuid, fieldName) => {
145
159
  const key = `${uuid}:${fieldName}`;
146
160
  const el = registeredFields[key];
147
161
  if (el) {
148
162
  observer.unobserve(el);
149
163
  }
164
+ visibleFields.delete(key);
150
165
  registeredFields[key] = void 0;
151
166
  };
152
167
  function getElementToObserve(el, bundle, fieldListType, parentBlockBundle) {
168
+ if (el.classList.contains("bk-block-proxy")) {
169
+ return el;
170
+ }
153
171
  const definition = getDefinition(bundle, fieldListType, parentBlockBundle);
154
172
  if (!definition) {
155
173
  throw new Error("Failed to load definition for bundle: " + bundle);
@@ -197,6 +215,7 @@ export default function(ui, debug) {
197
215
  }
198
216
  registeredBlocks[uuid] = void 0;
199
217
  delete blockRects[uuid];
218
+ visibleBlocks.delete(uuid);
200
219
  };
201
220
  const findBlock = (uuid) => {
202
221
  const cached = draggableBlockCache[uuid];
@@ -225,14 +244,6 @@ export default function(ui, debug) {
225
244
  }
226
245
  }).filter(falsy);
227
246
  };
228
- const getAllFields = () => {
229
- const elements = [...document.querySelectorAll(".bk-field-list")];
230
- return elements.map((element) => {
231
- if (element instanceof HTMLElement) {
232
- return buildFieldElement(element);
233
- }
234
- }).filter(falsy);
235
- };
236
247
  const getDropElementMarkup = (item, checkSize) => {
237
248
  const el = item.itemType === "existing" ? getDragElement(item) : item.element();
238
249
  if (!el) {
@@ -253,7 +264,7 @@ export default function(ui, debug) {
253
264
  if (!block) {
254
265
  throw new Error("Block does not exist: " + uuid);
255
266
  }
256
- const el = block.element().closest(".bk-field-list");
267
+ const el = block.element().closest(".bk-draggable-list-container");
257
268
  if (!(el instanceof HTMLElement)) {
258
269
  throw new TypeError("Failed to locate field element for block: " + uuid);
259
270
  }
@@ -272,9 +283,9 @@ export default function(ui, debug) {
272
283
  }
273
284
  return buildFieldElement(el);
274
285
  };
275
- const getAllDroppableFields = () => [...document.querySelectorAll("[data-blokkli-droppable-field]")].map(
276
- mapDroppableField
277
- );
286
+ const getAllDroppableFields = () => [...document.querySelectorAll("[data-blokkli-droppable-field]")].filter((el) => {
287
+ return !el.closest('[data-bk-in-proxy="true"]');
288
+ }).map(mapDroppableField);
278
289
  const getBlockVisibilities = () => {
279
290
  return blockVisibility;
280
291
  };
@@ -324,12 +335,19 @@ export default function(ui, debug) {
324
335
  fieldRects[key] = ui.getAbsoluteElementRect(el.getBoundingClientRect());
325
336
  }
326
337
  let stateReloadTimeout = null;
338
+ function getUuidsToUpdateRectsFor() {
339
+ const allUuids = Object.keys(registeredBlocks);
340
+ if (allUuids.length < 150) {
341
+ return allUuids;
342
+ }
343
+ return getVisibleBlocks();
344
+ }
327
345
  function updateVisibleRects() {
328
- const visible = getVisibleBlocks();
346
+ const toUpdate = getUuidsToUpdateRectsFor();
329
347
  const offset = ui.artboardOffset.value;
330
348
  const scale = ui.artboardScale.value;
331
- for (let i = 0; i < visible.length; i++) {
332
- const uuid = visible[i];
349
+ for (let i = 0; i < toUpdate.length; i++) {
350
+ const uuid = toUpdate[i];
333
351
  const el = registeredBlocks[uuid];
334
352
  if (!el) {
335
353
  continue;
@@ -376,7 +394,7 @@ export default function(ui, debug) {
376
394
  stateReloadTimeout = window.setTimeout(updateVisibleRects, 300);
377
395
  });
378
396
  onBlokkliEvent("ui:resized", function() {
379
- getVisibleBlocks().forEach(refreshBlockRect);
397
+ updateVisibleRects();
380
398
  getVisibleFields().forEach(refreshFieldRect);
381
399
  logger.log("Refreshed all visible rects");
382
400
  });
@@ -417,11 +435,13 @@ export default function(ui, debug) {
417
435
  dragElementCache.set(block.uuid, el);
418
436
  return el;
419
437
  }
438
+ function isBlockVisible(uuid) {
439
+ return visibleBlocks.has(uuid);
440
+ }
420
441
  return {
421
442
  findBlock,
422
443
  getAllBlocks,
423
444
  findClosestBlock,
424
- getAllFields,
425
445
  getDropElementMarkup,
426
446
  getBlockField,
427
447
  findField,
@@ -434,13 +454,16 @@ export default function(ui, debug) {
434
454
  getVisibleFields,
435
455
  registerField,
436
456
  unregisterField,
457
+ updateFieldElement,
437
458
  getActiveProviderElement,
438
459
  getBlockRects,
439
460
  getBlockRect,
440
461
  getFieldRect,
441
462
  refreshBlockRect,
463
+ isBlockVisible,
442
464
  isReady: computed(() => mutationsReady.value && intersectionReady.value),
443
465
  init,
444
- getDragElement
466
+ getDragElement,
467
+ updateVisibleRects
445
468
  };
446
469
  }
@@ -10,7 +10,7 @@ export default function (): {
10
10
  features: ComputedRef<{
11
11
  id: ValidFeatureKey;
12
12
  label?: string | undefined;
13
- icon: import("../../../playground/.nuxt/blokkli/icons").BlokkliIcon;
13
+ icon: import("../../../.nuxt/blokkli/icons").BlokkliIcon;
14
14
  description?: string | undefined;
15
15
  dependencies?: ValidFeatureKey[] | undefined;
16
16
  viewports?: import("../constants").Viewport[] | undefined;
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * This file should contain all helpers that are meant for runtime functionality, such as defineBlokkli composable or <BlokkliProvider>.
3
3
  */
4
+ import type { FieldListItemTyped } from '#blokkli/generated-types';
4
5
  import type { BlockOptionDefinition } from '#blokkli/types/blokkOptions';
6
+ import type { FieldListItem } from '#blokkli/types';
5
7
  /**
6
8
  * Map all kinds of truthy values for a checkbox.
7
9
  * Returns our "internal" value of a checkbox state.
@@ -13,3 +15,7 @@ export declare function mapCheckboxTrue(v?: unknown): '1' | '0';
13
15
  * Internally, all option values are stored as strings. This function maps the stored data to the runtime value.
14
16
  */
15
17
  export declare function getRuntimeOptionValue(definition: Pick<BlockOptionDefinition, 'type' | 'default'>, value: string | string[] | boolean | undefined | null | number): string | string[] | boolean | number;
18
+ /**
19
+ * Determines whether an item is visible.
20
+ */
21
+ export declare function isVisibleByOptions(item?: FieldListItemTyped | FieldListItem, language?: string): boolean;
@@ -1,3 +1,8 @@
1
+ import {
2
+ bundlesWithVisibleLanguage,
3
+ bundlesWithHiddenGlobally
4
+ } from "#blokkli/default-global-options";
5
+ import { BK_HIDDEN_GLOBALLY, BK_VISIBLE_LANGUAGES } from "../symbols.js";
1
6
  export function mapCheckboxTrue(v) {
2
7
  return v === true || v === "1" || v === 1 || v === "true" ? "1" : "0";
3
8
  }
@@ -31,3 +36,23 @@ export function getRuntimeOptionValue(definition, value) {
31
36
  }
32
37
  return "";
33
38
  }
39
+ export function isVisibleByOptions(item, language) {
40
+ if (!item) {
41
+ return false;
42
+ }
43
+ if (item.options) {
44
+ if (bundlesWithHiddenGlobally.includes(item.bundle) && mapCheckboxTrue(item.options[BK_HIDDEN_GLOBALLY]) === "1") {
45
+ return false;
46
+ }
47
+ if (bundlesWithVisibleLanguage.includes(item.bundle)) {
48
+ const option = item.options[BK_VISIBLE_LANGUAGES];
49
+ if (language && option && typeof option === "string") {
50
+ const languages = option.split(",");
51
+ if (languages.length && !languages.includes(language)) {
52
+ return false;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ return true;
58
+ }
@@ -9,7 +9,7 @@ export type SelectionProvider = {
9
9
  /**
10
10
  * The currently selected UUIDs as a map.
11
11
  */
12
- uuidsMap: ComputedRef<Record<string, boolean>>;
12
+ uuidsSet: ComputedRef<Set<string>>;
13
13
  /**
14
14
  * The currently selected blocks.
15
15
  */
@@ -58,5 +58,6 @@ export type SelectionProvider = {
58
58
  * The block bundles of the items being dragged.
59
59
  */
60
60
  dragItemsBundles: ComputedRef<string[]>;
61
+ isBlockSelected(uuid: string): boolean;
61
62
  };
62
63
  export default function (dom: DomProvider): SelectionProvider;
@@ -20,12 +20,7 @@ export default function(dom) {
20
20
  const dragItemsBundles = computed(
21
21
  () => dragItems.value.map((v) => v.itemBundle).filter(falsy)
22
22
  );
23
- const uuidsMap = computed(() => {
24
- return selectedUuids.value.reduce((acc, uuid) => {
25
- acc[uuid] = true;
26
- return acc;
27
- }, {});
28
- });
23
+ const uuidsSet = computed(() => new Set(selectedUuids.value));
29
24
  const isDragging = computed(() => !!draggingMode.value);
30
25
  const blocks = computed(
31
26
  () => selectedUuids.value.map((uuid) => {
@@ -130,6 +125,9 @@ export default function(dom) {
130
125
  (v) => v.itemType === "existing" || v.itemType === "existing_structure"
131
126
  );
132
127
  });
128
+ function isBlockSelected(uuid) {
129
+ return uuidsSet.value.has(uuid);
130
+ }
133
131
  return {
134
132
  uuids: selectedUuids,
135
133
  blocks,
@@ -143,7 +141,8 @@ export default function(dom) {
143
141
  draggingMode,
144
142
  interactionMode,
145
143
  dragItems,
146
- uuidsMap,
147
- dragItemsBundles
144
+ uuidsSet,
145
+ dragItemsBundles,
146
+ isBlockSelected
148
147
  };
149
148
  }
@@ -2,15 +2,22 @@ export declare const INJECT_APP: unique symbol;
2
2
  export declare const INJECT_EDIT_CONTEXT: unique symbol;
3
3
  export declare const INJECT_IS_EDITING: unique symbol;
4
4
  export declare const INJECT_IS_NESTED: unique symbol;
5
+ export declare const INJECT_NESTING_LEVEL: unique symbol;
5
6
  export declare const INJECT_IS_PREVIEW: unique symbol;
6
7
  export declare const INJECT_IS_IN_REUSABLE: unique symbol;
7
8
  export declare const INJECT_REUSABLE_OPTIONS: unique symbol;
8
9
  export declare const INJECT_FIELD_LIST_TYPE: unique symbol;
9
10
  export declare const INJECT_FIELD_LIST_BLOCKS: unique symbol;
11
+ export declare const INJECT_FIELD_PROXY_MODE: unique symbol;
12
+ export declare const INJECT_FIELD_USES_PROXY: unique symbol;
13
+ export declare const INJECT_GLOBAL_PROXY_MODE: unique symbol;
10
14
  export declare const INJECT_PROVIDER_BLOCKS: unique symbol;
11
15
  export declare const INJECT_BLOCK_ITEM: unique symbol;
12
16
  export declare const INJECT_MUTATED_FIELDS_MAP: unique symbol;
13
17
  export declare const INJECT_ENTITY_CONTEXT: unique symbol;
18
+ export declare const INJECT_PROVIDER_CONTEXT: unique symbol;
14
19
  export declare const INJECT_FRAGMENT_CONTEXT: unique symbol;
15
20
  export declare const INJECT_EDIT_FIELD_LIST_COMPONENT: unique symbol;
16
21
  export declare const INJECT_EDIT_LOGGER: unique symbol;
22
+ export declare const BK_HIDDEN_GLOBALLY = "bkHiddenGlobally";
23
+ export declare const BK_VISIBLE_LANGUAGES = "bkVisibleLanguages";
@@ -2,17 +2,24 @@ export const INJECT_APP = Symbol("blokkli_app");
2
2
  export const INJECT_EDIT_CONTEXT = Symbol("blokkli_edit_context");
3
3
  export const INJECT_IS_EDITING = Symbol("blokkli_is_editing");
4
4
  export const INJECT_IS_NESTED = Symbol("blokkli_is_nested");
5
+ export const INJECT_NESTING_LEVEL = Symbol("blokkli_nesting_level");
5
6
  export const INJECT_IS_PREVIEW = Symbol("blokkli_is_preview");
6
7
  export const INJECT_IS_IN_REUSABLE = Symbol("blokkli_is_in_reusable");
7
8
  export const INJECT_REUSABLE_OPTIONS = Symbol("blokkli_from_library_options");
8
9
  export const INJECT_FIELD_LIST_TYPE = Symbol("blokkli_field_list_type");
9
10
  export const INJECT_FIELD_LIST_BLOCKS = Symbol("blokkli_field_list_blocks");
11
+ export const INJECT_FIELD_PROXY_MODE = Symbol("blokkli_field_proxy_mode");
12
+ export const INJECT_FIELD_USES_PROXY = Symbol("blokkli_field_uses_proxy");
13
+ export const INJECT_GLOBAL_PROXY_MODE = Symbol("blokkli_global_proxy_mode");
10
14
  export const INJECT_PROVIDER_BLOCKS = Symbol("blokkli_provider_blocks");
11
15
  export const INJECT_BLOCK_ITEM = Symbol("blokkli_block_item");
12
16
  export const INJECT_MUTATED_FIELDS_MAP = Symbol("blokkli_mutated_fields_map");
13
17
  export const INJECT_ENTITY_CONTEXT = Symbol("blokkli_entity_context");
18
+ export const INJECT_PROVIDER_CONTEXT = Symbol("blokkli_provider_context");
14
19
  export const INJECT_FRAGMENT_CONTEXT = Symbol("blokkli_fragment_context");
15
20
  export const INJECT_EDIT_FIELD_LIST_COMPONENT = Symbol(
16
21
  "blokkli_edit_field_list_component"
17
22
  );
18
23
  export const INJECT_EDIT_LOGGER = Symbol("blokkli_edit_logger");
24
+ export const BK_HIDDEN_GLOBALLY = "bkHiddenGlobally";
25
+ export const BK_VISIBLE_LANGUAGES = "bkVisibleLanguages";
@@ -3,7 +3,7 @@ import type { FieldConfig, BlockBundleDefinition, EditableFieldConfig, BlockDefi
3
3
  import type { AdapterContext, BlokkliAdapter } from '../adapter.js';
4
4
  import type { SelectionProvider } from './selectionProvider.js';
5
5
  export type BlokkliBlockType = BlockBundleDefinition & {
6
- definition: BlockDefinitionInput<BlockDefinitionOptionsInput, any[]> | undefined;
6
+ definition: BlockDefinitionInput<BlockDefinitionOptionsInput, never[]> | undefined;
7
7
  };
8
8
  interface MappableConfig {
9
9
  entityType: string;
@@ -15,6 +15,7 @@ export type UiProvider = {
15
15
  isDesktop: ComputedRef<boolean>;
16
16
  isArtboard: () => boolean;
17
17
  isAnimating: Ref<boolean>;
18
+ isProxyMode: Ref<boolean>;
18
19
  useAnimations: ComputedRef<boolean>;
19
20
  lowPerformanceMode: ComputedRef<boolean>;
20
21
  toolbarHeight: ComputedRef<number>;
@@ -8,10 +8,12 @@ import {
8
8
  import { eventBus } from "./eventBus.js";
9
9
  import { falsy } from "./index.js";
10
10
  const ARTBOARD_CLASS = "bk-is-artboard";
11
+ const CLASS_PROXY_MODE = "bk-is-proxy-mode";
11
12
  export default function(storage) {
12
13
  let cachedRootElement = null;
13
14
  let cachedArtboardElement = null;
14
15
  let cachedProviderElement = null;
16
+ const isProxyMode = ref(false);
15
17
  const menuIsOpen = ref(false);
16
18
  const isAnimating = ref(false);
17
19
  const openContextMenu = ref("");
@@ -197,10 +199,18 @@ export default function(storage) {
197
199
  height: visibleViewportHeight.value - 2 * viewportPadding.value
198
200
  };
199
201
  });
202
+ function setProxyModeClass() {
203
+ document.documentElement.classList.remove(CLASS_PROXY_MODE);
204
+ if (isProxyMode.value) {
205
+ document.documentElement.classList.add(CLASS_PROXY_MODE);
206
+ }
207
+ }
208
+ watch(isProxyMode, setProxyModeClass);
200
209
  onMounted(() => {
201
210
  document.documentElement.classList.add("bk-html-root");
202
211
  document.body.classList.add("bk-body");
203
212
  document.documentElement.classList.add(ARTBOARD_CLASS);
213
+ setProxyModeClass();
204
214
  viewportWidth.value = window.innerWidth;
205
215
  viewportHeight.value = window.innerHeight;
206
216
  window.addEventListener("resize", onResize);
@@ -212,6 +222,7 @@ export default function(storage) {
212
222
  document.documentElement.classList.remove("bk-html-root");
213
223
  document.body.classList.remove("bk-body");
214
224
  document.documentElement.classList.remove(ARTBOARD_CLASS);
225
+ document.documentElement.classList.remove(CLASS_PROXY_MODE);
215
226
  clearTimeout(resizeTimeout);
216
227
  const artboard = artboardElement();
217
228
  resizeObserver.unobserve(artboard);
@@ -224,14 +235,15 @@ export default function(storage) {
224
235
  };
225
236
  });
226
237
  function getAbsoluteElementRect(v, providedScale, providedOffset) {
227
- const rect = "x" in v && "y" in v && "width" in v && "height" in v ? v : v.getBoundingClientRect();
238
+ const rect = v instanceof HTMLElement ? v.getBoundingClientRect() : v;
228
239
  const scale = providedScale || artboardScale.value;
229
240
  const offset = providedOffset || artboardOffset.value;
230
241
  return {
231
242
  x: rect.x / scale - offset.x / scale,
232
243
  y: rect.y / scale - offset.y / scale,
233
- width: rect.width / scale,
234
- height: rect.height / scale
244
+ // Force at least a size of 24.
245
+ width: Math.max(rect.width / scale, 24),
246
+ height: Math.max(rect.height / scale, 24)
235
247
  };
236
248
  }
237
249
  function getViewportRelativeRect(rect) {
@@ -268,6 +280,7 @@ export default function(storage) {
268
280
  openContextMenu,
269
281
  viewport,
270
282
  artboardSize: computed(() => artboardSize.value),
283
+ isProxyMode,
271
284
  artboardScale,
272
285
  artboardOffset,
273
286
  selectionTopLeft,
@@ -9,6 +9,9 @@ type RectangleBufferRect = Rectangle & {
9
9
  type RectangleBufferCollectorOptions = {
10
10
  padding?: number;
11
11
  };
12
+ type PlacedRectangle = Rectangle & {
13
+ originalY: number;
14
+ };
12
15
  export declare class RectangleBufferCollector<T extends RectangleBufferRect> {
13
16
  gl?: WebGLRenderingContext;
14
17
  added: Set<string>;
@@ -22,9 +25,11 @@ export declare class RectangleBufferCollector<T extends RectangleBufferRect> {
22
25
  radius: number[];
23
26
  index: number;
24
27
  bufferInfo: BufferInfo | null;
28
+ placedRects: PlacedRectangle[];
25
29
  constructor(gl?: WebGLRenderingContext, _options?: RectangleBufferCollectorOptions);
26
30
  reset(): void;
27
- addRectangle(rect: Omit<T, 'index'>, type: number): void;
31
+ getIdealPosition(x: number, y: number, width: number, height: number): Rectangle;
32
+ addRectangle(rect: Omit<T, 'index'>, type: number, checkOverlap?: boolean): void;
28
33
  getIndex(id: string): number | undefined;
29
34
  updateRectangle(): void;
30
35
  createBufferInfo(): BufferInfo | null;
@@ -1,4 +1,5 @@
1
1
  import { createBufferInfoFromArrays } from "twgl.js";
2
+ import { intersects } from "../index.js";
2
3
  export class RectangleBufferCollector {
3
4
  gl;
4
5
  added = /* @__PURE__ */ new Set();
@@ -12,6 +13,7 @@ export class RectangleBufferCollector {
12
13
  radius = [];
13
14
  index = 0;
14
15
  bufferInfo = null;
16
+ placedRects = [];
15
17
  constructor(gl, _options) {
16
18
  this.gl = gl;
17
19
  }
@@ -28,11 +30,42 @@ export class RectangleBufferCollector {
28
30
  this.index = 0;
29
31
  this.bufferInfo = null;
30
32
  }
31
- addRectangle(rect, type) {
32
- const x = rect.x;
33
- const y = rect.y;
34
- const width = rect.width;
35
- const height = rect.height;
33
+ getIdealPosition(x, y, width, height) {
34
+ const rect = {
35
+ x,
36
+ y,
37
+ width,
38
+ height,
39
+ originalY: y
40
+ };
41
+ const intersections = [];
42
+ for (let i = 0; i < this.placedRects.length; i++) {
43
+ if (intersects(rect, this.placedRects[i])) {
44
+ intersections.push(this.placedRects[i]);
45
+ }
46
+ }
47
+ if (intersections.length === 0) {
48
+ this.placedRects.push(rect);
49
+ return rect;
50
+ }
51
+ intersections.sort((a, b) => b.originalY - a.originalY);
52
+ for (let i = 0; i < intersections.length; i++) {
53
+ const existingRect = intersections[i];
54
+ let iterations = 0;
55
+ const direction = y > existingRect.originalY ? -1 : 1;
56
+ while (intersects(rect, existingRect) && iterations < 10) {
57
+ rect.y = y + direction * (10 * (iterations + 1));
58
+ iterations++;
59
+ }
60
+ if (iterations >= 10) {
61
+ rect.y = y;
62
+ }
63
+ }
64
+ this.placedRects.push(rect);
65
+ return rect;
66
+ }
67
+ addRectangle(rect, type, checkOverlap = false) {
68
+ const { x, y, width, height } = checkOverlap ? this.getIdealPosition(rect.x, rect.y, rect.width, rect.height) : rect;
36
69
  this.positions.push(
37
70
  x,
38
71
  y,
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>eye</title><path d="M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z" /></svg>
@@ -3,18 +3,22 @@ export type ModuleOptionsSettings = {
3
3
  disable?: boolean;
4
4
  default?: 'vertical' | 'horizontal' | 'sidebar';
5
5
  };
6
- 'feature:artboard:persist'?: {
6
+ 'feature:block-add-list:hideDisabledBlocks'?: {
7
7
  disable?: boolean;
8
8
  default?: boolean;
9
9
  };
10
- 'feature:artboard:scrollSpeed'?: {
10
+ 'feature:artboard:momentum'?: {
11
11
  disable?: boolean;
12
- default?: number;
12
+ default?: boolean;
13
13
  };
14
- 'feature:block-add-list:hideDisabledBlocks'?: {
14
+ 'feature:artboard:persist'?: {
15
15
  disable?: boolean;
16
16
  default?: boolean;
17
17
  };
18
+ 'feature:artboard:scrollSpeed'?: {
19
+ disable?: boolean;
20
+ default?: number;
21
+ };
18
22
  'feature:clipboard:openSidebarOnPaste'?: {
19
23
  disable?: boolean;
20
24
  default?: boolean;
@@ -27,6 +31,10 @@ export type ModuleOptionsSettings = {
27
31
  disable?: boolean;
28
32
  default?: boolean;
29
33
  };
34
+ 'feature:publish:closeAfterPublish'?: {
35
+ disable?: boolean;
36
+ default?: boolean;
37
+ };
30
38
  'feature:settings:lowPerformanceMode'?: {
31
39
  disable?: boolean;
32
40
  default?: boolean;