@blokkli/editor 2.0.0-alpha.17 → 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 (139) 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 +3 -0
  15. package/dist/runtime/components/BlokkliField.vue.d.ts +3 -3
  16. package/dist/runtime/components/BlokkliItem.vue +1 -1
  17. package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
  18. package/dist/runtime/components/BlokkliProvider.vue +12 -8
  19. package/dist/runtime/components/Edit/Actions/index.vue +27 -16
  20. package/dist/runtime/components/Edit/AnimationCanvas/index.vue +26 -10
  21. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +3 -0
  22. package/dist/runtime/components/Edit/Dialog/index.vue +6 -4
  23. package/dist/runtime/components/Edit/DraggableList.vue +15 -7
  24. package/dist/runtime/components/Edit/DraggableList.vue.d.ts +5 -5
  25. package/dist/runtime/components/Edit/EditProvider.vue +29 -16
  26. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +1 -0
  27. package/dist/runtime/components/Edit/Features/AddList/index.vue +9 -11
  28. package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +9 -6
  29. package/dist/runtime/components/Edit/Features/Analyze/Renderer.vue +1 -1
  30. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +15 -11
  31. package/dist/runtime/components/Edit/Features/Anchors/Renderer.vue +19 -102
  32. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +3 -0
  33. package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +28 -52
  34. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue +154 -0
  35. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue.d.ts +27 -0
  36. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +222 -0
  37. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue.d.ts +11 -0
  38. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +96 -0
  39. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue.d.ts +2 -0
  40. package/dist/runtime/components/Edit/Features/Clipboard/index.vue +15 -16
  41. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +51 -0
  42. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/{Group → Item}/index.vue.d.ts +9 -13
  43. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +46 -66
  44. package/dist/runtime/components/Edit/Features/Comments/index.vue +1 -1
  45. package/dist/runtime/components/Edit/Features/Conversions/index.vue +4 -7
  46. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +2 -2
  47. package/dist/runtime/components/Edit/Features/Debug/index.vue +4 -1
  48. package/dist/runtime/components/Edit/Features/Delete/index.vue +1 -1
  49. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +13 -5
  50. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +14 -11
  51. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +30 -18
  52. package/dist/runtime/components/Edit/Features/Duplicate/index.vue +6 -8
  53. package/dist/runtime/components/Edit/Features/Edit/index.vue +15 -21
  54. package/dist/runtime/components/Edit/Features/EditForm/index.vue +7 -6
  55. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +8 -3
  56. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue.d.ts +2 -2
  57. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +29 -12
  58. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue.d.ts +2 -2
  59. package/dist/runtime/components/Edit/Features/EditableField/index.vue +40 -42
  60. package/dist/runtime/components/Edit/Features/Fragments/Dialog/index.vue +11 -9
  61. package/dist/runtime/components/Edit/Features/Fragments/index.vue +3 -3
  62. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +16 -25
  63. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +5 -7
  64. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +5 -5
  65. package/dist/runtime/components/Edit/Features/Library/index.vue +27 -23
  66. package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +6 -3
  67. package/dist/runtime/components/Edit/Features/MediaLibrary/index.vue +15 -12
  68. package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +2 -2
  69. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +7 -6
  70. package/dist/runtime/components/Edit/Features/Options/index.vue +6 -6
  71. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +68 -15
  72. package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +15 -15
  73. package/dist/runtime/components/Edit/Features/Search/index.vue +4 -1
  74. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +3 -3
  75. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +34 -11
  76. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +21 -20
  77. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue.d.ts +2 -2
  78. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +3 -3
  79. package/dist/runtime/components/Edit/Features/Selection/OverlayFallback/index.vue +2 -2
  80. package/dist/runtime/components/Edit/Features/Selection/index.vue +61 -27
  81. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +2 -2
  82. package/dist/runtime/components/Edit/Features/Structure/List/Item/index.vue +13 -6
  83. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +3 -0
  84. package/dist/runtime/components/Edit/Features/Transform/index.vue +2 -27
  85. package/dist/runtime/components/Edit/Features/Translations/index.vue +7 -7
  86. package/dist/runtime/components/Edit/Features/Validations/SidebarItem/index.vue +5 -5
  87. package/dist/runtime/components/Edit/Features/index.vue +17 -7
  88. package/dist/runtime/components/Edit/Form/Toggle/index.vue +4 -3
  89. package/dist/runtime/components/Edit/Form/Toggle/index.vue.d.ts +12 -2
  90. package/dist/runtime/components/Edit/InfoBox/index.vue +6 -2
  91. package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +12 -2
  92. package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue → ScheduleDate/index.vue} +6 -58
  93. package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue.d.ts → ScheduleDate/index.vue.d.ts} +11 -1
  94. package/dist/runtime/components/Edit/ShortcutIndicator/index.vue +3 -0
  95. package/dist/runtime/components/Edit/Transition/Height.vue +95 -0
  96. package/dist/runtime/components/Edit/Transition/Height.vue.d.ts +36 -0
  97. package/dist/runtime/components/Edit/index.d.ts +3 -1
  98. package/dist/runtime/components/Edit/index.js +5 -1
  99. package/dist/runtime/css/output.css +1 -1
  100. package/dist/runtime/helpers/animationProvider.d.ts +2 -1
  101. package/dist/runtime/helpers/animationProvider.js +6 -2
  102. package/dist/runtime/helpers/composables/useStateBasedCache.d.ts +4 -0
  103. package/dist/runtime/helpers/composables/useStateBasedCache.js +13 -0
  104. package/dist/runtime/helpers/definitionProvider.d.ts +1 -1
  105. package/dist/runtime/helpers/dom/index.d.ts +1 -1
  106. package/dist/runtime/helpers/domProvider.d.ts +10 -16
  107. package/dist/runtime/helpers/domProvider.js +80 -135
  108. package/dist/runtime/helpers/index.d.ts +1 -8
  109. package/dist/runtime/helpers/index.js +1 -84
  110. package/dist/runtime/helpers/providers/blocks.d.ts +10 -0
  111. package/dist/runtime/helpers/providers/blocks.js +91 -0
  112. package/dist/runtime/helpers/providers/directive.d.ts +24 -0
  113. package/dist/runtime/helpers/{editableProvider.js → providers/directive.js} +90 -29
  114. package/dist/runtime/helpers/providers/element.d.ts +6 -0
  115. package/dist/runtime/helpers/providers/element.js +35 -0
  116. package/dist/runtime/helpers/providers/fields.d.ts +8 -0
  117. package/dist/runtime/helpers/providers/fields.js +47 -0
  118. package/dist/runtime/helpers/selectionProvider.d.ts +11 -11
  119. package/dist/runtime/helpers/selectionProvider.js +38 -45
  120. package/dist/runtime/helpers/stateProvider.d.ts +1 -0
  121. package/dist/runtime/helpers/stateProvider.js +21 -15
  122. package/dist/runtime/helpers/themeProvider.d.ts +2 -1
  123. package/dist/runtime/helpers/themeProvider.js +24 -14
  124. package/dist/runtime/helpers/typesProvider.js +10 -26
  125. package/dist/runtime/helpers/uiProvider.d.ts +3 -2
  126. package/dist/runtime/helpers/uiProvider.js +11 -15
  127. package/dist/runtime/icons/calendar.svg +1 -0
  128. package/dist/runtime/icons/clock.svg +1 -0
  129. package/dist/runtime/icons/comment_add.svg +1 -5
  130. package/dist/runtime/icons/delete.svg +1 -8
  131. package/dist/runtime/icons/duplicate.svg +1 -12
  132. package/dist/runtime/icons/edit.svg +1 -8
  133. package/dist/runtime/icons/reusable.svg +1 -5
  134. package/dist/runtime/plugins/{blokkliEditable.js → blokkliDirectives.js} +14 -20
  135. package/dist/runtime/types/index.d.ts +55 -36
  136. package/package.json +1 -1
  137. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Group/index.vue +0 -63
  138. package/dist/runtime/helpers/editableProvider.d.ts +0 -14
  139. /package/dist/runtime/plugins/{blokkliEditable.d.ts → blokkliDirectives.d.ts} +0 -0
@@ -67,7 +67,7 @@
67
67
  id="clipboard"
68
68
  :title="$t('clipboard', 'Clipboard')"
69
69
  :enabled="
70
- !!selection.blocks.value.length && state.editMode.value === 'editing'
70
+ !!selection.items.value.length && state.editMode.value === 'editing'
71
71
  "
72
72
  :items="itemDropdownItems"
73
73
  icon="clipboard"
@@ -92,6 +92,7 @@ import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
92
92
  import defineShortcut from "#blokkli/helpers/composables/defineShortcut";
93
93
  import getVideoId from "get-video-id";
94
94
  import { emitMessage } from "#blokkli/helpers/eventBus";
95
+ import { itemEntityType } from "#blokkli-build/config";
95
96
  const { settings, logger } = defineBlokkliFeature({
96
97
  id: "clipboard",
97
98
  label: "Clipboard",
@@ -108,7 +109,7 @@ const { settings, logger } = defineBlokkliFeature({
108
109
  },
109
110
  screenshot: "feature-clipboard.jpg"
110
111
  });
111
- const { selection, $t, adapter, dom, state, ui, types, keyboard } = useBlokkli();
112
+ const { selection, $t, adapter, state, ui, types, keyboard, blocks } = useBlokkli();
112
113
  const plugin = ref(null);
113
114
  const selectionClipboard = ref([]);
114
115
  const itemDropdownItems = computed(() => {
@@ -290,7 +291,7 @@ const handleSelectionPaste = (pastedUuids) => {
290
291
  if (!pastedUuids.length) {
291
292
  return;
292
293
  }
293
- const block = selection.blocks.value[0];
294
+ const block = selection.items.value[0];
294
295
  if (!block) {
295
296
  return;
296
297
  }
@@ -299,11 +300,11 @@ const handleSelectionPaste = (pastedUuids) => {
299
300
  let targetFieldKey = null;
300
301
  let preceedingUuid = void 0;
301
302
  if (!keyboard.isPressingShift.value) {
302
- const pastedBundles = pastedUuids.map((uuid) => dom.findBlock(uuid)?.itemBundle).filter((bundle) => !!bundle);
303
+ const pastedBundles = pastedUuids.map((uuid) => blocks.getBlock(uuid)?.bundle).filter((bundle) => !!bundle);
303
304
  if (pastedBundles.length) {
304
305
  const nestedFields = types.fieldConfig.forEntityTypeAndBundle(
305
- block.entityType,
306
- block.itemBundle
306
+ itemEntityType,
307
+ block.bundle
307
308
  );
308
309
  for (const fieldConfig of nestedFields) {
309
310
  const allowedPastedBundles = pastedBundles.filter(
@@ -314,7 +315,7 @@ const handleSelectionPaste = (pastedUuids) => {
314
315
  const currentCount = state.getFieldBlockCount(nestedFieldKey);
315
316
  if (fieldConfig.cardinality === -1 || currentCount + allowedPastedBundles.length <= fieldConfig.cardinality) {
316
317
  targetField = {
317
- entityType: block.entityType,
318
+ entityType: itemEntityType,
318
319
  entityUuid: block.uuid,
319
320
  name: fieldConfig.name
320
321
  };
@@ -328,13 +329,13 @@ const handleSelectionPaste = (pastedUuids) => {
328
329
  }
329
330
  }
330
331
  if (!targetField || !targetFieldConfig || !targetFieldKey) {
331
- const field = state.getMutatedField(block.hostUuid, block.hostFieldName);
332
+ const field = state.getMutatedField(block.host.uuid, block.host.fieldName);
332
333
  if (!field) {
333
334
  return;
334
335
  }
335
336
  const fieldConfig = types.getFieldConfig(
336
337
  field.entityType,
337
- block.hostBundle,
338
+ block.host.bundle,
338
339
  field.name
339
340
  );
340
341
  if (!fieldConfig) {
@@ -356,15 +357,13 @@ const handleSelectionPaste = (pastedUuids) => {
356
357
  if (!uuid) {
357
358
  continue;
358
359
  }
359
- const block2 = dom.findBlock(uuid);
360
+ const block2 = blocks.getBlock(uuid);
360
361
  if (!block2) {
361
362
  continue;
362
363
  }
363
- const isAllowed = targetFieldConfig.allowedBundles.includes(
364
- block2.itemBundle
365
- );
364
+ const isAllowed = targetFieldConfig.allowedBundles.includes(block2.bundle);
366
365
  if (!isAllowed) {
367
- notAllowedBundles.push(block2.itemBundle);
366
+ notAllowedBundles.push(block2.bundle);
368
367
  continue;
369
368
  }
370
369
  pastedBlocks.push(block2);
@@ -500,7 +499,7 @@ function setClipboard(text) {
500
499
  }
501
500
  }
502
501
  function copyCurrentSelectionToClipboard() {
503
- if (!selection.blocks.value.length) {
502
+ if (!selection.items.value.length) {
504
503
  selectionClipboard.value = [];
505
504
  return;
506
505
  }
@@ -510,7 +509,7 @@ function copyCurrentSelectionToClipboard() {
510
509
  selectionClipboard.value = selection.uuids.value;
511
510
  }
512
511
  onBlokkliEvent("keyPressed", (e) => {
513
- if (e.code !== "c" || !e.meta) {
512
+ if (e.code !== "c" || !e.meta || ui.hasDialogOpen.value) {
514
513
  return;
515
514
  }
516
515
  copyCurrentSelectionToClipboard();
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <button
3
+ ref="buttonEl"
4
+ :data-command-id="item.id"
5
+ :data-command-visible="true"
6
+ class="bk-command"
7
+ :class="{ 'bk-is-focused': isFocused }"
8
+ @mouseenter="$emit('focus', index)"
9
+ @click.prevent="$emit('select', item.id)"
10
+ >
11
+ <div class="bk-command-icon">
12
+ <Icon v-if="item.icon" :name="item.icon" />
13
+ <ItemIcon v-else :bundle="item.bundle" />
14
+ </div>
15
+ <Highlight :text="item.label" tag="span" :positions="item.positions" />
16
+ <div class="bk-command-group">{{ getGroupLabel(item.group) }}</div>
17
+ </button>
18
+ </template>
19
+
20
+ <script setup>
21
+ import { watch, useBlokkli, useTemplateRef } from "#imports";
22
+ import { Icon, ItemIcon, Highlight } from "#blokkli/components";
23
+ const props = defineProps({
24
+ item: { type: Object, required: true },
25
+ index: { type: Number, required: true },
26
+ isFocused: { type: Boolean, required: true }
27
+ });
28
+ defineEmits(["focus", "select"]);
29
+ const { $t } = useBlokkli();
30
+ const buttonEl = useTemplateRef("buttonEl");
31
+ watch(
32
+ () => props.isFocused,
33
+ (focused) => {
34
+ if (focused && buttonEl.value) {
35
+ buttonEl.value.scrollIntoView({ block: "nearest", inline: "nearest" });
36
+ }
37
+ }
38
+ );
39
+ const getGroupLabel = (id) => {
40
+ if (id === "ui") {
41
+ return $t("commandGroup.ui", "Interface");
42
+ } else if (id === "add") {
43
+ return $t("commandGroup.add", "Add new");
44
+ } else if (id === "action") {
45
+ return $t("commandGroup.action", "Actions");
46
+ } else if (id === "selection") {
47
+ return $t("commandGroup.selection", "Selection");
48
+ }
49
+ return $t("commandGroup.misc", "Miscellaneous");
50
+ };
51
+ </script>
@@ -1,21 +1,17 @@
1
1
  import type { Command } from '#blokkli/types';
2
2
  type __VLS_Props = {
3
- commands: Array<Command & {
3
+ item: Command & {
4
4
  _id: number;
5
- }>;
6
- visibleIds: {
7
- id: number;
8
- positions: number[];
9
- }[] | undefined;
10
- focusedId: string;
5
+ positions?: number[];
6
+ };
7
+ index: number;
8
+ isFocused: boolean;
11
9
  };
12
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
- close: () => void;
14
- focus: (id: string) => void;
15
- select: (id: string) => void;
10
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
11
+ select: (id: string) => any;
12
+ focus: (index: number) => any;
16
13
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
17
- onClose?: (() => any) | undefined;
18
- onFocus?: ((id: string) => any) | undefined;
19
14
  onSelect?: ((id: string) => any) | undefined;
15
+ onFocus?: ((index: number) => any) | undefined;
20
16
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
17
  export default _default;
@@ -18,14 +18,19 @@
18
18
  />
19
19
  </div>
20
20
  <div class="bk-command-palette-results bk-scrollbar-dark">
21
- <Group
22
- :commands="items"
23
- :visible-ids="visibleIds"
24
- :focused-id="focusedId"
25
- @close="$emit('close')"
26
- @focus="onFocus"
27
- @select="onSelect($event)"
28
- />
21
+ <div class="bk-command-palette-results-list">
22
+ <div>
23
+ <Item
24
+ v-for="(item, index) in visibleCommands"
25
+ :key="item.id"
26
+ :item="item"
27
+ :index="index"
28
+ :is-focused="focusedIndex === index"
29
+ @focus="onFocus"
30
+ @select="onSelect"
31
+ />
32
+ </div>
33
+ </div>
29
34
  </div>
30
35
  </ScrollBoundary>
31
36
  </template>
@@ -38,23 +43,24 @@ import {
38
43
  useBlokkli,
39
44
  watch,
40
45
  nextTick,
41
- onBeforeUnmount
46
+ onBeforeUnmount,
47
+ useTemplateRef
42
48
  } from "#imports";
43
49
  import { Icon, ScrollBoundary } from "#blokkli/components";
44
- import Group from "./Group/index.vue";
45
- import { falsy } from "#blokkli/helpers";
46
50
  import { Fzf } from "fzf";
51
+ import { modulo } from "#blokkli/helpers";
52
+ import Item from "./Item/index.vue";
47
53
  const { commands, $t, selection } = useBlokkli();
48
54
  const emit = defineEmits(["close"]);
49
- const inputEl = ref(null);
55
+ const inputEl = useTemplateRef("inputEl");
50
56
  const text = ref("");
51
- const focusedId = ref("");
57
+ const focusedIndex = ref(0);
52
58
  const hasUsedMouse = ref(false);
53
- function onFocus(id) {
59
+ function onFocus(index) {
54
60
  if (!hasUsedMouse.value) {
55
61
  return;
56
62
  }
57
- focusedId.value = id;
63
+ focusedIndex.value = index;
58
64
  }
59
65
  const items = computed(
60
66
  () => commands.getCommands().filter((v) => !v.disabled).map((doc, index) => {
@@ -65,8 +71,6 @@ const items = computed(
65
71
  })
66
72
  );
67
73
  const fzf = new Fzf(items.value, {
68
- // With selector you tell FZF where it can find
69
- // the string that you want to query on
70
74
  selector: (item) => item.label
71
75
  });
72
76
  const visibleIds = computed(
@@ -84,6 +88,16 @@ const visibleIds = computed(
84
88
  }).sort((a, b) => b.score - a.score);
85
89
  }
86
90
  );
91
+ const visibleCommands = computed(() => {
92
+ return items.value.map((v) => {
93
+ const found = visibleIds.value?.find((w) => w.id === v._id);
94
+ return {
95
+ ...v,
96
+ visible: visibleIds.value === void 0 || !!found,
97
+ positions: found?.positions
98
+ };
99
+ }).filter((v) => v.visible);
100
+ });
87
101
  watch(text, () => {
88
102
  nextTick(() => {
89
103
  focusFirst();
@@ -91,62 +105,25 @@ watch(text, () => {
91
105
  });
92
106
  watch(selection.uuids, () => emit("close"));
93
107
  const focusFirst = () => {
94
- const element = document.querySelector(
95
- '.bk-command-palette .bk-command[data-command-visible="true"]'
96
- );
97
- if (element instanceof HTMLElement) {
98
- focusedId.value = element.dataset.commandId || "";
99
- }
100
- };
101
- const getCommandElements = () => {
102
- return [
103
- ...document.querySelectorAll(
104
- '.bk-command-palette .bk-command[data-command-visible="true"]'
105
- )
106
- ].map((el) => {
107
- if (el instanceof HTMLElement) {
108
- const id = el.dataset.commandId;
109
- if (id) {
110
- return {
111
- id,
112
- el,
113
- focused: focusedId.value === id
114
- };
115
- }
116
- }
117
- }).filter(falsy);
108
+ focusedIndex.value = 0;
118
109
  };
119
110
  const focusPrev = () => {
120
- const elements = getCommandElements();
121
- if (elements.length === 0) {
111
+ if (visibleCommands.value.length === 0) {
122
112
  return;
123
113
  }
124
- const focusedIndex = elements.findIndex((v) => v.focused);
125
- if (focusedIndex <= 0) {
126
- focusedId.value = elements[elements.length - 1].id;
127
- } else {
128
- focusedId.value = elements[focusedIndex - 1].id;
129
- }
130
- scrollFocusedIntoView();
114
+ focusedIndex.value = modulo(
115
+ focusedIndex.value - 1,
116
+ visibleCommands.value.length
117
+ );
131
118
  };
132
119
  const focusNext = () => {
133
- const elements = getCommandElements();
134
- if (elements.length === 0) {
120
+ if (visibleCommands.value.length === 0) {
135
121
  return;
136
122
  }
137
- const focusedIndex = elements.findIndex((v) => v.focused);
138
- if (focusedIndex === -1 || focusedIndex === elements.length - 1) {
139
- focusedId.value = elements[0].id;
140
- } else {
141
- focusedId.value = elements[focusedIndex + 1].id;
142
- }
143
- scrollFocusedIntoView();
144
- };
145
- const scrollFocusedIntoView = () => {
146
- const element = getCommandElements().find((v) => v.focused)?.el;
147
- if (element) {
148
- element.scrollIntoView({ block: "nearest", inline: "nearest" });
149
- }
123
+ focusedIndex.value = modulo(
124
+ focusedIndex.value + 1,
125
+ visibleCommands.value.length
126
+ );
150
127
  };
151
128
  const onSelect = (id) => {
152
129
  const command = items.value.find((v) => v.id === id);
@@ -177,7 +154,10 @@ const onKeyDown = (e) => {
177
154
  focusPrev();
178
155
  } else if (e.code === "Enter") {
179
156
  e.preventDefault();
180
- onSelect(focusedId.value);
157
+ const command = visibleCommands.value[focusedIndex.value];
158
+ if (command) {
159
+ onSelect(command.id);
160
+ }
181
161
  } else if (e.code === "Escape") {
182
162
  e.preventDefault();
183
163
  emit("close");
@@ -30,7 +30,7 @@
30
30
  :title="$t('addCommentToItem', 'Add Comment...')"
31
31
  :active="showAddComment"
32
32
  weight="last"
33
- icon="comment"
33
+ icon="comment_add"
34
34
  multiple
35
35
  @click="showAddComment = !showAddComment"
36
36
  />
@@ -18,7 +18,7 @@ import {
18
18
  watch
19
19
  } from "#imports";
20
20
  import { PluginItemDropdown } from "#blokkli/plugins";
21
- import { falsy, onlyUnique } from "#blokkli/helpers";
21
+ import { falsy } from "#blokkli/helpers";
22
22
  const { adapter } = defineBlokkliFeature({
23
23
  id: "conversions",
24
24
  label: "Conversions",
@@ -46,20 +46,17 @@ async function onConvert(targetBundle) {
46
46
  }
47
47
  await state.mutateWithLoadingState(
48
48
  () => adapter.convertBlocks(
49
- selection.blocks.value.map((v) => v.uuid),
49
+ selection.items.value.map((v) => v.uuid),
50
50
  targetBundle
51
51
  ),
52
52
  $t("failedToConvert", "The block could not be converted.")
53
53
  );
54
54
  }
55
- const itemBundleIds = computed(
56
- () => selection.blocks.value.map((v) => v.itemBundle).filter(onlyUnique)
57
- );
58
55
  const possibleConversions = computed(() => {
59
- if (itemBundleIds.value.length !== 1) {
56
+ if (selection.bundles.value.length !== 1) {
60
57
  return [];
61
58
  }
62
- const sourceType = itemBundleIds.value[0];
59
+ const sourceType = selection.bundles.value[0];
63
60
  const titleBase = $t("conversionsConvertTo", "Convert to: @bundle");
64
61
  return conversions.value.filter(
65
62
  (v) => v.sourceBundle === sourceType && types.allowedTypesInList.value.includes(v.targetBundle)
@@ -14,7 +14,7 @@
14
14
  import { useBlokkli, ref } from "#imports";
15
15
  import { falsy, intersects } from "#blokkli/helpers";
16
16
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
17
- const { ui, dom, editable } = useBlokkli();
17
+ const { ui, dom, directive } = useBlokkli();
18
18
  const canvasRects = ref(null);
19
19
  function drawRects(ctx, rects, scale, offset, viewport) {
20
20
  for (let i = 0; i < rects.length; i++) {
@@ -54,7 +54,7 @@ onBlokkliEvent("canvas:draw", (e) => {
54
54
  }).filter(falsy);
55
55
  drawRects(ctx, visibleFieldRects, e.artboardScale, e.artboardOffset, viewport);
56
56
  ctx.strokeStyle = "green";
57
- const editableRects = editable.getVisible();
57
+ const editableRects = directive.getVisible("editable");
58
58
  drawRects(ctx, editableRects, e.artboardScale, e.artboardOffset, viewport);
59
59
  });
60
60
  </script>
@@ -12,8 +12,11 @@ const { logger } = defineBlokkliFeature({
12
12
  icon: "bug",
13
13
  description: "Provides debugging functionality."
14
14
  });
15
- const { debug } = useBlokkli();
15
+ const { debug, ui } = useBlokkli();
16
16
  onBlokkliEvent("keyPressed", (e) => {
17
+ if (ui.hasDialogOpen.value) {
18
+ return;
19
+ }
17
20
  if (e.code === "=" && e.meta) {
18
21
  e.originalEvent.preventDefault();
19
22
  debug.toggle();
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <PluginItemAction
3
3
  id="delete"
4
+ edit-only
4
5
  :title="$t('deleteButton', 'Delete')"
5
- :disabled="state.editMode.value !== 'editing'"
6
6
  multiple
7
7
  key-code="Delete"
8
8
  icon="delete"
@@ -69,7 +69,14 @@ import {
69
69
  import { Icon, ItemIcon, BlokkliTransition } from "#blokkli/components";
70
70
  import { easeOutElastic } from "#blokkli/helpers/easing";
71
71
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
72
- const { dom, ui, animation, theme, types } = useBlokkli();
72
+ const {
73
+ dom,
74
+ ui,
75
+ animation,
76
+ theme,
77
+ types,
78
+ element: elementProvider
79
+ } = useBlokkli();
73
80
  const props = defineProps({
74
81
  items: { type: Array, required: true },
75
82
  x: { type: Number, required: true },
@@ -201,7 +208,11 @@ onMounted(() => {
201
208
  if (!itemElement) {
202
209
  return;
203
210
  }
204
- const element = itemElement.querySelector(".bk-drop-element") || itemElement;
211
+ const element = elementProvider.query(
212
+ itemElement,
213
+ ".bk-drop-element",
214
+ "Find drop element for drag item."
215
+ ) || itemElement;
205
216
  return {
206
217
  rect: element.getBoundingClientRect(),
207
218
  element,
@@ -259,9 +270,6 @@ onMounted(() => {
259
270
  let bundle;
260
271
  let label = "";
261
272
  if (!markup) {
262
- if (item.item.itemType === "existing" && item.item.editTitle) {
263
- label = item.item.editTitle;
264
- }
265
273
  if ("itemBundle" in item.item) {
266
274
  bundle = item.item.itemBundle;
267
275
  if (bundle) {
@@ -61,7 +61,8 @@ const {
61
61
  animation,
62
62
  state,
63
63
  runtimeConfig,
64
- types
64
+ types,
65
+ fields
65
66
  } = useBlokkli();
66
67
  const gl = animation.gl();
67
68
  const canvas = animation.getCanvasElement();
@@ -121,7 +122,7 @@ const emitDrop = async () => {
121
122
  if (!hostUuid || !fieldName) {
122
123
  return;
123
124
  }
124
- const field = dom.findField(hostUuid, fieldName);
125
+ const field = fields.find(hostUuid, fieldName);
125
126
  if (!field) {
126
127
  return;
127
128
  }
@@ -149,19 +150,21 @@ const emitDrop = async () => {
149
150
  const draggingBundles = computed(
150
151
  () => props.items.flatMap((item) => {
151
152
  const bundles = [];
152
- if ("itemBundle" in item && item.itemBundle) {
153
+ if (item.itemType === "existing" || item.itemType === "existing_structure") {
154
+ bundles.push(item.block.bundle);
155
+ if (item.block.library?.reusableBundle) {
156
+ bundles.push(item.block.library.reusableBundle);
157
+ }
158
+ } else if (item.itemBundle) {
153
159
  bundles.push(item.itemBundle);
154
160
  }
155
- if ("reusableBundle" in item && item.reusableBundle) {
156
- bundles.push(item.reusableBundle);
157
- }
158
161
  return bundles;
159
162
  }).filter(falsy)
160
163
  );
161
164
  const selectionUuids = computed(
162
165
  () => props.items.map((item) => {
163
166
  if (item.itemType === "existing") {
164
- return item.uuid;
167
+ return item.block.uuid;
165
168
  }
166
169
  }).filter(falsy)
167
170
  );
@@ -305,7 +308,7 @@ const buildFieldRect = (key) => {
305
308
  if (!uuid || !name) {
306
309
  return;
307
310
  }
308
- const field = dom.findField(uuid, name);
311
+ const field = fields.find(uuid, name);
309
312
  if (!field) {
310
313
  return;
311
314
  }
@@ -605,11 +608,11 @@ function setHoveredFieldArea(box, mouse) {
605
608
  }
606
609
  return;
607
610
  }
608
- const fields = Object.values(fieldCache);
611
+ const fields2 = Object.values(fieldCache);
609
612
  let highestNestingLevel = 0;
610
613
  let candidate = null;
611
- for (let i = 0; i < fields.length; i++) {
612
- const field = fields[i];
614
+ for (let i = 0; i < fields2.length; i++) {
615
+ const field = fields2[i];
613
616
  if (!field.canAddChildren) {
614
617
  continue;
615
618
  }
@@ -40,7 +40,18 @@ const { adapter } = defineBlokkliFeature({
40
40
  description: "Renders an overlay when dragging or placing a block.",
41
41
  screenshot: "feature-dragging-overlay.jpg"
42
42
  });
43
- const { eventBus, state, ui, animation, dom, selection, definitions } = useBlokkli();
43
+ const {
44
+ eventBus,
45
+ state,
46
+ ui,
47
+ animation,
48
+ dom,
49
+ selection,
50
+ definitions,
51
+ blocks,
52
+ directive,
53
+ fields
54
+ } = useBlokkli();
44
55
  const dragItemsComponent = ref(null);
45
56
  const isVisible = ref(false);
46
57
  const isTouching = ref(false);
@@ -77,7 +88,7 @@ function filterItemType(items) {
77
88
  return { itemType, item: items[0] };
78
89
  }
79
90
  const onDropNew = async (bundle, host, afterUuid) => {
80
- const field = dom.findField(host.uuid, host.fieldName);
91
+ const field = fields.find(host.uuid, host.fieldName);
81
92
  if (!field) {
82
93
  throw new Error(
83
94
  `Failed to locate field with name "${host.fieldName}" on UUID "${host.uuid}"`
@@ -106,7 +117,7 @@ const onDropNew = async (bundle, host, afterUuid) => {
106
117
  }
107
118
  };
108
119
  const onDropExisting = async (items, host, afterUuid) => {
109
- const uuids = items.map((v) => v.uuid);
120
+ const uuids = items.map((v) => v.block.uuid);
110
121
  await state.mutateWithLoadingState(
111
122
  () => adapter.moveMultipleBlocks({
112
123
  uuids,
@@ -224,15 +235,15 @@ onBlokkliEvent("state:reloaded", async function() {
224
235
  }
225
236
  eventBus.emit("select", newUuid);
226
237
  await renderCycle();
227
- const newBlock = dom.findBlock(newUuid);
238
+ const newBlock = blocks.getBlock(newUuid);
228
239
  if (!newBlock) {
229
240
  return;
230
241
  }
231
242
  const allSelected = [...selection.uuids.value, newBlock.uuid];
232
243
  eventBus.emit("select", allSelected);
233
244
  const definition = definitions.getBlockDefinition(
234
- newBlock.itemBundle,
235
- newBlock.hostFieldListType
245
+ newBlock.bundle,
246
+ newBlock.fieldListType
236
247
  );
237
248
  if (!definition?.editor?.addBehaviour?.startsWith("editable:")) {
238
249
  return;
@@ -241,8 +252,8 @@ onBlokkliEvent("state:reloaded", async function() {
241
252
  if (!editableField) {
242
253
  return;
243
254
  }
244
- const editableFieldElement = newBlock.element().querySelector(`[data-blokkli-editable-field="${editableField}"]`);
245
- if (!(editableFieldElement instanceof HTMLElement)) {
255
+ const editableFieldElement = directive.getEditablesForBlock(newUuid).find((v) => v.fieldName === editableField);
256
+ if (!editableFieldElement) {
246
257
  return;
247
258
  }
248
259
  eventBus.emit("editable:focus", {
@@ -283,17 +294,15 @@ onBlokkliEvent("dragging:start", (e) => {
283
294
  mouseY.value = e.coords.y;
284
295
  dom.updateVisibleRects();
285
296
  dragItems.value = e.items;
286
- if ("element" in item) {
287
- if (!isTouching.value) {
288
- document.removeEventListener("pointerup", onMouseUp);
289
- document.addEventListener("pointerup", onMouseUp);
290
- document.removeEventListener("pointermove", onMouseMove, {
291
- capture: true
292
- });
293
- document.addEventListener("pointermove", onMouseMove, { capture: true });
294
- }
295
- eventBus.on("animationFrame", loop);
297
+ if (!isTouching.value) {
298
+ document.removeEventListener("pointerup", onMouseUp);
299
+ document.addEventListener("pointerup", onMouseUp);
300
+ document.removeEventListener("pointermove", onMouseMove, {
301
+ capture: true
302
+ });
303
+ document.addEventListener("pointermove", onMouseMove, { capture: true });
296
304
  }
305
+ eventBus.on("animationFrame", loop);
297
306
  });
298
307
  onBlokkliEvent("dragging:end", () => {
299
308
  isVisible.value = false;
@@ -303,6 +312,9 @@ onBlokkliEvent("dragging:end", () => {
303
312
  document.removeEventListener("pointermove", onMouseMove, { capture: true });
304
313
  });
305
314
  onBlokkliEvent("keyPressed", (e) => {
315
+ if (ui.hasDialogOpen.value) {
316
+ return;
317
+ }
306
318
  if (e.code === "Escape") {
307
319
  eventBus.emit("dragging:end");
308
320
  }