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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +640 -137
  3. package/dist/modules/drupal/graphql/base/fragment.blokkliProps.graphql +1 -1
  4. package/dist/modules/drupal/graphql/base/fragment.paragraphsFieldItem.graphql +3 -1
  5. package/dist/modules/drupal/graphql/base/query.pbConfig.graphql +1 -10
  6. package/dist/modules/drupal/graphql/features/comments.graphql +11 -8
  7. package/dist/modules/drupal/graphql/mutations/set_paragraph_schedule.graphql +15 -0
  8. package/dist/modules/drupal/index.mjs +33 -0
  9. package/dist/modules/drupal/runtime/adapter/index.js +12 -4
  10. package/dist/runtime/adapter/index.d.ts +21 -0
  11. package/dist/runtime/blokkliPlugins/ContextMenu/Menu/index.vue +3 -0
  12. package/dist/runtime/blokkliPlugins/ItemAction/index.vue +23 -15
  13. package/dist/runtime/blokkliPlugins/ItemAction/index.vue.d.ts +20 -44
  14. package/dist/runtime/blokkliPlugins/TourItem/index.vue +10 -5
  15. package/dist/runtime/components/Blocks/FromLibrary/index.vue +4 -2
  16. package/dist/runtime/components/BlokkliEditable.vue +32 -14
  17. package/dist/runtime/components/BlokkliField.vue +3 -0
  18. package/dist/runtime/components/BlokkliField.vue.d.ts +3 -3
  19. package/dist/runtime/components/BlokkliItem.vue +1 -1
  20. package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
  21. package/dist/runtime/components/BlokkliProvider.vue +41 -28
  22. package/dist/runtime/components/BlokkliProvider.vue.d.ts +2 -1
  23. package/dist/runtime/components/Edit/Actions/index.vue +36 -20
  24. package/dist/runtime/components/Edit/AnimationCanvas/index.vue +436 -25
  25. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +83 -0
  26. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue.d.ts +32 -0
  27. package/dist/runtime/components/Edit/Banner/index.vue +51 -0
  28. package/dist/runtime/components/Edit/Banner/index.vue.d.ts +18 -0
  29. package/dist/runtime/components/Edit/Dialog/index.vue +6 -4
  30. package/dist/runtime/components/Edit/DraggableList.vue +15 -7
  31. package/dist/runtime/components/Edit/DraggableList.vue.d.ts +5 -5
  32. package/dist/runtime/components/Edit/EditIndicator.vue +118 -44
  33. package/dist/runtime/components/Edit/EditIndicator.vue.d.ts +3 -0
  34. package/dist/runtime/components/Edit/EditProvider.vue +101 -31
  35. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +3 -0
  36. package/dist/runtime/components/Edit/Features/AddList/index.vue +9 -11
  37. package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +28 -26
  38. package/dist/runtime/components/Edit/Features/Analyze/Renderer.vue +1 -1
  39. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +15 -11
  40. package/dist/runtime/components/Edit/Features/Anchors/Renderer.vue +19 -102
  41. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +3 -0
  42. package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +29 -53
  43. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue +154 -0
  44. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue.d.ts +27 -0
  45. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +222 -0
  46. package/dist/runtime/components/Edit/Features/{Selection/AddButtons/AddButtonsField.vue.d.ts → BlockScheduler/Dialog/index.vue.d.ts} +6 -9
  47. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +96 -0
  48. package/dist/runtime/components/Edit/Features/Clipboard/index.vue +15 -16
  49. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +51 -0
  50. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/{Group → Item}/index.vue.d.ts +9 -13
  51. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +46 -66
  52. package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +2 -0
  53. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue +35 -20
  54. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue.d.ts +5 -3
  55. package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue +29 -0
  56. package/dist/runtime/components/Edit/Features/{Publish/Dialog/ScheduleDate.vue.d.ts → Comments/CommentInput/index.vue.d.ts} +2 -2
  57. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue +22 -16
  58. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue.d.ts +1 -0
  59. package/dist/runtime/components/Edit/Features/Comments/Overlay/index.vue +15 -6
  60. package/dist/runtime/components/Edit/Features/Comments/index.vue +21 -9
  61. package/dist/runtime/components/Edit/Features/Conversions/index.vue +4 -7
  62. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +26 -35
  63. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue +240 -0
  64. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue.d.ts +6 -0
  65. package/dist/runtime/components/Edit/Features/Debug/index.vue +7 -165
  66. package/dist/runtime/components/Edit/Features/Delete/index.vue +1 -1
  67. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +14 -6
  68. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +55 -48
  69. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +30 -18
  70. package/dist/runtime/components/Edit/Features/Duplicate/index.vue +6 -8
  71. package/dist/runtime/components/Edit/Features/Edit/index.vue +16 -22
  72. package/dist/runtime/components/Edit/Features/EditForm/index.vue +7 -6
  73. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +69 -4
  74. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue.d.ts +2 -2
  75. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Plaintext/index.vue +13 -9
  76. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +45 -87
  77. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue.d.ts +2 -2
  78. package/dist/runtime/components/Edit/Features/EditableField/index.vue +41 -43
  79. package/dist/runtime/components/Edit/Features/Fragments/Dialog/index.vue +11 -9
  80. package/dist/runtime/components/Edit/Features/Fragments/index.vue +3 -3
  81. package/dist/runtime/components/Edit/Features/History/index.vue +5 -2
  82. package/dist/runtime/components/Edit/Features/Hover/Overlay/fragment.glsl +139 -0
  83. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +261 -0
  84. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue.d.ts +6 -0
  85. package/dist/runtime/components/Edit/Features/Hover/Overlay/vertex.glsl +117 -0
  86. package/dist/runtime/components/Edit/Features/Hover/index.vue +25 -0
  87. package/dist/runtime/components/Edit/Features/Hover/index.vue.d.ts +2 -0
  88. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +5 -7
  89. package/dist/runtime/components/Edit/Features/Library/LibraryDialog/index.vue +19 -27
  90. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +32 -28
  91. package/dist/runtime/components/Edit/Features/Library/index.vue +28 -23
  92. package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +6 -3
  93. package/dist/runtime/components/Edit/Features/MediaLibrary/index.vue +15 -12
  94. package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +36 -29
  95. package/dist/runtime/components/Edit/Features/MultiSelect/index.vue +2 -4
  96. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +6 -1
  97. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +8 -6
  98. package/dist/runtime/components/Edit/Features/Options/index.vue +6 -6
  99. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue +35 -0
  100. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue.d.ts +6 -0
  101. package/dist/runtime/components/Edit/Features/Ownership/index.vue +7 -25
  102. package/dist/runtime/components/Edit/Features/ProxyView/index.vue +5 -1
  103. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +68 -15
  104. package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +15 -15
  105. package/dist/runtime/components/Edit/Features/Search/index.vue +4 -1
  106. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +39 -74
  107. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +7 -5
  108. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/fragment.glsl +106 -0
  109. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +440 -0
  110. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue.d.ts +32 -0
  111. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/vertex.glsl +102 -0
  112. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +53 -125
  113. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue.d.ts +2 -2
  114. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +88 -29
  115. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +5 -3
  116. package/dist/runtime/components/Edit/Features/Selection/Overlay/vertex.glsl +11 -2
  117. package/dist/runtime/components/Edit/Features/Selection/OverlayFallback/index.vue +2 -2
  118. package/dist/runtime/components/Edit/Features/Selection/index.vue +66 -39
  119. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +2 -2
  120. package/dist/runtime/components/Edit/Features/Structure/List/Item/index.vue +13 -6
  121. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +3 -0
  122. package/dist/runtime/components/Edit/Features/Transform/index.vue +2 -27
  123. package/dist/runtime/components/Edit/Features/Translations/Banner/index.vue +17 -11
  124. package/dist/runtime/components/Edit/Features/Translations/index.vue +20 -23
  125. package/dist/runtime/components/Edit/Features/Validations/SidebarItem/index.vue +5 -5
  126. package/dist/runtime/components/Edit/Features/index.vue +17 -7
  127. package/dist/runtime/components/Edit/Form/Text/index.vue +2 -1
  128. package/dist/runtime/components/Edit/Form/Text/index.vue.d.ts +1 -0
  129. package/dist/runtime/components/Edit/Form/Toggle/index.vue +4 -3
  130. package/dist/runtime/components/Edit/Form/Toggle/index.vue.d.ts +12 -2
  131. package/dist/runtime/components/Edit/Indicators/index.vue +1 -1
  132. package/dist/runtime/components/Edit/InfoBox/index.vue +6 -2
  133. package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +12 -2
  134. package/dist/runtime/components/Edit/Konami/Game/index.vue +5 -5
  135. package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue → ScheduleDate/index.vue} +6 -58
  136. package/dist/runtime/components/Edit/ScheduleDate/index.vue.d.ts +23 -0
  137. package/dist/runtime/components/Edit/ShortcutIndicator/index.vue +3 -0
  138. package/dist/runtime/components/Edit/Transition/Height.vue +95 -0
  139. package/dist/runtime/components/Edit/Transition/Height.vue.d.ts +36 -0
  140. package/dist/runtime/components/Edit/index.d.ts +7 -3
  141. package/dist/runtime/components/Edit/index.js +12 -4
  142. package/dist/runtime/composables/defineBlokkli.js +4 -2
  143. package/dist/runtime/css/output.css +1 -1
  144. package/dist/runtime/helpers/animationProvider.d.ts +35 -1
  145. package/dist/runtime/helpers/animationProvider.js +179 -48
  146. package/dist/runtime/helpers/composables/defineRenderer.d.ts +8 -0
  147. package/dist/runtime/helpers/composables/defineRenderer.js +8 -0
  148. package/dist/runtime/helpers/composables/useStateBasedCache.d.ts +4 -0
  149. package/dist/runtime/helpers/composables/useStateBasedCache.js +13 -0
  150. package/dist/runtime/helpers/composables/useStickyToolbar.d.ts +4 -1
  151. package/dist/runtime/helpers/composables/useStickyToolbar.js +53 -35
  152. package/dist/runtime/helpers/definitionProvider.d.ts +1 -1
  153. package/dist/runtime/helpers/dom/index.d.ts +1 -0
  154. package/dist/runtime/helpers/domProvider.d.ts +54 -14
  155. package/dist/runtime/helpers/domProvider.js +168 -134
  156. package/dist/runtime/helpers/index.d.ts +1 -8
  157. package/dist/runtime/helpers/index.js +1 -84
  158. package/dist/runtime/helpers/providers/blocks.d.ts +10 -0
  159. package/dist/runtime/helpers/providers/blocks.js +91 -0
  160. package/dist/runtime/helpers/providers/directive.d.ts +24 -0
  161. package/dist/runtime/helpers/providers/directive.js +205 -0
  162. package/dist/runtime/helpers/providers/element.d.ts +6 -0
  163. package/dist/runtime/helpers/providers/element.js +35 -0
  164. package/dist/runtime/helpers/providers/fields.d.ts +8 -0
  165. package/dist/runtime/helpers/providers/fields.js +47 -0
  166. package/dist/runtime/helpers/selectionProvider.d.ts +11 -11
  167. package/dist/runtime/helpers/selectionProvider.js +38 -45
  168. package/dist/runtime/helpers/stateProvider.d.ts +7 -2
  169. package/dist/runtime/helpers/stateProvider.js +83 -14
  170. package/dist/runtime/helpers/storageProvider.d.ts +3 -2
  171. package/dist/runtime/helpers/storageProvider.js +6 -2
  172. package/dist/runtime/helpers/symbols.d.ts +1 -0
  173. package/dist/runtime/helpers/symbols.js +1 -0
  174. package/dist/runtime/helpers/themeProvider.d.ts +2 -1
  175. package/dist/runtime/helpers/themeProvider.js +24 -14
  176. package/dist/runtime/helpers/typesProvider.js +10 -26
  177. package/dist/runtime/helpers/uiProvider.d.ts +11 -3
  178. package/dist/runtime/helpers/uiProvider.js +45 -17
  179. package/dist/runtime/icons/calendar.svg +1 -0
  180. package/dist/runtime/icons/clock.svg +1 -0
  181. package/dist/runtime/icons/comment_add.svg +1 -5
  182. package/dist/runtime/icons/delete.svg +1 -8
  183. package/dist/runtime/icons/duplicate.svg +1 -12
  184. package/dist/runtime/icons/edit.svg +1 -8
  185. package/dist/runtime/icons/reusable.svg +1 -5
  186. package/dist/runtime/plugins/blokkliDirectives.js +96 -0
  187. package/dist/runtime/types/index.d.ts +66 -35
  188. package/package.json +1 -1
  189. package/dist/runtime/components/Edit/DragInteractions/index.vue +0 -401
  190. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Group/index.vue +0 -63
  191. package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue +0 -54
  192. package/dist/runtime/plugins/blokkliEditable.js +0 -31
  193. /package/dist/runtime/components/Edit/{DragInteractions → Features/BlockScheduler}/index.vue.d.ts +0 -0
  194. /package/dist/runtime/plugins/{blokkliEditable.d.ts → blokkliDirectives.d.ts} +0 -0
@@ -0,0 +1,91 @@
1
+ import { itemEntityType } from "#blokkli-build/config";
2
+ import onBlokkliEvent from "../composables/onBlokkliEvent.js";
3
+ export default function(state, dom, context) {
4
+ const renderedFieldListItemCache = /* @__PURE__ */ new Map();
5
+ function getParentBlockBundle(field) {
6
+ if (field.entityType !== itemEntityType) {
7
+ return null;
8
+ }
9
+ const block = state.getFieldListItem(field.entityUuid);
10
+ if (!block) {
11
+ return null;
12
+ }
13
+ return block.bundle;
14
+ }
15
+ function getLibraryData(item) {
16
+ if (item.bundle === "from_library" && item.props.libraryItem) {
17
+ const uuid = item.props.libraryItem.uuid;
18
+ const bundle = item.props.libraryItem.block?.bundle;
19
+ if (uuid && bundle) {
20
+ return {
21
+ label: item.props.libraryItem.label ?? "",
22
+ libraryItemUuid: uuid,
23
+ reusableBundle: bundle
24
+ };
25
+ }
26
+ }
27
+ return null;
28
+ }
29
+ function getBlock(uuid) {
30
+ const cached = renderedFieldListItemCache.get(uuid);
31
+ if (cached) {
32
+ return cached;
33
+ }
34
+ const item = state.getFieldListItem(uuid);
35
+ if (!item) {
36
+ return;
37
+ }
38
+ if (!item.editContext) {
39
+ throw new Error("Missing editContext on block with UUID: " + item.uuid);
40
+ }
41
+ const fieldList = state.getFieldListForBlock(item.uuid);
42
+ if (!fieldList) {
43
+ return;
44
+ }
45
+ const field = dom.getRegisteredField(fieldList.entityUuid, fieldList.name);
46
+ const parentBlockBundle = getParentBlockBundle(fieldList);
47
+ const renderedItem = {
48
+ uuid: item.uuid,
49
+ bundle: item.bundle,
50
+ isNew: item.editContext.isNew,
51
+ isPublished: item.editContext.isPublished,
52
+ publishOn: item.editContext.publishOn,
53
+ unpublishOn: item.editContext.unpublishOn,
54
+ isNested: fieldList.entityType === itemEntityType,
55
+ fieldListType: field?.fieldListType ?? "default",
56
+ library: getLibraryData(item),
57
+ parentBlockBundle,
58
+ host: {
59
+ type: fieldList.entityType,
60
+ uuid: fieldList.entityUuid,
61
+ fieldName: fieldList.name,
62
+ bundle: parentBlockBundle ?? context.value.entityBundle
63
+ }
64
+ };
65
+ renderedFieldListItemCache.set(item.uuid, renderedItem);
66
+ return renderedItem;
67
+ }
68
+ function getAllBlocks() {
69
+ const blocks = [];
70
+ const uuids = state.getAllUuids();
71
+ for (let i = 0; i < uuids.length; i++) {
72
+ const uuid = uuids[i];
73
+ if (!uuid) {
74
+ continue;
75
+ }
76
+ const block = getBlock(uuid);
77
+ if (!block) {
78
+ continue;
79
+ }
80
+ blocks.push(block);
81
+ }
82
+ return blocks;
83
+ }
84
+ onBlokkliEvent("state:reloaded", () => {
85
+ renderedFieldListItemCache.clear();
86
+ });
87
+ return {
88
+ getBlock,
89
+ getAllBlocks
90
+ };
91
+ }
@@ -0,0 +1,24 @@
1
+ import type { BlokkliDirectiveType, EntityContext, Rectangle } from '#blokkli/types';
2
+ import type { UiProvider } from './../uiProvider.js';
3
+ import { type ComputedRef } from '#imports';
4
+ type EditableFieldData = EntityContext & {
5
+ key: string;
6
+ fieldName: string;
7
+ directiveType: BlokkliDirectiveType;
8
+ };
9
+ type DroppableFieldElementData = EditableFieldData & {
10
+ element: HTMLElement;
11
+ };
12
+ export type DirectiveProvider = {
13
+ init: () => void;
14
+ registerDirectiveElement: (el: HTMLElement, fieldName: string, entity: EntityContext, type: BlokkliDirectiveType) => void;
15
+ unregisterDirectiveElement: (el: HTMLElement, fieldName: string, entity: EntityContext, type: BlokkliDirectiveType) => void;
16
+ getVisible: (directiveType: BlokkliDirectiveType) => Rectangle[];
17
+ getEditableAtPoint: (x: number, y: number) => EditableFieldData | undefined;
18
+ getEditablesForBlock: (uuid: string) => EditableFieldData[];
19
+ getDroppableElements: () => DroppableFieldElementData[];
20
+ findEditableElement: (fieldName: string, host: EntityContext) => HTMLElement | undefined;
21
+ isReady: ComputedRef<boolean>;
22
+ };
23
+ export default function (ui: UiProvider): DirectiveProvider;
24
+ export {};
@@ -0,0 +1,205 @@
1
+ import { falsy } from "#blokkli/helpers";
2
+ import useDelayedIntersectionObserver from "./../composables/useDelayedIntersectionObserver.js";
3
+ import { computed, onBeforeUnmount, ref } from "#imports";
4
+ import onBlokkliEvent from "./../composables/onBlokkliEvent.js";
5
+ import { itemEntityType } from "#blokkli-build/config";
6
+ export default function(ui) {
7
+ let initTimeout = null;
8
+ const isInitalizing = ref(true);
9
+ let stateReloadTimeout = null;
10
+ const elementMap = /* @__PURE__ */ new WeakMap();
11
+ const elements = /* @__PURE__ */ new Map();
12
+ const fieldData = /* @__PURE__ */ new Map();
13
+ const rects = {};
14
+ const visible = /* @__PURE__ */ new Set();
15
+ const editablesByUuid = {};
16
+ function doInitTimeout() {
17
+ if (initTimeout) {
18
+ window.clearTimeout(initTimeout);
19
+ }
20
+ if (isInitalizing.value) {
21
+ initTimeout = window.setTimeout(() => {
22
+ isInitalizing.value = false;
23
+ }, 500);
24
+ }
25
+ }
26
+ function getVisible(directiveType) {
27
+ return [...visible.keys()].map((key) => {
28
+ if (key.startsWith(directiveType)) {
29
+ return rects[key];
30
+ }
31
+ }).filter(falsy);
32
+ }
33
+ function getEditableKey(fieldName, entity, directiveType) {
34
+ return `${directiveType}:${entity.type}:${entity.uuid}:${fieldName}`;
35
+ }
36
+ function intersectionCallback(entries) {
37
+ const scale = ui.artboardScale.value;
38
+ const offset = ui.artboardOffset.value;
39
+ for (const entry of entries) {
40
+ if (entry.target instanceof HTMLElement) {
41
+ const data = elementMap.get(entry.target);
42
+ if (!data) {
43
+ continue;
44
+ }
45
+ const key = getEditableKey(data.fieldName, data, data.directiveType);
46
+ const domRect = entry.target.getBoundingClientRect();
47
+ rects[key] ||= {
48
+ width: 0,
49
+ height: 0,
50
+ x: 0,
51
+ y: 0,
52
+ key
53
+ };
54
+ const newRect = ui.getAbsoluteElementRect(domRect, scale, offset);
55
+ rects[key].width = newRect.width;
56
+ rects[key].height = newRect.height;
57
+ rects[key].x = newRect.x;
58
+ rects[key].y = newRect.y;
59
+ if (entry.isIntersecting) {
60
+ visible.add(key);
61
+ } else {
62
+ visible.delete(key);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ const intersectionObserver = useDelayedIntersectionObserver(
68
+ intersectionCallback,
69
+ {
70
+ rootMargin: "400px 0px 400px 0px"
71
+ }
72
+ );
73
+ function registerDirectiveElement(el, fieldName, entity, directiveType) {
74
+ const key = getEditableKey(fieldName, entity, directiveType);
75
+ const data = {
76
+ ...entity,
77
+ fieldName,
78
+ directiveType,
79
+ key
80
+ };
81
+ elementMap.set(el, data);
82
+ fieldData.set(key, data);
83
+ intersectionObserver.observe(el);
84
+ elements.set(key, el);
85
+ if (directiveType === "editable" && entity.type === itemEntityType) {
86
+ editablesByUuid[entity.uuid] ||= {};
87
+ editablesByUuid[entity.uuid][fieldName] = data;
88
+ }
89
+ doInitTimeout();
90
+ }
91
+ function unregisterDirectiveElement(el, fieldName, entity, directiveType) {
92
+ const key = getEditableKey(fieldName, entity, directiveType);
93
+ intersectionObserver.unobserve(el);
94
+ elementMap.delete(el);
95
+ fieldData.delete(key);
96
+ delete rects[key];
97
+ visible.delete(key);
98
+ elements.delete(key);
99
+ if (directiveType === "editable" && entity.type === itemEntityType) {
100
+ if (editablesByUuid[entity.uuid]) {
101
+ editablesByUuid[entity.uuid][fieldName] = void 0;
102
+ }
103
+ }
104
+ }
105
+ function init() {
106
+ intersectionObserver.init();
107
+ }
108
+ function getEditableAtPoint(x, y) {
109
+ const scale = ui.artboardScale.value;
110
+ const offset = ui.artboardOffset.value;
111
+ const artboardX = x / scale - offset.x / scale;
112
+ const artboardY = y / scale - offset.y / scale;
113
+ for (const key of visible) {
114
+ if (!key.startsWith("editable:")) continue;
115
+ const rect = rects[key];
116
+ if (!rect) continue;
117
+ if (artboardX >= rect.x && artboardX <= rect.x + rect.width && artboardY >= rect.y && artboardY <= rect.y + rect.height) {
118
+ return fieldData.get(key);
119
+ }
120
+ }
121
+ return void 0;
122
+ }
123
+ function updateRects() {
124
+ const scale = ui.artboardScale.value;
125
+ const offset = ui.artboardOffset.value;
126
+ const keysToUpdate = elements.size < 150 ? Array.from(elements.keys()) : Array.from(visible);
127
+ for (let i = 0; i < keysToUpdate.length; i++) {
128
+ const key = keysToUpdate[i];
129
+ const el = elements.get(key);
130
+ if (!el) continue;
131
+ const domRect = el.getBoundingClientRect();
132
+ const newRect = ui.getAbsoluteElementRect(domRect, scale, offset);
133
+ if (rects[key]) {
134
+ rects[key].width = newRect.width;
135
+ rects[key].height = newRect.height;
136
+ rects[key].x = newRect.x;
137
+ rects[key].y = newRect.y;
138
+ } else {
139
+ rects[key] = {
140
+ width: newRect.width,
141
+ height: newRect.height,
142
+ x: newRect.x,
143
+ y: newRect.y,
144
+ key
145
+ };
146
+ }
147
+ }
148
+ }
149
+ function handleRefresh() {
150
+ if (stateReloadTimeout) {
151
+ window.clearTimeout(stateReloadTimeout);
152
+ }
153
+ if (visible.size < 150) {
154
+ updateRects();
155
+ }
156
+ stateReloadTimeout = window.setTimeout(updateRects, 300);
157
+ }
158
+ function getEditablesForBlock(uuid) {
159
+ const editables = editablesByUuid[uuid];
160
+ if (!editables) {
161
+ return [];
162
+ }
163
+ return Object.values(editables).filter(falsy);
164
+ }
165
+ function getDroppableElements() {
166
+ const droppableElements = [];
167
+ for (const item of fieldData.values()) {
168
+ if (item.directiveType !== "droppable") {
169
+ continue;
170
+ }
171
+ const element = elements.get(item.key);
172
+ if (!element) {
173
+ continue;
174
+ }
175
+ droppableElements.push({
176
+ ...item,
177
+ element
178
+ });
179
+ }
180
+ return droppableElements;
181
+ }
182
+ function findEditableElement(fieldName, host) {
183
+ const key = getEditableKey(fieldName, host, "editable");
184
+ return elements.get(key);
185
+ }
186
+ onBlokkliEvent("state:reloaded", handleRefresh);
187
+ onBlokkliEvent("ui:resized", handleRefresh);
188
+ onBlokkliEvent("option:finish-change", handleRefresh);
189
+ onBeforeUnmount(() => {
190
+ if (stateReloadTimeout) {
191
+ window.clearTimeout(stateReloadTimeout);
192
+ }
193
+ });
194
+ return {
195
+ registerDirectiveElement,
196
+ unregisterDirectiveElement,
197
+ init,
198
+ getVisible,
199
+ getEditableAtPoint,
200
+ getEditablesForBlock,
201
+ findEditableElement,
202
+ getDroppableElements,
203
+ isReady: computed(() => !isInitalizing.value)
204
+ };
205
+ }
@@ -0,0 +1,6 @@
1
+ import type { DebugProvider } from '../debugProvider.js';
2
+ export type ElementProvider = {
3
+ queryAll: <T = HTMLElement>(target: HTMLElement | Document, query: string, reason: string, map?: (v: HTMLElement) => T | null | undefined) => T[];
4
+ query: <T = HTMLElement>(target: HTMLElement | Document, query: string, reason: string, map?: (v: HTMLElement) => T | null | undefined) => T | null;
5
+ };
6
+ export default function (debug: DebugProvider): ElementProvider;
@@ -0,0 +1,35 @@
1
+ export default function(debug) {
2
+ const logger = debug.createLogger("ElementProvider");
3
+ function queryAll(target, query2, reason, map) {
4
+ const results = [];
5
+ logger.log(`querySelectorAll - "${query2}" - ${reason}`);
6
+ for (const element of target.querySelectorAll(query2)) {
7
+ if (element instanceof HTMLElement) {
8
+ if (map) {
9
+ const result = map(element);
10
+ if (result) {
11
+ results.push(result);
12
+ }
13
+ } else {
14
+ results.push(element);
15
+ }
16
+ }
17
+ }
18
+ return results;
19
+ }
20
+ function query(target, query2, reason, map) {
21
+ logger.log(`querySelector - "${query2}" - ${reason}`);
22
+ const match = target.querySelector(query2);
23
+ if (!(match instanceof HTMLElement)) {
24
+ return null;
25
+ }
26
+ if (map) {
27
+ return map(match) ?? null;
28
+ }
29
+ return match;
30
+ }
31
+ return {
32
+ query,
33
+ queryAll
34
+ };
35
+ }
@@ -0,0 +1,8 @@
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';
5
+ export type FieldsProvider = {
6
+ find: (uuid: string, fieldName: string) => BlokkliFieldElement | undefined;
7
+ };
8
+ export default function (state: StateProvider, dom: DomProvider, types: BlockDefinitionProvider): FieldsProvider;
@@ -0,0 +1,47 @@
1
+ import onBlokkliEvent from "../composables/onBlokkliEvent.js";
2
+ export default function(state, dom, types) {
3
+ const fieldCache = /* @__PURE__ */ new Map();
4
+ function find(uuid, fieldName) {
5
+ const key = uuid + ":" + fieldName;
6
+ const cached = fieldCache.get(key);
7
+ if (cached) {
8
+ return cached;
9
+ }
10
+ const registeredField = dom.getRegisteredField(uuid, fieldName);
11
+ if (!registeredField) {
12
+ return;
13
+ }
14
+ const definition = types.getFieldConfig(
15
+ registeredField.entity.type,
16
+ registeredField.entity.bundle,
17
+ registeredField.fieldName
18
+ );
19
+ if (!definition) {
20
+ return;
21
+ }
22
+ const fieldElement = {
23
+ key,
24
+ name: registeredField.fieldName,
25
+ label: definition.label,
26
+ isNested: registeredField.isNested,
27
+ nestingLevel: registeredField.nestingLevel,
28
+ fieldListType: registeredField.fieldListType,
29
+ hostEntityType: registeredField.entity.type,
30
+ hostEntityBundle: registeredField.entity.bundle,
31
+ hostEntityUuid: registeredField.entity.uuid,
32
+ allowedBundles: definition.allowedBundles,
33
+ allowedFragments: registeredField.allowedFragments,
34
+ cardinality: definition.cardinality,
35
+ element: registeredField.element,
36
+ dropAlignment: registeredField.dropAlignment
37
+ };
38
+ fieldCache.set(key, fieldElement);
39
+ return fieldElement;
40
+ }
41
+ onBlokkliEvent("state:reloaded", () => {
42
+ fieldCache.clear();
43
+ });
44
+ return {
45
+ find
46
+ };
47
+ }
@@ -1,6 +1,6 @@
1
- import type { DomProvider } from './domProvider.js';
2
1
  import { type Ref, type ComputedRef } from '#imports';
3
- import type { DraggableExistingBlock, DraggableItem, InteractionMode } from '#blokkli/types';
2
+ import type { DraggableItem, InteractionMode, RenderedFieldListItem } from '#blokkli/types';
3
+ import type { BlocksProvider } from './providers/blocks.js';
4
4
  export type SelectionProvider = {
5
5
  /**
6
6
  * The currently selected UUIDs.
@@ -14,18 +14,22 @@ export type SelectionProvider = {
14
14
  * Whether anything is selected.
15
15
  */
16
16
  hasAnythingSelected: ComputedRef<boolean>;
17
+ /**
18
+ * The selected bundles.
19
+ */
20
+ bundles: ComputedRef<string[]>;
17
21
  /**
18
22
  * The currently selected UUIDs as a Set.
19
23
  */
20
24
  uuidsSet: ComputedRef<Set<string>>;
21
25
  /**
22
- * The currently selected blocks.
26
+ * The currently selected field list items.
23
27
  */
24
- blocks: ComputedRef<DraggableExistingBlock[]>;
28
+ items: ComputedRef<RenderedFieldListItem[]>;
25
29
  /**
26
- * The active field key.
30
+ * The currently selected field list item, if only a single item is selected.
27
31
  */
28
- activeFieldKey: Readonly<Ref<string>>;
32
+ item: ComputedRef<RenderedFieldListItem | null>;
29
33
  /**
30
34
  * Whether the user is currently dragging a block.
31
35
  */
@@ -46,10 +50,6 @@ export type SelectionProvider = {
46
50
  * Whether the user is currently in multi select mode.
47
51
  */
48
52
  isMultiSelecting: Ref<boolean>;
49
- /**
50
- * Update the active field key.
51
- */
52
- setActiveFieldKey: (key: string) => void;
53
53
  /**
54
54
  * Whether an editable field is currently being edited.
55
55
  */
@@ -76,4 +76,4 @@ export type SelectionProvider = {
76
76
  */
77
77
  unlockSelection: (key: string) => void;
78
78
  };
79
- export default function (dom: DomProvider): SelectionProvider;
79
+ export default function (blocks: BlocksProvider): SelectionProvider;
@@ -1,32 +1,52 @@
1
1
  import onBlokkliEvent from "./composables/onBlokkliEvent.js";
2
2
  import { computed, ref } from "#imports";
3
- import { falsy, modulo, onlyUnique } from "#blokkli/helpers";
4
- import { eventBus } from "#blokkli/helpers/eventBus";
5
- export default function(dom) {
3
+ import { falsy, onlyUnique } from "#blokkli/helpers";
4
+ export default function(blocks) {
6
5
  const selectedUuids = ref([]);
7
6
  const hasHostSelected = ref(false);
8
- const activeFieldKey = ref("");
9
7
  const draggingMode = ref(null);
10
8
  const editableActive = ref(false);
11
9
  const isChangingOptions = ref(false);
12
10
  const isMultiSelecting = ref(false);
13
11
  const interactionMode = ref("mouse");
14
12
  const selectionLocks = ref([]);
13
+ const selectedRenderedItems = computed(() => {
14
+ const items = [];
15
+ for (let i = 0; i < selectedUuids.value.length; i++) {
16
+ const uuid = selectedUuids.value[i];
17
+ if (!uuid) {
18
+ continue;
19
+ }
20
+ const item2 = blocks.getBlock(uuid);
21
+ if (!item2) {
22
+ continue;
23
+ }
24
+ items.push(item2);
25
+ }
26
+ return items;
27
+ });
28
+ const item = computed(() => {
29
+ if (selectedRenderedItems.value.length === 1) {
30
+ return selectedRenderedItems.value[0] ?? null;
31
+ }
32
+ return null;
33
+ });
34
+ const bundles = computed(() => {
35
+ return selectedRenderedItems.value.map((v) => v.bundle).filter(onlyUnique);
36
+ });
15
37
  const selectionIsLocked = computed(() => !!selectionLocks.value.length);
16
38
  const dragItems = ref([]);
17
39
  const dragItemsBundles = computed(
18
- () => dragItems.value.map((v) => v.itemBundle).filter(falsy)
19
- );
20
- const uuidsSet = computed(() => new Set(selectedUuids.value));
21
- const isDragging = computed(() => !!draggingMode.value);
22
- const blocks = computed(
23
- () => selectedUuids.value.map((uuid) => {
24
- if (dom.registeredBlockUuids.value.includes(uuid)) {
25
- return dom.findBlock(uuid);
40
+ () => dragItems.value.map((v) => {
41
+ if (v.itemType === "existing") {
42
+ return v.block.bundle;
43
+ } else if ("itemBundle" in v) {
44
+ return v.itemBundle;
26
45
  }
27
- return null;
28
46
  }).filter(falsy)
29
47
  );
48
+ const uuidsSet = computed(() => new Set(selectedUuids.value));
49
+ const isDragging = computed(() => !!draggingMode.value);
30
50
  function updateSelectedUuids(uuids, force) {
31
51
  if (selectionIsLocked.value && !force) {
32
52
  return;
@@ -34,7 +54,6 @@ export default function(dom) {
34
54
  selectedUuids.value = uuids;
35
55
  }
36
56
  function unselectItems() {
37
- activeFieldKey.value = "";
38
57
  if (selectedUuids.value.length === 0) {
39
58
  return;
40
59
  }
@@ -47,25 +66,6 @@ export default function(dom) {
47
66
  updateSelectedUuids(v.filter(onlyUnique), force);
48
67
  }
49
68
  }
50
- const selectInList = (prev) => {
51
- const items = dom.getAllBlocks();
52
- if (!items.length) {
53
- return;
54
- }
55
- const currentIndex = blocks.value[0] ? items.findIndex((v) => v.uuid === blocks.value[0].uuid) : -1;
56
- const targetIndex = modulo(
57
- prev ? currentIndex - 1 : currentIndex + 1,
58
- items.length
59
- );
60
- const targetItem = items[targetIndex];
61
- if (!targetItem) {
62
- return;
63
- }
64
- onSelect(targetItem.uuid);
65
- dom.refreshBlockRect(targetItem.uuid);
66
- eventBus.emit("scrollIntoView", { uuid: targetItem.uuid });
67
- };
68
- const setActiveFieldKey = (key) => activeFieldKey.value = key;
69
69
  onBlokkliEvent("select", onSelect);
70
70
  onBlokkliEvent("select:force", (arg) => {
71
71
  onSelect(arg, true);
@@ -74,7 +74,6 @@ export default function(dom) {
74
74
  updateSelectedUuids((e.uuids || []).filter(onlyUnique));
75
75
  isMultiSelecting.value = true;
76
76
  interactionMode.value = e.mode;
77
- activeFieldKey.value = "";
78
77
  });
79
78
  onBlokkliEvent("select:toggle", (uuid) => {
80
79
  if (selectedUuids.value.includes(uuid)) {
@@ -90,18 +89,13 @@ export default function(dom) {
90
89
  }
91
90
  updateSelectedUuids(uuids);
92
91
  });
93
- onBlokkliEvent("select:previous", () => selectInList(true));
94
- onBlokkliEvent("select:next", selectInList);
95
- onBlokkliEvent("setActiveFieldKey", setActiveFieldKey);
96
92
  onBlokkliEvent("dragging:start", (e) => {
97
93
  draggingMode.value = e.mode;
98
94
  isMultiSelecting.value = false;
99
95
  dragItems.value = e.items;
100
- const blocks2 = e.items.filter(
101
- (v) => v.itemType === "existing"
102
- );
96
+ const blocks2 = e.items.filter((v) => v.itemType === "existing");
103
97
  if (blocks2.length) {
104
- updateSelectedUuids(blocks2.map((v) => v.uuid));
98
+ updateSelectedUuids(blocks2.map((v) => v.block.uuid));
105
99
  }
106
100
  });
107
101
  onBlokkliEvent("dragging:end", () => {
@@ -118,7 +112,6 @@ export default function(dom) {
118
112
  });
119
113
  onBlokkliEvent("window:clickAway", () => {
120
114
  unselectItems();
121
- activeFieldKey.value = "";
122
115
  if (document.activeElement instanceof HTMLElement) {
123
116
  document.activeElement.blur();
124
117
  }
@@ -142,11 +135,11 @@ export default function(dom) {
142
135
  }
143
136
  return {
144
137
  uuids: selectedUuids,
145
- blocks,
146
- activeFieldKey,
138
+ bundles,
139
+ items: selectedRenderedItems,
140
+ item,
147
141
  isDragging,
148
142
  isDraggingExisting,
149
- setActiveFieldKey,
150
143
  editableActive,
151
144
  isChangingOptions,
152
145
  isMultiSelecting,
@@ -1,6 +1,6 @@
1
1
  import { type Ref, type ComputedRef } from 'vue';
2
2
  import type { BlokkliAdapter, AdapterContext } from '../adapter/index.js';
3
- import type { MutatedField, EditEntity, MutatedOptions, TranslationState, MappedState, MutationItem, Validation, MutateWithLoadingStateFunction, EditMode, FieldListItem, PublishOptions } from '#blokkli/types';
3
+ import type { MutatedField, EditEntity, MutatedOptions, TranslationState, MappedState, MutationItem, Validation, MutateWithLoadingStateFunction, EditMode, FieldListItem, PublishOptions, EditPermission } from '#blokkli/types';
4
4
  import type { TextProvider } from './textProvider.js';
5
5
  export type BlokkliOwner = {
6
6
  name: string | undefined;
@@ -27,16 +27,21 @@ export type StateProvider = {
27
27
  editMode: Readonly<Ref<EditMode>>;
28
28
  mutatedEntity: Readonly<Ref<any>>;
29
29
  canEdit: ComputedRef<boolean>;
30
+ permissions: ComputedRef<EditPermission[]>;
30
31
  stateAvailable: ComputedRef<boolean>;
31
32
  isLoading: Readonly<Ref<boolean>>;
33
+ fromLibraryUuids: Readonly<Ref<Readonly<string[]>>>;
32
34
  getFieldBlockCount: (key: string) => number;
33
35
  getBlockBundleCount: (bundle: string) => number;
34
36
  getFieldListItem: (uuid: string) => FieldListItem | undefined;
35
37
  getFieldListForBlock: (uuid: string) => MutatedField | undefined;
36
38
  getMutatedField: (uuid: string, fieldName: string) => MutatedField | undefined;
37
39
  getAllUuids: (bundle?: string) => string[];
40
+ getNestingLevel: (uuid: string) => number;
41
+ isChildOf: (childUuid: string, parentUuid: string) => boolean;
38
42
  getMappedState: () => MappedState;
39
43
  setOverrideState: (state: MappedState) => void;
40
44
  clearOverrideState: () => void;
45
+ getFieldKeyForUuid: (uuid: string) => string | null;
41
46
  };
42
- export default function (adapter: BlokkliAdapter<any>, context: ComputedRef<AdapterContext>, $t: TextProvider, providerKey: string): Promise<StateProvider>;
47
+ export default function (adapter: BlokkliAdapter<any>, context: ComputedRef<AdapterContext>, $t: TextProvider, providerKey: string, permissions: EditPermission[]): Promise<StateProvider>;