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

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 (138) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +380 -59
  3. package/dist/modules/drupal/graphql/base/fragment.paragraphsFieldItem.graphql +3 -1
  4. package/dist/modules/drupal/graphql/base/query.pbConfig.graphql +1 -10
  5. package/dist/modules/drupal/graphql/mutations/set_paragraph_schedule.graphql +15 -0
  6. package/dist/modules/drupal/index.mjs +33 -0
  7. package/dist/modules/drupal/runtime/adapter/index.js +10 -2
  8. package/dist/runtime/adapter/index.d.ts +21 -0
  9. package/dist/runtime/blokkliPlugins/ContextMenu/Menu/index.vue +3 -0
  10. package/dist/runtime/blokkliPlugins/ItemAction/index.vue +23 -13
  11. package/dist/runtime/blokkliPlugins/ItemAction/index.vue.d.ts +20 -44
  12. package/dist/runtime/blokkliPlugins/TourItem/index.vue +10 -5
  13. package/dist/runtime/components/BlokkliEditable.vue +13 -13
  14. package/dist/runtime/components/BlokkliField.vue.d.ts +3 -3
  15. package/dist/runtime/components/BlokkliItem.vue +1 -1
  16. package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
  17. package/dist/runtime/components/BlokkliProvider.vue +12 -8
  18. package/dist/runtime/components/Edit/Actions/index.vue +27 -16
  19. package/dist/runtime/components/Edit/AnimationCanvas/index.vue +26 -10
  20. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +3 -0
  21. package/dist/runtime/components/Edit/Dialog/index.vue +6 -4
  22. package/dist/runtime/components/Edit/DraggableList.vue +15 -7
  23. package/dist/runtime/components/Edit/DraggableList.vue.d.ts +5 -5
  24. package/dist/runtime/components/Edit/EditProvider.vue +29 -16
  25. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +1 -0
  26. package/dist/runtime/components/Edit/Features/AddList/index.vue +9 -11
  27. package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +9 -6
  28. package/dist/runtime/components/Edit/Features/Analyze/Renderer.vue +1 -1
  29. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +15 -11
  30. package/dist/runtime/components/Edit/Features/Anchors/Renderer.vue +19 -102
  31. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +3 -0
  32. package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +28 -52
  33. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue +154 -0
  34. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue.d.ts +27 -0
  35. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +222 -0
  36. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue.d.ts +11 -0
  37. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +96 -0
  38. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue.d.ts +2 -0
  39. package/dist/runtime/components/Edit/Features/Clipboard/index.vue +15 -16
  40. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +51 -0
  41. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/{Group → Item}/index.vue.d.ts +9 -13
  42. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +46 -66
  43. package/dist/runtime/components/Edit/Features/Comments/index.vue +1 -1
  44. package/dist/runtime/components/Edit/Features/Conversions/index.vue +4 -7
  45. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +2 -2
  46. package/dist/runtime/components/Edit/Features/Debug/index.vue +4 -1
  47. package/dist/runtime/components/Edit/Features/Delete/index.vue +1 -1
  48. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +13 -5
  49. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +14 -11
  50. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +30 -18
  51. package/dist/runtime/components/Edit/Features/Duplicate/index.vue +6 -8
  52. package/dist/runtime/components/Edit/Features/Edit/index.vue +15 -21
  53. package/dist/runtime/components/Edit/Features/EditForm/index.vue +7 -6
  54. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +8 -3
  55. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue.d.ts +2 -2
  56. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +29 -12
  57. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue.d.ts +2 -2
  58. package/dist/runtime/components/Edit/Features/EditableField/index.vue +40 -42
  59. package/dist/runtime/components/Edit/Features/Fragments/Dialog/index.vue +11 -9
  60. package/dist/runtime/components/Edit/Features/Fragments/index.vue +3 -3
  61. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +16 -25
  62. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +5 -7
  63. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +5 -5
  64. package/dist/runtime/components/Edit/Features/Library/index.vue +27 -23
  65. package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +6 -3
  66. package/dist/runtime/components/Edit/Features/MediaLibrary/index.vue +15 -12
  67. package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +2 -2
  68. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +7 -6
  69. package/dist/runtime/components/Edit/Features/Options/index.vue +6 -6
  70. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +68 -15
  71. package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +15 -15
  72. package/dist/runtime/components/Edit/Features/Search/index.vue +4 -1
  73. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +3 -3
  74. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +34 -11
  75. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +21 -20
  76. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue.d.ts +2 -2
  77. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +3 -3
  78. package/dist/runtime/components/Edit/Features/Selection/OverlayFallback/index.vue +2 -2
  79. package/dist/runtime/components/Edit/Features/Selection/index.vue +61 -27
  80. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +2 -2
  81. package/dist/runtime/components/Edit/Features/Structure/List/Item/index.vue +13 -6
  82. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +3 -0
  83. package/dist/runtime/components/Edit/Features/Transform/index.vue +2 -27
  84. package/dist/runtime/components/Edit/Features/Translations/index.vue +7 -7
  85. package/dist/runtime/components/Edit/Features/Validations/SidebarItem/index.vue +5 -5
  86. package/dist/runtime/components/Edit/Features/index.vue +17 -7
  87. package/dist/runtime/components/Edit/Form/Toggle/index.vue +4 -3
  88. package/dist/runtime/components/Edit/Form/Toggle/index.vue.d.ts +12 -2
  89. package/dist/runtime/components/Edit/InfoBox/index.vue +6 -2
  90. package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +12 -2
  91. package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue → ScheduleDate/index.vue} +6 -58
  92. package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue.d.ts → ScheduleDate/index.vue.d.ts} +11 -1
  93. package/dist/runtime/components/Edit/ShortcutIndicator/index.vue +3 -0
  94. package/dist/runtime/components/Edit/Transition/Height.vue +95 -0
  95. package/dist/runtime/components/Edit/Transition/Height.vue.d.ts +36 -0
  96. package/dist/runtime/components/Edit/index.d.ts +3 -1
  97. package/dist/runtime/components/Edit/index.js +5 -1
  98. package/dist/runtime/css/output.css +1 -1
  99. package/dist/runtime/helpers/animationProvider.d.ts +2 -1
  100. package/dist/runtime/helpers/animationProvider.js +6 -2
  101. package/dist/runtime/helpers/composables/useStateBasedCache.d.ts +4 -0
  102. package/dist/runtime/helpers/composables/useStateBasedCache.js +13 -0
  103. package/dist/runtime/helpers/definitionProvider.d.ts +1 -1
  104. package/dist/runtime/helpers/dom/index.d.ts +1 -1
  105. package/dist/runtime/helpers/domProvider.d.ts +10 -16
  106. package/dist/runtime/helpers/domProvider.js +80 -135
  107. package/dist/runtime/helpers/index.d.ts +1 -8
  108. package/dist/runtime/helpers/index.js +1 -84
  109. package/dist/runtime/helpers/providers/blocks.d.ts +10 -0
  110. package/dist/runtime/helpers/providers/blocks.js +91 -0
  111. package/dist/runtime/helpers/providers/directive.d.ts +24 -0
  112. package/dist/runtime/helpers/{editableProvider.js → providers/directive.js} +90 -29
  113. package/dist/runtime/helpers/providers/element.d.ts +6 -0
  114. package/dist/runtime/helpers/providers/element.js +35 -0
  115. package/dist/runtime/helpers/providers/fields.d.ts +8 -0
  116. package/dist/runtime/helpers/providers/fields.js +47 -0
  117. package/dist/runtime/helpers/selectionProvider.d.ts +11 -11
  118. package/dist/runtime/helpers/selectionProvider.js +38 -45
  119. package/dist/runtime/helpers/stateProvider.d.ts +1 -0
  120. package/dist/runtime/helpers/stateProvider.js +21 -15
  121. package/dist/runtime/helpers/themeProvider.d.ts +2 -1
  122. package/dist/runtime/helpers/themeProvider.js +24 -14
  123. package/dist/runtime/helpers/typesProvider.js +10 -26
  124. package/dist/runtime/helpers/uiProvider.d.ts +3 -2
  125. package/dist/runtime/helpers/uiProvider.js +11 -15
  126. package/dist/runtime/icons/calendar.svg +1 -0
  127. package/dist/runtime/icons/clock.svg +1 -0
  128. package/dist/runtime/icons/comment_add.svg +1 -5
  129. package/dist/runtime/icons/delete.svg +1 -8
  130. package/dist/runtime/icons/duplicate.svg +1 -12
  131. package/dist/runtime/icons/edit.svg +1 -8
  132. package/dist/runtime/icons/reusable.svg +1 -5
  133. package/dist/runtime/plugins/{blokkliEditable.js → blokkliDirectives.js} +14 -20
  134. package/dist/runtime/types/index.d.ts +55 -36
  135. package/package.json +1 -1
  136. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Group/index.vue +0 -63
  137. package/dist/runtime/helpers/editableProvider.d.ts +0 -14
  138. /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 {};
@@ -1,32 +1,48 @@
1
1
  import { falsy } from "#blokkli/helpers";
2
- import useDelayedIntersectionObserver from "./composables/useDelayedIntersectionObserver.js";
3
- import { onBeforeUnmount } from "#imports";
4
- import onBlokkliEvent from "./composables/onBlokkliEvent.js";
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";
5
6
  export default function(ui) {
7
+ let initTimeout = null;
8
+ const isInitalizing = ref(true);
6
9
  let stateReloadTimeout = null;
7
- const editableFieldElementMap = /* @__PURE__ */ new WeakMap();
8
- const editableFieldElements = /* @__PURE__ */ new Map();
9
- const editableFieldData = /* @__PURE__ */ new Map();
10
+ const elementMap = /* @__PURE__ */ new WeakMap();
11
+ const elements = /* @__PURE__ */ new Map();
12
+ const fieldData = /* @__PURE__ */ new Map();
10
13
  const rects = {};
11
14
  const visible = /* @__PURE__ */ new Set();
12
- function getVisible() {
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) {
13
27
  return [...visible.keys()].map((key) => {
14
- return rects[key];
28
+ if (key.startsWith(directiveType)) {
29
+ return rects[key];
30
+ }
15
31
  }).filter(falsy);
16
32
  }
17
- function getEditableKey(fieldName, entity) {
18
- return `${entity.type}:${entity.uuid}:${fieldName}`;
33
+ function getEditableKey(fieldName, entity, directiveType) {
34
+ return `${directiveType}:${entity.type}:${entity.uuid}:${fieldName}`;
19
35
  }
20
36
  function intersectionCallback(entries) {
21
37
  const scale = ui.artboardScale.value;
22
38
  const offset = ui.artboardOffset.value;
23
39
  for (const entry of entries) {
24
40
  if (entry.target instanceof HTMLElement) {
25
- const data = editableFieldElementMap.get(entry.target);
41
+ const data = elementMap.get(entry.target);
26
42
  if (!data) {
27
43
  continue;
28
44
  }
29
- const key = getEditableKey(data.fieldName, data);
45
+ const key = getEditableKey(data.fieldName, data, data.directiveType);
30
46
  const domRect = entry.target.getBoundingClientRect();
31
47
  rects[key] ||= {
32
48
  width: 0,
@@ -54,25 +70,37 @@ export default function(ui) {
54
70
  rootMargin: "400px 0px 400px 0px"
55
71
  }
56
72
  );
57
- function registerEditableField(el, fieldName, entity) {
58
- const key = getEditableKey(fieldName, entity);
73
+ function registerDirectiveElement(el, fieldName, entity, directiveType) {
74
+ const key = getEditableKey(fieldName, entity, directiveType);
59
75
  const data = {
60
76
  ...entity,
61
- fieldName
77
+ fieldName,
78
+ directiveType,
79
+ key
62
80
  };
63
- editableFieldElementMap.set(el, data);
64
- editableFieldData.set(key, data);
81
+ elementMap.set(el, data);
82
+ fieldData.set(key, data);
65
83
  intersectionObserver.observe(el);
66
- editableFieldElements.set(key, 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();
67
90
  }
68
- function unregisterEditableField(el, fieldName, entity) {
69
- const key = getEditableKey(fieldName, entity);
91
+ function unregisterDirectiveElement(el, fieldName, entity, directiveType) {
92
+ const key = getEditableKey(fieldName, entity, directiveType);
70
93
  intersectionObserver.unobserve(el);
71
- editableFieldElementMap.delete(el);
72
- editableFieldData.delete(key);
94
+ elementMap.delete(el);
95
+ fieldData.delete(key);
73
96
  delete rects[key];
74
97
  visible.delete(key);
75
- editableFieldElements.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
+ }
76
104
  }
77
105
  function init() {
78
106
  intersectionObserver.init();
@@ -83,10 +111,11 @@ export default function(ui) {
83
111
  const artboardX = x / scale - offset.x / scale;
84
112
  const artboardY = y / scale - offset.y / scale;
85
113
  for (const key of visible) {
114
+ if (!key.startsWith("editable:")) continue;
86
115
  const rect = rects[key];
87
116
  if (!rect) continue;
88
117
  if (artboardX >= rect.x && artboardX <= rect.x + rect.width && artboardY >= rect.y && artboardY <= rect.y + rect.height) {
89
- return editableFieldData.get(key);
118
+ return fieldData.get(key);
90
119
  }
91
120
  }
92
121
  return void 0;
@@ -94,10 +123,10 @@ export default function(ui) {
94
123
  function updateRects() {
95
124
  const scale = ui.artboardScale.value;
96
125
  const offset = ui.artboardOffset.value;
97
- const keysToUpdate = editableFieldElements.size < 150 ? Array.from(editableFieldElements.keys()) : Array.from(visible);
126
+ const keysToUpdate = elements.size < 150 ? Array.from(elements.keys()) : Array.from(visible);
98
127
  for (let i = 0; i < keysToUpdate.length; i++) {
99
128
  const key = keysToUpdate[i];
100
- const el = editableFieldElements.get(key);
129
+ const el = elements.get(key);
101
130
  if (!el) continue;
102
131
  const domRect = el.getBoundingClientRect();
103
132
  const newRect = ui.getAbsoluteElementRect(domRect, scale, offset);
@@ -126,6 +155,34 @@ export default function(ui) {
126
155
  }
127
156
  stateReloadTimeout = window.setTimeout(updateRects, 300);
128
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
+ }
129
186
  onBlokkliEvent("state:reloaded", handleRefresh);
130
187
  onBlokkliEvent("ui:resized", handleRefresh);
131
188
  onBlokkliEvent("option:finish-change", handleRefresh);
@@ -135,10 +192,14 @@ export default function(ui) {
135
192
  }
136
193
  });
137
194
  return {
138
- registerEditableField,
139
- unregisterEditableField,
195
+ registerDirectiveElement,
196
+ unregisterDirectiveElement,
140
197
  init,
141
198
  getVisible,
142
- getEditableAtPoint
199
+ getEditableAtPoint,
200
+ getEditablesForBlock,
201
+ findEditableElement,
202
+ getDroppableElements,
203
+ isReady: computed(() => !isInitalizing.value)
143
204
  };
144
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,
@@ -42,5 +42,6 @@ export type StateProvider = {
42
42
  getMappedState: () => MappedState;
43
43
  setOverrideState: (state: MappedState) => void;
44
44
  clearOverrideState: () => void;
45
+ getFieldKeyForUuid: (uuid: string) => string | null;
45
46
  };
46
47
  export default function (adapter: BlokkliAdapter<any>, context: ComputedRef<AdapterContext>, $t: TextProvider, providerKey: string, permissions: EditPermission[]): Promise<StateProvider>;