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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +330 -93
  3. package/dist/modules/drupal/graphql/base/fragment.blokkliProps.graphql +1 -1
  4. package/dist/modules/drupal/graphql/features/comments.graphql +11 -8
  5. package/dist/modules/drupal/runtime/adapter/index.js +2 -2
  6. package/dist/runtime/blokkliPlugins/ItemAction/index.vue +1 -3
  7. package/dist/runtime/components/Blocks/FromLibrary/index.vue +4 -2
  8. package/dist/runtime/components/BlokkliEditable.vue +22 -4
  9. package/dist/runtime/components/BlokkliProvider.vue +29 -20
  10. package/dist/runtime/components/BlokkliProvider.vue.d.ts +2 -1
  11. package/dist/runtime/components/Edit/Actions/index.vue +9 -4
  12. package/dist/runtime/components/Edit/AnimationCanvas/index.vue +420 -25
  13. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +80 -0
  14. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue.d.ts +32 -0
  15. package/dist/runtime/components/Edit/Banner/index.vue +51 -0
  16. package/dist/runtime/components/Edit/Banner/index.vue.d.ts +18 -0
  17. package/dist/runtime/components/Edit/Dialog/index.vue +3 -0
  18. package/dist/runtime/components/Edit/Dialog/index.vue.d.ts +2 -0
  19. package/dist/runtime/components/Edit/EditIndicator.vue +118 -44
  20. package/dist/runtime/components/Edit/EditIndicator.vue.d.ts +3 -0
  21. package/dist/runtime/components/Edit/EditProvider.vue +79 -22
  22. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +2 -0
  23. package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +19 -20
  24. package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +1 -1
  25. package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +2 -0
  26. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue +35 -20
  27. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue.d.ts +5 -3
  28. package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue +29 -0
  29. package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue.d.ts +13 -0
  30. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue +22 -16
  31. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue.d.ts +1 -0
  32. package/dist/runtime/components/Edit/Features/Comments/Overlay/index.vue +15 -6
  33. package/dist/runtime/components/Edit/Features/Comments/index.vue +20 -8
  34. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +26 -35
  35. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue +240 -0
  36. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue.d.ts +6 -0
  37. package/dist/runtime/components/Edit/Features/Debug/index.vue +4 -165
  38. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +1 -1
  39. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/fragment.glsl +7 -1
  40. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +62 -39
  41. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/vertex.glsl +1 -0
  42. package/dist/runtime/components/Edit/Features/Edit/index.vue +1 -1
  43. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +63 -3
  44. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Plaintext/index.vue +13 -9
  45. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +17 -76
  46. package/dist/runtime/components/Edit/Features/EditableField/index.vue +1 -1
  47. package/dist/runtime/components/Edit/Features/History/index.vue +5 -2
  48. package/dist/runtime/components/Edit/Features/Hover/Overlay/fragment.glsl +139 -0
  49. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +270 -0
  50. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue.d.ts +6 -0
  51. package/dist/runtime/components/Edit/Features/Hover/Overlay/vertex.glsl +117 -0
  52. package/dist/runtime/components/Edit/Features/Hover/index.vue +25 -0
  53. package/dist/runtime/components/Edit/Features/Library/LibraryDialog/index.vue +19 -27
  54. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +27 -23
  55. package/dist/runtime/components/Edit/Features/Library/index.vue +2 -1
  56. package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +34 -27
  57. package/dist/runtime/components/Edit/Features/MultiSelect/index.vue +2 -4
  58. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +6 -1
  59. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +1 -0
  60. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue +35 -0
  61. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue.d.ts +6 -0
  62. package/dist/runtime/components/Edit/Features/Ownership/index.vue +7 -25
  63. package/dist/runtime/components/Edit/Features/ProxyView/index.vue +5 -1
  64. package/dist/runtime/components/Edit/Features/Publish/Dialog/Summary.vue +2 -2
  65. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +17 -7
  66. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +39 -74
  67. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +4 -2
  68. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/fragment.glsl +106 -0
  69. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +417 -0
  70. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue.d.ts +32 -0
  71. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/vertex.glsl +102 -0
  72. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +33 -106
  73. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +88 -29
  74. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +2 -0
  75. package/dist/runtime/components/Edit/Features/Selection/Overlay/vertex.glsl +11 -2
  76. package/dist/runtime/components/Edit/Features/Selection/index.vue +26 -19
  77. package/dist/runtime/components/Edit/Features/Translations/Banner/index.vue +17 -11
  78. package/dist/runtime/components/Edit/Features/Translations/index.vue +13 -16
  79. package/dist/runtime/components/Edit/Form/Text/index.vue +2 -1
  80. package/dist/runtime/components/Edit/Form/Text/index.vue.d.ts +1 -0
  81. package/dist/runtime/components/Edit/Indicators/index.vue +1 -1
  82. package/dist/runtime/components/Edit/Konami/Game/index.vue +5 -5
  83. package/dist/runtime/components/Edit/index.d.ts +5 -3
  84. package/dist/runtime/components/Edit/index.js +8 -4
  85. package/dist/runtime/composables/defineBlokkli.js +5 -3
  86. package/dist/runtime/css/output.css +1 -1
  87. package/dist/runtime/helpers/animationProvider.d.ts +34 -1
  88. package/dist/runtime/helpers/animationProvider.js +175 -48
  89. package/dist/runtime/helpers/composables/defineRenderer.d.ts +8 -0
  90. package/dist/runtime/helpers/composables/defineRenderer.js +8 -0
  91. package/dist/runtime/helpers/composables/useDelayedIntersectionObserver.d.ts +1 -1
  92. package/dist/runtime/helpers/composables/useDelayedIntersectionObserver.js +3 -2
  93. package/dist/runtime/helpers/composables/useStickyToolbar.d.ts +4 -1
  94. package/dist/runtime/helpers/composables/useStickyToolbar.js +53 -35
  95. package/dist/runtime/helpers/dom/index.d.ts +1 -0
  96. package/dist/runtime/helpers/domProvider.d.ts +46 -0
  97. package/dist/runtime/helpers/domProvider.js +101 -7
  98. package/dist/runtime/helpers/editableProvider.d.ts +14 -0
  99. package/dist/runtime/helpers/editableProvider.js +144 -0
  100. package/dist/runtime/helpers/stateProvider.d.ts +6 -2
  101. package/dist/runtime/helpers/stateProvider.js +66 -3
  102. package/dist/runtime/helpers/storageProvider.d.ts +3 -2
  103. package/dist/runtime/helpers/storageProvider.js +6 -2
  104. package/dist/runtime/helpers/symbols.d.ts +1 -0
  105. package/dist/runtime/helpers/symbols.js +1 -0
  106. package/dist/runtime/helpers/uiProvider.d.ts +8 -1
  107. package/dist/runtime/helpers/uiProvider.js +34 -2
  108. package/dist/runtime/helpers/webgl/index.d.ts +11 -2
  109. package/dist/runtime/helpers/webgl/index.js +162 -7
  110. package/dist/runtime/plugins/blokkliEditable.js +74 -3
  111. package/dist/runtime/types/index.d.ts +13 -1
  112. package/package.json +1 -1
  113. package/dist/runtime/components/Edit/DragInteractions/index.vue +0 -401
  114. package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue +0 -54
  115. package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue.d.ts +0 -14
  116. /package/dist/runtime/components/Edit/{DragInteractions → Features/Hover}/index.vue.d.ts +0 -0
@@ -2,6 +2,24 @@ import { type ComputedRef, type WritableComputedRef } from '#imports';
2
2
  import type { UiProvider } from './uiProvider.js';
3
3
  import { type ProgramInfo } from 'twgl.js';
4
4
  import type { StorageProvider } from './storageProvider.js';
5
+ import type { CursorKeyword } from './dom/index.js';
6
+ import type { CanvasDrawEvent, Coord } from '#blokkli/types';
7
+ import type { SelectionProvider } from './selectionProvider.js';
8
+ export type RenderContext = CanvasDrawEvent & {
9
+ gl: WebGLRenderingContext;
10
+ };
11
+ export type Renderer = {
12
+ id: string;
13
+ zIndex: number;
14
+ enabled?: () => boolean;
15
+ only?: boolean | (() => boolean);
16
+ cursor?: () => CursorKeyword | undefined | null;
17
+ onClick?: (coord: {
18
+ mouse: Coord;
19
+ mouseArtboard: Coord;
20
+ }) => boolean | undefined;
21
+ render: (ctx: RenderContext) => void;
22
+ };
5
23
  export type AnimationProvider = {
6
24
  /**
7
25
  * Request an animation loop. Should be called when UI state changes.
@@ -23,5 +41,20 @@ export type AnimationProvider = {
23
41
  */
24
42
  registerProgram: (id: string, gl: WebGLRenderingContext, shaders: string[]) => ProgramInfo;
25
43
  setMouseCoords: (x: number, y: number) => void;
44
+ cursor: ComputedRef<CursorKeyword>;
45
+ /**
46
+ * Handle a click event by calling onClick handlers on renderers.
47
+ * Returns true if any renderer claimed the click, false otherwise.
48
+ */
49
+ handleClick: (x: number, y: number) => boolean;
50
+ /**
51
+ * Register a WebGL renderer with a specific zIndex.
52
+ * Returns an unregister function.
53
+ */
54
+ registerRenderer: (id: string, config: Omit<Renderer, 'id'>) => () => void;
55
+ /**
56
+ * Unregister a WebGL renderer.
57
+ */
58
+ unregisterRenderer: (id: string) => void;
26
59
  };
27
- export default function (ui: UiProvider, storage: StorageProvider): AnimationProvider;
60
+ export default function (ui: UiProvider, storage: StorageProvider, selection: SelectionProvider): AnimationProvider;
@@ -8,13 +8,81 @@ import {
8
8
  } from "#imports";
9
9
  import { eventBus } from "#blokkli/helpers/eventBus";
10
10
  import { createProgramInfo } from "twgl.js";
11
- export default function(ui, storage) {
11
+ export default function(ui, storage, selection) {
12
12
  const webglEnabled = storage.use("webglEnabled", true);
13
+ const currentCursor = ref("default");
14
+ const cursor = computed(() => currentCursor.value);
15
+ const renderers = /* @__PURE__ */ new Map();
16
+ function registerRenderer(id, config) {
17
+ renderers.set(id, { id, ...config });
18
+ return () => unregisterRenderer(id);
19
+ }
20
+ function unregisterRenderer(id) {
21
+ renderers.delete(id);
22
+ }
23
+ function handleClick(x, y) {
24
+ const sortedRenderers = Array.from(renderers.values()).filter((renderer) => !renderer.enabled || renderer.enabled()).sort((a, b) => b.zIndex - a.zIndex);
25
+ const artboardOffset = ui.artboardOffset.value;
26
+ const artboardScale = ui.artboardScale.value;
27
+ const mouseArtboard = {
28
+ x: (x - artboardOffset.x) / artboardScale,
29
+ y: (y - artboardOffset.y) / artboardScale
30
+ };
31
+ for (const renderer of sortedRenderers) {
32
+ if (renderer.onClick) {
33
+ const claimed = renderer.onClick({
34
+ mouse: { x, y },
35
+ mouseArtboard
36
+ });
37
+ if (claimed === true) {
38
+ return true;
39
+ }
40
+ }
41
+ }
42
+ return false;
43
+ }
13
44
  let mouseX = 0;
14
45
  let mouseY = 0;
15
46
  let iterator = 120;
16
47
  const webglSupported = ref(null);
48
+ const maxCanvasWidth = ref(16384);
49
+ const maxCanvasHeight = ref(16384);
50
+ let webglLimitsQueried = false;
51
+ function getCanvasElement() {
52
+ const el = document.querySelector("#bk-animation-canvas-webgl");
53
+ if (!(el instanceof HTMLCanvasElement)) {
54
+ throw new TypeError("Failed to locate WebGL canvas.");
55
+ }
56
+ return el;
57
+ }
58
+ function gl() {
59
+ if (!webglEnabled.value) {
60
+ return;
61
+ }
62
+ if (webglSupported.value === false) {
63
+ return;
64
+ }
65
+ const canvas = getCanvasElement();
66
+ const glContext = canvas.getContext("webgl2", {
67
+ premultipliedAlpha: true
68
+ });
69
+ if (!glContext) {
70
+ webglSupported.value = false;
71
+ return;
72
+ }
73
+ webglSupported.value = true;
74
+ if (!webglLimitsQueried) {
75
+ const maxViewportDims = glContext.getParameter(
76
+ glContext.MAX_VIEWPORT_DIMS
77
+ );
78
+ maxCanvasWidth.value = maxViewportDims[0] || 16384;
79
+ maxCanvasHeight.value = maxViewportDims[1] || 16384;
80
+ webglLimitsQueried = true;
81
+ }
82
+ return glContext;
83
+ }
17
84
  useAnimationFrame((time) => {
85
+ const selectedUuids = [...selection.uuids.value];
18
86
  if (iterator < 1) {
19
87
  return;
20
88
  }
@@ -26,10 +94,79 @@ export default function(ui, storage) {
26
94
  fieldAreas: [],
27
95
  time
28
96
  });
97
+ const glContext = gl();
98
+ if (glContext) {
99
+ glContext.enable(glContext.BLEND);
100
+ glContext.blendFunc(glContext.SRC_ALPHA_SATURATE, glContext.ONE);
101
+ glContext.blendEquation(glContext.FUNC_ADD);
102
+ glContext.clearColor(0, 0, 0, 0);
103
+ glContext.clear(glContext.COLOR_BUFFER_BIT);
104
+ }
105
+ const sortedRenderers = Array.from(renderers.values()).sort(
106
+ (a, b) => a.zIndex - b.zIndex
107
+ );
108
+ let onlyRenderer = null;
109
+ for (const renderer of sortedRenderers) {
110
+ if (!renderer.enabled || renderer.enabled()) {
111
+ const onlyValue = typeof renderer.only === "function" ? renderer.only() : renderer.only;
112
+ if (onlyValue) {
113
+ onlyRenderer = renderer;
114
+ break;
115
+ }
116
+ }
117
+ }
118
+ const artboardOffset = ui.artboardOffset.value;
119
+ const artboardScale = ui.artboardScale.value;
120
+ const artboardSize = ui.artboardSize.value;
121
+ const mouseArtboard = {
122
+ x: (mouseX - artboardOffset.x) / artboardScale,
123
+ y: (mouseY - artboardOffset.y) / artboardScale
124
+ };
125
+ const ctx = {
126
+ gl: glContext,
127
+ time,
128
+ mouseX,
129
+ mouseY,
130
+ mouseArtboard,
131
+ artboardOffset,
132
+ artboardScale,
133
+ artboardSize,
134
+ selectedUuids
135
+ };
136
+ if (onlyRenderer) {
137
+ const glContext2 = gl();
138
+ if (glContext2) {
139
+ onlyRenderer.render(ctx);
140
+ }
141
+ } else {
142
+ for (let i = sortedRenderers.length - 1; i >= 0; i--) {
143
+ const renderer = sortedRenderers[i];
144
+ if (!renderer.enabled || renderer.enabled()) {
145
+ const glContext2 = gl();
146
+ if (glContext2) {
147
+ renderer.render(ctx);
148
+ }
149
+ }
150
+ }
151
+ }
152
+ let newCursor = "default";
153
+ for (let i = sortedRenderers.length - 1; i >= 0; i--) {
154
+ const renderer = sortedRenderers[i];
155
+ if (renderer.cursor && (!renderer.enabled || renderer.enabled())) {
156
+ const cursorValue = renderer.cursor();
157
+ if (cursorValue) {
158
+ newCursor = cursorValue;
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ currentCursor.value = newCursor;
164
+ eventBus.emit("canvas:draw", ctx);
165
+ eventBus.emit("animationFrame:after");
29
166
  });
30
167
  function onWindowMouseMove(e) {
31
- mouseX = e.clientX;
32
- mouseY = e.clientY;
168
+ mouseX = e.pageX;
169
+ mouseY = e.pageY;
33
170
  }
34
171
  onMounted(() => {
35
172
  document.body.addEventListener("wheel", requestDraw, { passive: false });
@@ -49,39 +186,49 @@ export default function(ui, storage) {
49
186
  onBlokkliEvent("option:update", requestDraw);
50
187
  onBlokkliEvent("state:reloaded", requestDraw);
51
188
  const dpi = computed(() => {
52
- if (ui.lowPerformanceMode.value) {
53
- return 0.5;
54
- }
55
- if (ui.isMobile.value) {
56
- return window.devicePixelRatio;
57
- }
58
- return Math.min(window.devicePixelRatio, 2.5);
189
+ const viewportWidth = ui.viewport.value.width;
190
+ const viewportHeight = ui.viewport.value.height;
191
+ const deviceRatio = window.devicePixelRatio;
192
+ const maxDpiByWidth = maxCanvasWidth.value / viewportWidth;
193
+ const maxDpiByHeight = maxCanvasHeight.value / viewportHeight;
194
+ const MAX_PIXELS = 16e6;
195
+ const maxDpiByPixels = Math.sqrt(
196
+ MAX_PIXELS / (viewportWidth * viewportHeight)
197
+ );
198
+ const maxDpi = ui.lowPerformanceMode.value ? 0.5 : 2;
199
+ return Math.min(
200
+ deviceRatio,
201
+ maxDpiByWidth,
202
+ maxDpiByHeight,
203
+ maxDpiByPixels,
204
+ maxDpi
205
+ );
59
206
  });
60
- function setSharedUniforms(gl, programInfo) {
207
+ function setSharedUniforms(gl2, programInfo) {
61
208
  const resolution = [ui.viewport.value.width, ui.viewport.value.height];
62
- gl.uniform2fv(
63
- gl.getUniformLocation(programInfo.program, "u_resolution"),
209
+ gl2.uniform2fv(
210
+ gl2.getUniformLocation(programInfo.program, "u_resolution"),
64
211
  resolution
65
212
  );
66
213
  const offset = ui.artboardOffset.value;
67
- gl.uniform1f(
68
- gl.getUniformLocation(programInfo.program, "u_offset_x"),
214
+ gl2.uniform1f(
215
+ gl2.getUniformLocation(programInfo.program, "u_offset_x"),
69
216
  offset.x
70
217
  );
71
- gl.uniform1f(
72
- gl.getUniformLocation(programInfo.program, "u_offset_y"),
218
+ gl2.uniform1f(
219
+ gl2.getUniformLocation(programInfo.program, "u_offset_y"),
73
220
  offset.y
74
221
  );
75
- gl.uniform1f(
76
- gl.getUniformLocation(programInfo.program, "u_scale"),
222
+ gl2.uniform1f(
223
+ gl2.getUniformLocation(programInfo.program, "u_scale"),
77
224
  ui.artboardScale.value
78
225
  );
79
- gl.uniform1f(gl.getUniformLocation(programInfo.program, "u_dpi"), dpi.value);
226
+ gl2.uniform1f(gl2.getUniformLocation(programInfo.program, "u_dpi"), dpi.value);
80
227
  }
81
228
  const registeredPrograms = {};
82
- function registerProgram(id, gl, shaders) {
229
+ function registerProgram(id, gl2, shaders) {
83
230
  if (!registeredPrograms[id]) {
84
- registeredPrograms[id] = createProgramInfo(gl, shaders);
231
+ registeredPrograms[id] = createProgramInfo(gl2, shaders);
85
232
  }
86
233
  return registeredPrograms[id];
87
234
  }
@@ -90,39 +237,19 @@ export default function(ui, storage) {
90
237
  mouseY = y;
91
238
  iterator = 120;
92
239
  }
93
- function getCanvasElement() {
94
- const el = document.querySelector("#bk-animation-canvas-webgl");
95
- if (!(el instanceof HTMLCanvasElement)) {
96
- throw new TypeError("Failed to locate WebGL canvas.");
97
- }
98
- return el;
99
- }
100
240
  return {
101
241
  requestDraw,
102
- gl: function() {
103
- if (!webglEnabled.value) {
104
- return;
105
- }
106
- if (webglSupported.value === false) {
107
- return;
108
- }
109
- const canvas = getCanvasElement();
110
- const gl = canvas.getContext("webgl2", {
111
- premultipliedAlpha: true
112
- });
113
- if (!gl) {
114
- webglSupported.value = false;
115
- return;
116
- }
117
- webglSupported.value = true;
118
- return gl;
119
- },
242
+ gl,
120
243
  setSharedUniforms,
121
244
  dpi,
122
245
  registerProgram,
123
246
  setMouseCoords,
124
247
  webglSupported: computed(() => webglSupported.value && webglEnabled.value),
125
248
  webglEnabled,
126
- getCanvasElement
249
+ getCanvasElement,
250
+ cursor,
251
+ handleClick,
252
+ registerRenderer,
253
+ unregisterRenderer
127
254
  };
128
255
  }
@@ -0,0 +1,8 @@
1
+ import type { Renderer } from '../animationProvider.js';
2
+ /**
3
+ * Register a WebGL renderer with automatic cleanup on unmount.
4
+ *
5
+ * @param id - Unique identifier for the renderer
6
+ * @param config - Renderer configuration (zIndex, enabled, render)
7
+ */
8
+ export default function defineRenderer(id: string, config: Omit<Renderer, 'id'>): void;
@@ -0,0 +1,8 @@
1
+ import { onBeforeUnmount, useBlokkli } from "#imports";
2
+ export default function defineRenderer(id, config) {
3
+ const { animation } = useBlokkli();
4
+ const unregisterRenderer = animation.registerRenderer(id, config);
5
+ onBeforeUnmount(() => {
6
+ unregisterRenderer();
7
+ });
8
+ }
@@ -1,4 +1,4 @@
1
- export default function (callback: (entries: IntersectionObserverEntry[]) => void): {
1
+ export default function (callback: (entries: IntersectionObserverEntry[]) => void, options?: IntersectionObserverInit): {
2
2
  observe: (el: HTMLElement) => void;
3
3
  unobserve: (el: HTMLElement) => void;
4
4
  init: () => void;
@@ -1,9 +1,10 @@
1
- export default function(callback) {
1
+ export default function(callback, options = {}) {
2
2
  let observer = null;
3
3
  let collected = [];
4
4
  function init() {
5
5
  observer = new IntersectionObserver(callback, {
6
- threshold: 0
6
+ threshold: 0,
7
+ ...options
7
8
  });
8
9
  for (const el of collected) {
9
10
  observer.observe(el);
@@ -1,5 +1,6 @@
1
1
  import type { ComputedRef, ShallowRef } from 'vue';
2
- type PlacementVertical = 'top' | 'bottom' | 'auto';
2
+ import type { Coord } from '#blokkli/types';
3
+ export type PlacementVertical = 'top' | 'bottom' | 'auto';
3
4
  type PlacementHorizontal = 'left' | 'center';
4
5
  type UseStickyToolbarOptions = {
5
6
  getPlacementY?: () => PlacementVertical;
@@ -9,7 +10,9 @@ type UseStickyToolbarOptions = {
9
10
  getHeight?: () => number;
10
11
  getMargin?: () => number;
11
12
  getAnchorElement?: () => HTMLElement | null;
13
+ getAnchorCoordinates?: () => Coord | null;
12
14
  getCaretWidth?: () => number;
15
+ allowHorizontalOverflow?: boolean;
13
16
  };
14
17
  type UseStickyToolbar = {
15
18
  shouldRender: ComputedRef<boolean>;
@@ -39,26 +39,33 @@ export default function(el, options) {
39
39
  let minY = 0;
40
40
  let maxY = 0;
41
41
  let hasRects = false;
42
- if (options && options.getAnchorElement) {
43
- const anchorElement = options.getAnchorElement();
44
- if (anchorElement) {
45
- anchorRect ||= ui.getAbsoluteElementRect(
46
- anchorElement.getBoundingClientRect(),
47
- scale,
48
- offset
49
- );
50
- const rectX = (anchorRect.x + offset.x / scale) * scale;
51
- const rectY = (anchorRect.y + offset.y / scale) * scale;
52
- const rectRight = rectX + anchorRect.width * scale;
53
- const rectBottom = rectY + anchorRect.height * scale;
54
- minX = rectX;
55
- maxX = rectRight;
56
- minY = rectY;
57
- maxY = rectBottom;
58
- hasRects = true;
59
- }
42
+ const anchorElement = options && options.getAnchorElement ? options.getAnchorElement() : null;
43
+ const anchorCoordinates = options && options.getAnchorCoordinates ? options.getAnchorCoordinates() : null;
44
+ if (anchorCoordinates) {
45
+ const rectX = (anchorCoordinates.x + offset.x / scale) * scale;
46
+ const rectY = (anchorCoordinates.y + offset.y / scale) * scale;
47
+ minX = rectX;
48
+ maxX = rectX + 1;
49
+ minY = rectY;
50
+ maxY = rectY + 1;
51
+ hasRects = true;
52
+ } else if (anchorElement) {
53
+ anchorRect ||= ui.getAbsoluteElementRect(
54
+ anchorElement.getBoundingClientRect(),
55
+ scale,
56
+ offset
57
+ );
58
+ const rectX = (anchorRect.x + offset.x / scale) * scale;
59
+ const rectY = (anchorRect.y + offset.y / scale) * scale;
60
+ const rectRight = rectX + anchorRect.width * scale;
61
+ const rectBottom = rectY + anchorRect.height * scale;
62
+ minX = rectX;
63
+ maxX = rectRight;
64
+ minY = rectY;
65
+ maxY = rectBottom;
66
+ hasRects = true;
60
67
  } else {
61
- const rects = selection.blocks.value.map((block) => dom.getBlockRect(block.uuid)).filter(falsy).filter((rect2) => rect2.height || rect2.width);
68
+ const rects = selection.uuids.value.map((uuid) => dom.getBlockRect(uuid)).filter(falsy).filter((rect) => rect.height || rect.width);
62
69
  hasRects = !!rects.length;
63
70
  if (hasRects) {
64
71
  for (let i = 0; i < rects.length; i++) {
@@ -114,22 +121,33 @@ export default function(el, options) {
114
121
  } else {
115
122
  x = minX - xSubtract;
116
123
  }
117
- const rect = limitPlacedRect(
118
- {
119
- x,
120
- y,
121
- width,
122
- height
123
- },
124
- padding
125
- );
126
- const idealPosition = findIdealRectPosition(
127
- ui.viewportBlockingRects.value,
128
- rect,
129
- padding
130
- );
131
- if (!idealPosition) {
132
- return void 0;
124
+ const shouldAllowOverflow = options?.allowHorizontalOverflow && width > padding.width;
125
+ let idealPosition;
126
+ if (shouldAllowOverflow) {
127
+ const limitedY = Math.min(
128
+ Math.max(padding.y, y),
129
+ padding.height + padding.y - height
130
+ );
131
+ idealPosition = { x, y: limitedY };
132
+ } else {
133
+ const rect = limitPlacedRect(
134
+ {
135
+ x,
136
+ y,
137
+ width,
138
+ height
139
+ },
140
+ padding
141
+ );
142
+ const position = findIdealRectPosition(
143
+ ui.viewportBlockingRects.value,
144
+ rect,
145
+ padding
146
+ );
147
+ if (!position) {
148
+ return void 0;
149
+ }
150
+ idealPosition = position;
133
151
  }
134
152
  const caretWidth = getCaretWidth();
135
153
  const caretHalfWidth = caretWidth / 2;
@@ -62,3 +62,4 @@ export declare const MOUSE_BUTTON: Readonly<{
62
62
  */
63
63
  FIFTH: 4;
64
64
  }>;
65
+ export type CursorKeyword = 'auto' | 'default' | 'none' | 'context-menu' | 'help' | 'pointer' | 'progress' | 'wait' | 'cell' | 'crosshair' | 'text' | 'vertical-text' | 'alias' | 'copy' | 'move' | 'no-drop' | 'not-allowed' | 'e-resize' | 'n-resize' | 'ne-resize' | 'nw-resize' | 's-resize' | 'se-resize' | 'sw-resize' | 'w-resize' | 'ew-resize' | 'ns-resize' | 'nesw-resize' | 'nwse-resize' | 'col-resize' | 'row-resize' | 'all-scroll' | 'zoom-in' | 'zoom-out' | 'grab' | 'grabbing';
@@ -47,6 +47,52 @@ export type DomProvider = {
47
47
  * Get the drag element for a block.
48
48
  */
49
49
  getDragElement: (block: DraggableExistingBlock) => HTMLElement | undefined;
50
+ /**
51
+ * Get debug data for troubleshooting.
52
+ */
53
+ getDebugData: () => {
54
+ registeredBlocks: Array<{
55
+ uuid: string;
56
+ hasElement: boolean;
57
+ hasObservedElement: boolean;
58
+ hasRect: boolean;
59
+ hasCurrentKey: boolean;
60
+ isVisible: boolean;
61
+ inCache: boolean;
62
+ elementInfo?: {
63
+ tagName: string;
64
+ bundle?: string;
65
+ hostBundle?: string;
66
+ fieldListType?: string;
67
+ };
68
+ }>;
69
+ fields: Array<{
70
+ key: string;
71
+ isVisible: boolean;
72
+ hasRect: boolean;
73
+ entityType: string;
74
+ entityBundle: string;
75
+ fieldName: string;
76
+ }>;
77
+ summary: {
78
+ totalRegisteredBlocks: number;
79
+ totalBlocksWithElements: number;
80
+ totalObservedElements: number;
81
+ totalBlockRects: number;
82
+ totalVisibleBlocks: number;
83
+ totalRegisteredFields: number;
84
+ totalVisibleFields: number;
85
+ totalFieldRects: number;
86
+ cacheSize: number;
87
+ isInitializing: boolean;
88
+ isReady: boolean;
89
+ };
90
+ orphanedData: {
91
+ rectsWithoutRegistration: string[];
92
+ observedElementsWithoutRegistration: string[];
93
+ keysWithoutRegistration: string[];
94
+ };
95
+ };
50
96
  };
51
97
  export default function (ui: UiProvider, debug: DebugProvider, definitions: DefinitionProvider): DomProvider;
52
98
  export {};