@blokkli/editor 2.0.0-alpha.23 → 2.0.0-alpha.24

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 (115) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +62 -66
  3. package/dist/runtime/blokkliPlugins/ContextMenu/index.vue +1 -1
  4. package/dist/runtime/blokkliPlugins/Sidebar/index.vue.d.ts +1 -1
  5. package/dist/runtime/blokkliPlugins/ToolbarButton/index.vue +5 -1
  6. package/dist/runtime/blokkliPlugins/ToolbarButton/index.vue.d.ts +2 -0
  7. package/dist/runtime/blokkliPlugins/TourItem/index.vue +22 -13
  8. package/dist/runtime/blokkliPlugins/TourItem/index.vue.d.ts +1 -0
  9. package/dist/runtime/blokkliPlugins/index.d.ts +1 -3
  10. package/dist/runtime/blokkliPlugins/index.js +0 -4
  11. package/dist/runtime/components/BlokkliProvider.vue.d.ts +1 -1
  12. package/dist/runtime/components/Edit/Actions/ItemDropdown.vue +1 -1
  13. package/dist/runtime/components/Edit/Actions/index.vue +77 -72
  14. package/dist/runtime/components/Edit/AddListItem/index.vue +8 -29
  15. package/dist/runtime/components/Edit/AddListItem/index.vue.d.ts +2 -3
  16. package/dist/runtime/components/Edit/AppMenu/MenuButton.vue +39 -0
  17. package/dist/runtime/{blokkliPlugins/MenuButton/index.vue.d.ts → components/Edit/AppMenu/MenuButton.vue.d.ts} +0 -4
  18. package/dist/runtime/components/Edit/AppMenu/index.vue +62 -40
  19. package/dist/runtime/components/Edit/Dialog/index.vue +26 -5
  20. package/dist/runtime/components/Edit/Dialog/index.vue.d.ts +2 -0
  21. package/dist/runtime/components/Edit/EditProvider.vue +48 -31
  22. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +1 -1
  23. package/dist/runtime/components/Edit/Features/AddList/Actions/Action.vue +52 -0
  24. package/dist/runtime/components/Edit/Features/AddList/Actions/Action.vue.d.ts +7 -0
  25. package/dist/runtime/components/Edit/Features/AddList/Actions/index.vue +41 -0
  26. package/dist/runtime/components/Edit/Features/AddList/Actions/index.vue.d.ts +5 -0
  27. package/dist/runtime/components/Edit/Features/AddList/Blocks/index.vue +11 -47
  28. package/dist/runtime/components/Edit/Features/AddList/Blocks/index.vue.d.ts +5 -0
  29. package/dist/runtime/components/Edit/Features/AddList/index.vue +68 -123
  30. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +41 -20
  31. package/dist/runtime/components/Edit/Features/Artboard/Scrollbar/index.vue +3 -2
  32. package/dist/runtime/components/Edit/Features/Assistant/Overlay/index.vue +2 -28
  33. package/dist/runtime/components/Edit/Features/Assistant/index.vue +18 -14
  34. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +1 -0
  35. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +2 -2
  36. package/dist/runtime/components/Edit/Features/Clipboard/List/index.vue +1 -1
  37. package/dist/runtime/components/Edit/Features/Clipboard/index.vue +52 -18
  38. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +0 -2
  39. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue.d.ts +6 -4
  40. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +77 -27
  41. package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +7 -4
  42. package/dist/runtime/components/Edit/Features/Comments/index.vue +2 -2
  43. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/DragItem.vue +113 -0
  44. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/DragItem.vue.d.ts +25 -0
  45. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +8 -97
  46. package/dist/runtime/components/Edit/Features/DraggingOverlay/Renderer/fragment.glsl +2 -5
  47. package/dist/runtime/components/Edit/Features/DraggingOverlay/Renderer/index.vue +38 -5
  48. package/dist/runtime/components/Edit/Features/DraggingOverlay/Renderer/vertex.glsl +10 -1
  49. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +1 -2
  50. package/dist/runtime/components/Edit/Features/EditForm/index.vue +2 -2
  51. package/dist/runtime/components/Edit/Features/EditableField/index.vue +2 -2
  52. package/dist/runtime/components/Edit/Features/Exit/index.vue +12 -9
  53. package/dist/runtime/components/Edit/Features/Fragments/index.vue +27 -31
  54. package/dist/runtime/components/Edit/Features/ImportExisting/Dialog/index.vue +1 -0
  55. package/dist/runtime/components/Edit/Features/ImportExisting/index.vue +25 -24
  56. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +2 -2
  57. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +1 -0
  58. package/dist/runtime/components/Edit/Features/Library/index.vue +26 -24
  59. package/dist/runtime/components/Edit/Features/MultiSelect/Renderer/index.vue +1 -3
  60. package/dist/runtime/components/Edit/Features/PreviewGrant/index.vue +2 -1
  61. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +1 -0
  62. package/dist/runtime/components/Edit/Features/Publish/index.vue +17 -15
  63. package/dist/runtime/components/Edit/Features/Revert/index.vue +24 -18
  64. package/dist/runtime/components/Edit/Features/Search/index.vue +1 -1
  65. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +21 -17
  66. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +6 -6
  67. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +3 -6
  68. package/dist/runtime/components/Edit/Features/Settings/Dialog/index.vue +1 -0
  69. package/dist/runtime/components/Edit/Features/Settings/index.vue +25 -17
  70. package/dist/runtime/components/Edit/Features/TouchActionBar/index.vue +2 -2
  71. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +1 -1
  72. package/dist/runtime/components/Edit/Features/Tour/Popup/index.vue +2 -2
  73. package/dist/runtime/components/Edit/Features/Tour/index.vue +12 -10
  74. package/dist/runtime/components/Edit/Features/Transform/index.vue +1 -1
  75. package/dist/runtime/components/Edit/Features/Translations/index.vue +18 -17
  76. package/dist/runtime/components/Edit/FormOverlay/index.vue +13 -4
  77. package/dist/runtime/components/Edit/ItemIconBox/index.vue +41 -0
  78. package/dist/runtime/components/Edit/{AddListItemIcon → ItemIconBox}/index.vue.d.ts +5 -5
  79. package/dist/runtime/components/Edit/Konami/Game/index.vue +0 -1
  80. package/dist/runtime/components/Edit/Konami/index.vue +3 -5
  81. package/dist/runtime/components/Edit/Messages/Item/index.vue +11 -2
  82. package/dist/runtime/components/Edit/Messages/index.vue +6 -1
  83. package/dist/runtime/components/Edit/Overlay/index.vue +66 -0
  84. package/dist/runtime/components/Edit/Overlay/index.vue.d.ts +2 -0
  85. package/dist/runtime/components/Edit/SystemRequirements/index.vue +36 -36
  86. package/dist/runtime/components/Edit/Toolbar/index.vue +47 -48
  87. package/dist/runtime/components/Edit/index.d.ts +2 -2
  88. package/dist/runtime/components/Edit/index.js +2 -2
  89. package/dist/runtime/css/output.css +1 -1
  90. package/dist/runtime/helpers/composables/defineAddAction.d.ts +2 -0
  91. package/dist/runtime/helpers/composables/defineAddAction.js +10 -0
  92. package/dist/runtime/helpers/composables/defineItemDropdownAction.js +2 -2
  93. package/dist/runtime/helpers/composables/defineMenuButton.d.ts +2 -0
  94. package/dist/runtime/helpers/composables/defineMenuButton.js +10 -0
  95. package/dist/runtime/helpers/composables/useDialog.d.ts +3 -0
  96. package/dist/runtime/helpers/composables/useDialog.js +16 -0
  97. package/dist/runtime/helpers/defineElementStyle.d.ts +2 -0
  98. package/dist/runtime/helpers/defineElementStyle.js +33 -0
  99. package/dist/runtime/helpers/domProvider.d.ts +1 -0
  100. package/dist/runtime/helpers/domProvider.js +7 -2
  101. package/dist/runtime/helpers/dropTargets/index.d.ts +1 -1
  102. package/dist/runtime/helpers/dropTargets/index.js +17 -3
  103. package/dist/runtime/helpers/pluginProvider.d.ts +25 -6
  104. package/dist/runtime/helpers/pluginProvider.js +48 -46
  105. package/dist/runtime/helpers/providers/blocks.js +10 -0
  106. package/dist/runtime/helpers/providers/fields.d.ts +9 -1
  107. package/dist/runtime/helpers/uiProvider.d.ts +9 -12
  108. package/dist/runtime/helpers/uiProvider.js +85 -83
  109. package/dist/runtime/icons/click.svg +1 -0
  110. package/dist/runtime/types/index.d.ts +12 -5
  111. package/package.json +1 -1
  112. package/dist/runtime/blokkliPlugins/AddAction/index.vue +0 -96
  113. package/dist/runtime/blokkliPlugins/AddAction/index.vue.d.ts +0 -26
  114. package/dist/runtime/blokkliPlugins/MenuButton/index.vue +0 -68
  115. package/dist/runtime/components/Edit/AddListItemIcon/index.vue +0 -19
@@ -77,7 +77,7 @@ import {
77
77
  import { PluginSidebar } from "#blokkli/plugins";
78
78
  import defineItemDropdownAction from "#blokkli/helpers/composables/defineItemDropdownAction";
79
79
  import ClipboardList from "./List/index.vue";
80
- import { generateUUID, getFieldKey } from "#blokkli/helpers";
80
+ import { falsy, generateUUID, getFieldKey } from "#blokkli/helpers";
81
81
  import { Icon } from "#blokkli/components";
82
82
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
83
83
  import defineShortcut from "#blokkli/helpers/composables/defineShortcut";
@@ -100,7 +100,7 @@ const { settings, logger } = defineBlokkliFeature({
100
100
  },
101
101
  screenshot: "feature-clipboard.jpg"
102
102
  });
103
- const { selection, $t, adapter, state, ui, types, keyboard, blocks } = useBlokkli();
103
+ const { selection, $t, adapter, state, ui, types, keyboard, blocks, fields } = useBlokkli();
104
104
  const plugin = ref(null);
105
105
  const selectionClipboard = ref([]);
106
106
  const itemDropdownItems = computed(() => {
@@ -287,30 +287,47 @@ const handleSelectionPaste = (pastedUuids) => {
287
287
  return;
288
288
  }
289
289
  let targetField = null;
290
- let targetFieldConfig = null;
290
+ let targetFieldElement = null;
291
291
  let targetFieldKey = null;
292
292
  let preceedingUuid = void 0;
293
293
  if (!keyboard.isPressingShift.value) {
294
294
  const pastedBundles = pastedUuids.map((uuid) => blocks.getBlock(uuid)?.bundle).filter((bundle) => !!bundle);
295
+ const pastedFragments = pastedUuids.map((uuid) => {
296
+ const block2 = blocks.getBlock(uuid);
297
+ if (block2?.bundle === "blokkli_fragment" && block2.fragment?.name) {
298
+ return block2.fragment.name;
299
+ }
300
+ return null;
301
+ }).filter(falsy);
295
302
  if (pastedBundles.length) {
296
303
  const nestedFields = types.fieldConfig.forEntityTypeAndBundle(
297
304
  itemEntityType,
298
305
  block.bundle
299
306
  );
300
307
  for (const fieldConfig of nestedFields) {
308
+ const fieldElement = fields.find(block.uuid, fieldConfig.name);
309
+ if (!fieldElement) {
310
+ continue;
311
+ }
301
312
  const allowedPastedBundles = pastedBundles.filter(
302
- (bundle) => fieldConfig.allowedBundles.includes(bundle)
313
+ (bundle) => fieldElement.allowedBundles.includes(bundle)
303
314
  );
304
- if (allowedPastedBundles.length > 0) {
315
+ let fragmentsAllowed = true;
316
+ if (pastedFragments.length > 0 && fieldElement.allowedFragments.length > 0) {
317
+ fragmentsAllowed = pastedFragments.every(
318
+ (fragment) => fieldElement.allowedFragments.includes(fragment)
319
+ );
320
+ }
321
+ if (allowedPastedBundles.length > 0 && fragmentsAllowed) {
305
322
  const nestedFieldKey = getFieldKey(block.uuid, fieldConfig.name);
306
323
  const currentCount = state.getFieldBlockCount(nestedFieldKey);
307
- if (fieldConfig.cardinality === -1 || currentCount + allowedPastedBundles.length <= fieldConfig.cardinality) {
324
+ if (fieldElement.cardinality === -1 || currentCount + allowedPastedBundles.length <= fieldElement.cardinality) {
308
325
  targetField = {
309
326
  entityType: itemEntityType,
310
327
  entityUuid: block.uuid,
311
328
  name: fieldConfig.name
312
329
  };
313
- targetFieldConfig = fieldConfig;
330
+ targetFieldElement = fieldElement;
314
331
  targetFieldKey = nestedFieldKey;
315
332
  preceedingUuid = void 0;
316
333
  break;
@@ -319,17 +336,13 @@ const handleSelectionPaste = (pastedUuids) => {
319
336
  }
320
337
  }
321
338
  }
322
- if (!targetField || !targetFieldConfig || !targetFieldKey) {
339
+ if (!targetField || !targetFieldElement || !targetFieldKey) {
323
340
  const field = state.getMutatedField(block.host.uuid, block.host.fieldName);
324
341
  if (!field) {
325
342
  return;
326
343
  }
327
- const fieldConfig = types.getFieldConfig(
328
- field.entityType,
329
- block.host.bundle,
330
- field.name
331
- );
332
- if (!fieldConfig) {
344
+ const fieldElement = fields.find(field.entityUuid, field.name);
345
+ if (!fieldElement) {
333
346
  return;
334
347
  }
335
348
  targetField = {
@@ -337,12 +350,13 @@ const handleSelectionPaste = (pastedUuids) => {
337
350
  entityUuid: field.entityUuid,
338
351
  name: field.name
339
352
  };
340
- targetFieldConfig = fieldConfig;
353
+ targetFieldElement = fieldElement;
341
354
  targetFieldKey = getFieldKey(field.entityUuid, field.name);
342
355
  preceedingUuid = selection.uuids.value[0];
343
356
  }
344
357
  const pastedBlocks = [];
345
358
  const notAllowedBundles = [];
359
+ const notAllowedFragments = [];
346
360
  for (let i = 0; i < pastedUuids.length; i++) {
347
361
  const uuid = pastedUuids[i];
348
362
  if (!uuid) {
@@ -352,14 +366,34 @@ const handleSelectionPaste = (pastedUuids) => {
352
366
  if (!block2) {
353
367
  continue;
354
368
  }
355
- const isAllowed = targetFieldConfig.allowedBundles.includes(block2.bundle);
369
+ const isAllowed = targetFieldElement.allowedBundles.includes(block2.bundle);
356
370
  if (!isAllowed) {
357
371
  notAllowedBundles.push(block2.bundle);
358
372
  continue;
359
373
  }
374
+ if (block2.bundle === "blokkli_fragment" && block2.fragment?.name && targetFieldElement.allowedFragments.length > 0) {
375
+ const fragmentAllowed = targetFieldElement.allowedFragments.includes(
376
+ block2.fragment.name
377
+ );
378
+ if (!fragmentAllowed) {
379
+ notAllowedFragments.push(block2.fragment.name);
380
+ continue;
381
+ }
382
+ }
360
383
  pastedBlocks.push(block2);
361
384
  }
362
385
  if (!pastedBlocks.length) {
386
+ if (notAllowedFragments.length) {
387
+ const message2 = notAllowedFragments.length === 1 ? $t(
388
+ "clipboardPasteErrorAllowedFragmentsSingle",
389
+ 'Fragment "@types" is not allowed here.'
390
+ ) : $t(
391
+ "clipboardPasteErrorAllowedFragmentsMultiple",
392
+ "Fragments (@types) are not allowed here."
393
+ );
394
+ emitPasteError(message2.replace("@types", notAllowedFragments.join(", ")));
395
+ return;
396
+ }
363
397
  const blockTypes = notAllowedBundles.map((bundle) => {
364
398
  return types.getBlockBundleDefinition(bundle)?.label ?? bundle;
365
399
  });
@@ -374,12 +408,12 @@ const handleSelectionPaste = (pastedUuids) => {
374
408
  return;
375
409
  }
376
410
  const count = state.getFieldBlockCount(targetFieldKey);
377
- if (targetFieldConfig.cardinality !== -1 && count + pastedBlocks.length > targetFieldConfig.cardinality) {
411
+ if (targetFieldElement.cardinality !== -1 && count + pastedBlocks.length > targetFieldElement.cardinality) {
378
412
  emitPasteError(
379
413
  $t(
380
414
  "clipboardPasteErrorCardinality",
381
415
  "This field only allows up to @count blocks."
382
- ).replace("@count", targetFieldConfig.cardinality.toString())
416
+ ).replace("@count", targetFieldElement.cardinality.toString())
383
417
  );
384
418
  return;
385
419
  }
@@ -1,8 +1,6 @@
1
1
  <template>
2
2
  <button
3
3
  ref="buttonEl"
4
- :data-command-id="item.id"
5
- :data-command-visible="true"
6
4
  class="bk-command"
7
5
  :class="{ 'bk-is-focused': isFocused }"
8
6
  @mouseenter="$emit('focus', index)"
@@ -1,9 +1,11 @@
1
1
  import type { Command } from '#blokkli/types';
2
+ export type MappedCommandItem = Command & {
3
+ positions?: number[];
4
+ score?: number;
5
+ visible?: boolean;
6
+ };
2
7
  type __VLS_Props = {
3
- item: Command & {
4
- _id: number;
5
- positions?: number[];
6
- };
8
+ item: MappedCommandItem;
7
9
  index: number;
8
10
  isFocused: boolean;
9
11
  };
@@ -21,11 +21,12 @@
21
21
  <div class="bk-command-palette-results-list">
22
22
  <div>
23
23
  <Item
24
- v-for="(item, index) in visibleCommands"
24
+ v-for="item in allCommands"
25
+ v-show="item.visible"
25
26
  :key="item.id"
26
27
  :item="item"
27
- :index="index"
28
- :is-focused="focusedIndex === index"
28
+ :index="getVisibleIndex(item.id)"
29
+ :is-focused="focusedIndex === getVisibleIndex(item.id)"
29
30
  @focus="onFocus"
30
31
  @select="onSelect"
31
32
  />
@@ -49,9 +50,21 @@ import {
49
50
  import { Icon, ScrollBoundary } from "#blokkli/components";
50
51
  import { Fzf } from "fzf";
51
52
  import { modulo } from "#blokkli/helpers";
52
- import Item from "./Item/index.vue";
53
- const { commands, $t, selection } = useBlokkli();
53
+ import Item, {} from "./Item/index.vue";
54
+ import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
54
55
  const emit = defineEmits(["close"]);
56
+ const { commands, $t, selection, plugins, storage } = useBlokkli();
57
+ const frequency = storage.use(
58
+ "commandPaletteFrequency",
59
+ {}
60
+ );
61
+ function incrementFrequency(id) {
62
+ const currentCount = frequency.value[id] ?? 0;
63
+ frequency.value = {
64
+ ...frequency.value,
65
+ [id]: currentCount + 1
66
+ };
67
+ }
55
68
  const inputEl = useTemplateRef("inputEl");
56
69
  const text = ref("");
57
70
  const focusedIndex = ref(0);
@@ -62,42 +75,75 @@ function onFocus(index) {
62
75
  }
63
76
  focusedIndex.value = index;
64
77
  }
65
- const items = computed(
66
- () => commands.getCommands().filter((v) => !v.disabled).map((doc, index) => {
78
+ const items = computed(() => {
79
+ return [
80
+ ...commands.getCommands(),
81
+ ...plugins.get("menuButton").map((plugin) => {
82
+ return {
83
+ id: "menu-button:" + plugin.id,
84
+ label: plugin.title,
85
+ group: "action",
86
+ icon: plugin.icon,
87
+ disabled: plugin.disabled,
88
+ callback: plugin.callback
89
+ };
90
+ })
91
+ ].filter((v) => !v.disabled).map((doc, index) => {
67
92
  return {
68
93
  ...doc,
69
- _id: index
94
+ _id: index,
95
+ visible: true
70
96
  };
71
- })
72
- );
97
+ }).sort((a, b) => {
98
+ const freqA = frequency.value[a.id] ?? 0;
99
+ const freqB = frequency.value[b.id] ?? 0;
100
+ return freqB - freqA;
101
+ });
102
+ });
73
103
  const fzf = new Fzf(items.value, {
74
104
  selector: (item) => item.label
75
105
  });
76
- const visibleIds = computed(
77
- () => {
78
- if (!text.value) {
79
- return void 0;
80
- }
81
- const results = fzf.find(text.value);
82
- return results.map((v) => {
83
- return {
84
- id: v.item._id,
85
- positions: [...v.positions],
86
- score: v.score
87
- };
88
- }).sort((a, b) => b.score - a.score);
106
+ const visibleIds = computed(() => {
107
+ if (!text.value) {
108
+ return void 0;
109
+ }
110
+ const results = fzf.find(text.value);
111
+ return results.map((v) => {
112
+ return {
113
+ id: v.item._id,
114
+ positions: [...v.positions],
115
+ score: v.score
116
+ };
117
+ });
118
+ });
119
+ const allCommands = computed(() => {
120
+ if (!text.value) {
121
+ return items.value;
89
122
  }
90
- );
91
- const visibleCommands = computed(() => {
92
123
  return items.value.map((v) => {
93
124
  const found = visibleIds.value?.find((w) => w.id === v._id);
94
125
  return {
95
126
  ...v,
96
127
  visible: visibleIds.value === void 0 || !!found,
97
- positions: found?.positions
128
+ positions: found?.positions,
129
+ score: found?.score ?? 0
98
130
  };
99
- }).filter((v) => v.visible);
131
+ }).sort((a, b) => {
132
+ const scoreDiff = b.score - a.score;
133
+ if (scoreDiff !== 0) {
134
+ return scoreDiff;
135
+ }
136
+ const freqA = frequency.value[a.id] ?? 0;
137
+ const freqB = frequency.value[b.id] ?? 0;
138
+ return freqB - freqA;
139
+ });
140
+ });
141
+ const visibleCommands = computed(() => {
142
+ return allCommands.value.filter((v) => v.visible !== false);
100
143
  });
144
+ const getVisibleIndex = (id) => {
145
+ return visibleCommands.value.findIndex((v) => v.id === id);
146
+ };
101
147
  watch(text, () => {
102
148
  nextTick(() => {
103
149
  focusFirst();
@@ -128,6 +174,7 @@ const focusNext = () => {
128
174
  const onSelect = (id) => {
129
175
  const command = items.value.find((v) => v.id === id);
130
176
  if (command) {
177
+ incrementFrequency(id);
131
178
  command.callback();
132
179
  emit("close");
133
180
  }
@@ -166,6 +213,9 @@ const onKeyDown = (e) => {
166
213
  const onWindowClick = () => {
167
214
  emit("close");
168
215
  };
216
+ onBlokkliEvent("overlay:close", () => {
217
+ emit("close");
218
+ });
169
219
  onMounted(() => {
170
220
  if (inputEl.value) {
171
221
  inputEl.value.focus();
@@ -1,16 +1,18 @@
1
1
  <template>
2
- <Teleport to="body">
2
+ <Teleport :to="ui.mainLayoutElement.value">
3
3
  <div class="bk">
4
4
  <BlokkliTransition name="command-palette">
5
5
  <Palette v-if="isVisible" @close="isVisible = false" />
6
6
  </BlokkliTransition>
7
7
  </div>
8
8
  </Teleport>
9
+
9
10
  <PluginToolbarButton
10
11
  id="command_palette"
11
12
  :title="label"
12
13
  meta
13
14
  key-code="K"
15
+ no-command
14
16
  region="before-sidebar"
15
17
  :tour-text="
16
18
  $t(
@@ -24,11 +26,12 @@
24
26
  </template>
25
27
 
26
28
  <script setup>
27
- import { useBlokkli, defineBlokkliFeature, ref, computed } from "#imports";
29
+ import { useBlokkli, defineBlokkliFeature, computed } from "#imports";
28
30
  import { PluginToolbarButton } from "#blokkli/plugins";
29
31
  import { BlokkliTransition } from "#blokkli/components";
30
32
  import Palette from "./Palette/index.vue";
31
33
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
34
+ import { useDialog } from "#blokkli/helpers/composables/useDialog";
32
35
  defineBlokkliFeature({
33
36
  id: "command-palette",
34
37
  icon: "command",
@@ -36,8 +39,8 @@ defineBlokkliFeature({
36
39
  description: "Provides a command palette with search to access most UI features with a keyboard.",
37
40
  viewports: ["desktop"]
38
41
  });
39
- const { $t } = useBlokkli();
40
- const isVisible = ref(false);
42
+ const { $t, ui } = useBlokkli();
43
+ const isVisible = useDialog("command-palette", "center");
41
44
  const label = computed(() => $t("commandPaletteOpen", "Open Command Palette"));
42
45
  onBlokkliEvent("window:clickAway", () => isVisible.value = false);
43
46
  </script>
@@ -35,7 +35,7 @@
35
35
  @click="showAddComment = !showAddComment"
36
36
  />
37
37
 
38
- <Teleport to="body">
38
+ <Teleport :to="ui.mainLayoutElement.value">
39
39
  <BlokkliTransition name="caret-tooltip">
40
40
  <CommentAddForm
41
41
  v-if="showAddComment"
@@ -75,7 +75,7 @@ const { adapter } = defineBlokkliFeature({
75
75
  description: "Provides comment functionality for blocks.",
76
76
  screenshot: "feature-comments.jpg"
77
77
  });
78
- const { eventBus, $t, selection } = useBlokkli();
78
+ const { eventBus, $t, selection, ui } = useBlokkli();
79
79
  const commentForm = ref(null);
80
80
  const showAddComment = ref(false);
81
81
  watch(selection.uuids, () => {
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <div
3
+ ref="rootEl"
4
+ class="bk-dragging-overlay-item"
5
+ :class="{ 'bk-is-top': isTop, 'bk-is-fallback': !markup }"
6
+ :style="{
7
+ width: width + 'px',
8
+ height: height + 'px',
9
+ transformOrigin,
10
+ background,
11
+ '--bk-dragging-scale': to.scaleX,
12
+ '--bk-dragging-radius': Math.max(borderRadius ?? 0, 4)
13
+ }"
14
+ >
15
+ <div
16
+ v-if="markup"
17
+ ref="markupEl"
18
+ class="bk-dragging-overlay-markup"
19
+ v-html="markup"
20
+ />
21
+ <div v-else class="bk-dragging-overlay-fallback">
22
+ <div :style="{ transform: `scale(${1 / to.scaleX})` }">
23
+ <template v-if="isTop">
24
+ <ItemIcon v-if="bundle" :bundle="bundle" />
25
+ <Icon v-else-if="icon" :name="icon" />
26
+ <div v-if="label">{{ label }}</div>
27
+ </template>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </template>
32
+
33
+ <script setup>
34
+ import { ref, onMounted, useBlokkli, useTemplateRef } from "#imports";
35
+ import { Icon, ItemIcon } from "#blokkli/components";
36
+ import { lerp } from "#blokkli/helpers";
37
+ import { easeOutElastic } from "#blokkli/helpers/easing";
38
+ import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
39
+ const props = defineProps({
40
+ isTop: { type: Boolean, required: true },
41
+ from: { type: Object, required: true },
42
+ to: { type: Object, required: true },
43
+ width: { type: Number, required: true },
44
+ height: { type: Number, required: true },
45
+ transformOrigin: { type: String, required: true },
46
+ markup: { type: String, required: true },
47
+ background: { type: String, required: true },
48
+ bundle: { type: String, required: false },
49
+ icon: { type: null, required: false },
50
+ label: { type: String, required: false },
51
+ prevVisibility: { type: String, required: false },
52
+ element: { type: null, required: true }
53
+ });
54
+ const DURATION = 500;
55
+ const { ui, theme } = useBlokkli();
56
+ const rootEl = useTemplateRef("rootEl");
57
+ const markupEl = useTemplateRef("markupEl");
58
+ const borderRadius = ref(null);
59
+ let isDone = false;
60
+ let animationStart = 0;
61
+ function setBorderRadius() {
62
+ if (borderRadius.value !== null) {
63
+ return;
64
+ }
65
+ if (!props.isTop) {
66
+ borderRadius.value = 4;
67
+ return;
68
+ }
69
+ if (markupEl.value) {
70
+ const child = markupEl.value.firstChild;
71
+ if (child instanceof HTMLElement) {
72
+ const style = theme.getDraggableStyle(child);
73
+ borderRadius.value = style.radiusMin;
74
+ return;
75
+ }
76
+ }
77
+ borderRadius.value = 4;
78
+ }
79
+ onBlokkliEvent("canvas:draw", (e) => {
80
+ if (isDone || !rootEl.value) {
81
+ return;
82
+ }
83
+ if (!animationStart) {
84
+ animationStart = e.time;
85
+ }
86
+ setBorderRadius();
87
+ const elapsed = e.time - animationStart;
88
+ const alphaX = easeOutElastic(elapsed / DURATION, 1.92, 0.91);
89
+ const alphaY = easeOutElastic(elapsed / DURATION, 2.2, 0.76);
90
+ const opacityAlpha = Math.min(Math.max(elapsed - 300, 0) / 200, 1);
91
+ const from = props.from;
92
+ const to = props.to;
93
+ if (elapsed > DURATION || !ui.useAnimations.value || ui.lowPerformanceMode.value) {
94
+ rootEl.value.style.transform = `translate(${to.x}px, ${to.y}px) scale(${to.scaleX}, ${to.scaleY})`;
95
+ rootEl.value.style.opacity = String(to.opacity);
96
+ isDone = true;
97
+ return;
98
+ }
99
+ const newX = lerp(from.x, to.x, alphaX);
100
+ const newY = lerp(from.y, to.y, alphaY);
101
+ const newOpacity = lerp(from.opacity, to.opacity, opacityAlpha);
102
+ const newScaleX = lerp(from.scaleX, to.scaleX, alphaX);
103
+ const newScaleY = lerp(from.scaleY, to.scaleY, alphaY);
104
+ rootEl.value.style.transform = `translate(${newX}px, ${newY}px) scale(${newScaleX}, ${newScaleY})`;
105
+ rootEl.value.style.opacity = String(newOpacity);
106
+ });
107
+ onMounted(() => {
108
+ if (rootEl.value) {
109
+ rootEl.value.style.transform = `translate(${props.from.x}px, ${props.from.y}px) scale(${props.from.scaleX}, ${props.from.scaleY})`;
110
+ rootEl.value.style.opacity = String(props.from.opacity);
111
+ }
112
+ });
113
+ </script>
@@ -0,0 +1,25 @@
1
+ import type { BlokkliIcon } from '#blokkli-build/icons';
2
+ type AnimationRectangleValues = {
3
+ opacity: number;
4
+ scaleX: number;
5
+ scaleY: number;
6
+ x: number;
7
+ y: number;
8
+ };
9
+ export type DragItemData = {
10
+ isTop: boolean;
11
+ from: AnimationRectangleValues;
12
+ to: AnimationRectangleValues;
13
+ width: number;
14
+ height: number;
15
+ transformOrigin: string;
16
+ markup: string;
17
+ background: string;
18
+ bundle?: string;
19
+ icon?: BlokkliIcon;
20
+ label?: string;
21
+ prevVisibility?: string;
22
+ element: HTMLElement;
23
+ };
24
+ declare const _default: import("vue").DefineComponent<DragItemData, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<DragItemData> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
+ export default _default;