@blokkli/editor 2.0.0-alpha.53 → 2.0.0-alpha.55

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 (218) hide show
  1. package/dist/global/constants/index.d.ts +1 -1
  2. package/dist/global/constants/index.js +1 -1
  3. package/dist/global/types/features.d.ts +5 -9
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +28 -35
  6. package/dist/modules/agent/index.mjs +46 -29
  7. package/dist/modules/agent/runtime/app/composables/agentProvider.js +2 -1
  8. package/dist/modules/agent/runtime/app/features/agent/Container.d.vue.ts +19 -0
  9. package/dist/modules/agent/runtime/app/features/agent/Container.vue +195 -0
  10. package/dist/modules/agent/runtime/app/features/agent/Container.vue.d.ts +19 -0
  11. package/dist/modules/agent/runtime/app/features/agent/index.vue +18 -164
  12. package/dist/modules/agent/runtime/app/features/agent/types.d.ts +9 -0
  13. package/dist/modules/agent/runtime/app/helpers/index.d.ts +7 -3
  14. package/dist/modules/agent/runtime/app/helpers/index.js +9 -3
  15. package/dist/modules/agent/runtime/app/prompts/fixReadability.js +51 -44
  16. package/dist/modules/agent/runtime/app/tools/add_media_paragraph/index.js +2 -1
  17. package/dist/modules/agent/runtime/app/tools/check_readability/index.js +1 -0
  18. package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Component.vue +1 -1
  19. package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/index.js +6 -1
  20. package/dist/modules/agent/runtime/app/tools/get_readability_issues/index.js +1 -0
  21. package/dist/modules/agent/runtime/app/types/index.d.ts +12 -0
  22. package/dist/modules/charts/runtime/components/ChartRenderer/index.vue +34 -18
  23. package/dist/modules/drupal/graphql/base/fragment.paragraphsBlokkliEditState.graphql +7 -0
  24. package/dist/modules/drupal/graphql/features/droppable-field-items.graphql +22 -0
  25. package/dist/modules/drupal/graphql/features/import-existing.graphql +0 -25
  26. package/dist/modules/drupal/graphql/features/workspace.graphql +9 -2
  27. package/dist/modules/drupal/graphql/mutations/update_droppable_field.graphql +21 -0
  28. package/dist/modules/drupal/index.mjs +6 -2
  29. package/dist/modules/drupal/runtime/adapter/index.js +75 -39
  30. package/dist/modules/readability/index.d.mts +11 -0
  31. package/dist/modules/readability/index.mjs +17 -0
  32. package/dist/modules/readability/runtime/adapter-extension.d.ts +2 -0
  33. package/dist/modules/readability/runtime/adapter-extension.js +5 -0
  34. package/dist/modules/readability/runtime/analyzers/builtin.d.ts +10 -0
  35. package/dist/modules/readability/runtime/analyzers/builtin.js +340 -0
  36. package/dist/runtime/components/BlokkliEditable.vue +10 -90
  37. package/dist/runtime/components/BlokkliItem.vue +2 -2
  38. package/dist/runtime/components/BlokkliProvider.vue +11 -5
  39. package/dist/runtime/composables/defineBlokkli.js +3 -1
  40. package/dist/runtime/composables/defineBlokkliFeature.d.ts +2 -3
  41. package/dist/runtime/editor/components/Actions/index.vue +1 -1
  42. package/dist/runtime/editor/components/AnimationCanvas/index.vue +41 -6
  43. package/dist/runtime/editor/components/AppMenu/Inner.d.vue.ts +7 -0
  44. package/dist/runtime/editor/components/AppMenu/Inner.vue +83 -0
  45. package/dist/runtime/editor/components/AppMenu/Inner.vue.d.ts +7 -0
  46. package/dist/runtime/editor/components/AppMenu/index.vue +5 -79
  47. package/dist/runtime/editor/components/ArtboardTooltip/index.d.vue.ts +1 -0
  48. package/dist/runtime/editor/components/ArtboardTooltip/index.vue +9 -1
  49. package/dist/runtime/editor/components/ArtboardTooltip/index.vue.d.ts +1 -0
  50. package/dist/runtime/editor/components/BlockPreviewItem/index.vue +12 -6
  51. package/dist/runtime/editor/components/BlokkliEditableEdit.d.vue.ts +23 -0
  52. package/dist/runtime/editor/components/BlokkliEditableEdit.vue +95 -0
  53. package/dist/runtime/editor/components/BlokkliEditableEdit.vue.d.ts +23 -0
  54. package/dist/runtime/editor/components/BlokkliRootErrorBoundary.d.vue.ts +4 -1
  55. package/dist/runtime/editor/components/BlokkliRootErrorBoundary.vue +4 -1
  56. package/dist/runtime/editor/components/BlokkliRootErrorBoundary.vue.d.ts +4 -1
  57. package/dist/runtime/editor/components/BundleSelector/index.vue +10 -5
  58. package/dist/runtime/editor/components/Dialog/index.vue +0 -77
  59. package/dist/runtime/editor/components/EditIndicator.d.vue.ts +1 -0
  60. package/dist/runtime/editor/components/EditIndicator.vue +3 -2
  61. package/dist/runtime/editor/components/EditIndicator.vue.d.ts +1 -0
  62. package/dist/runtime/editor/components/EditProvider.d.vue.ts +3 -1
  63. package/dist/runtime/editor/components/EditProvider.vue +13 -4
  64. package/dist/runtime/editor/components/EditProvider.vue.d.ts +3 -1
  65. package/dist/runtime/editor/components/FeaturesRenderer/index.vue +1 -4
  66. package/dist/runtime/editor/components/Form/Text/index.d.vue.ts +5 -0
  67. package/dist/runtime/editor/components/Form/Text/index.vue +10 -4
  68. package/dist/runtime/editor/components/Form/Text/index.vue.d.ts +5 -0
  69. package/dist/runtime/editor/components/FormOverlay/index.vue +0 -24
  70. package/dist/runtime/editor/components/GrowOnly/index.d.vue.ts +10 -0
  71. package/dist/runtime/editor/components/GrowOnly/index.vue +34 -0
  72. package/dist/runtime/editor/components/GrowOnly/index.vue.d.ts +10 -0
  73. package/dist/runtime/editor/components/Konami/Game/index.vue +120 -0
  74. package/dist/runtime/editor/components/Konami/index.vue +7 -124
  75. package/dist/runtime/editor/components/Loading/index.vue +1 -1
  76. package/dist/runtime/editor/components/PluginConfigForm/Text/index.vue +1 -0
  77. package/dist/runtime/editor/components/PluginConfigForm/index.vue +1 -0
  78. package/dist/runtime/editor/components/PreviewProvider.d.vue.ts +3 -1
  79. package/dist/runtime/editor/components/PreviewProvider.vue +6 -1
  80. package/dist/runtime/editor/components/PreviewProvider.vue.d.ts +3 -1
  81. package/dist/runtime/editor/components/Toolbar/index.vue +1 -1
  82. package/dist/runtime/editor/components/index.d.ts +11 -10
  83. package/dist/runtime/editor/components/index.js +32 -10
  84. package/dist/runtime/editor/composables/defineRenderer.d.ts +2 -2
  85. package/dist/runtime/editor/composables/defineRenderer.js +8 -3
  86. package/dist/runtime/editor/css/output.css +1 -1
  87. package/dist/runtime/editor/events/index.d.ts +6 -0
  88. package/dist/runtime/editor/features/analyze/Main.d.vue.ts +1 -0
  89. package/dist/runtime/editor/features/analyze/Main.vue +9 -8
  90. package/dist/runtime/editor/features/analyze/Main.vue.d.ts +1 -0
  91. package/dist/runtime/editor/features/analyze/Results/ResultsItem.vue +7 -15
  92. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodesTarget.vue +4 -2
  93. package/dist/runtime/editor/features/analyze/analyzers/axe.js +9 -9
  94. package/dist/runtime/editor/features/analyze/analyzers/readability.js +7 -7
  95. package/dist/runtime/editor/features/analyze/index.vue +26 -26
  96. package/dist/runtime/editor/features/analyze/readability/types.d.ts +18 -14
  97. package/dist/runtime/editor/features/anchors/index.vue +6 -2
  98. package/dist/runtime/editor/features/artboard/Renderer.vue +3 -2
  99. package/dist/runtime/editor/features/block-scheduler/Dialog/index.vue +78 -0
  100. package/dist/runtime/editor/features/block-scheduler/index.vue +34 -89
  101. package/dist/runtime/editor/features/breadcrumbs/index.vue +2 -2
  102. package/dist/runtime/editor/features/changelog/changelog.json +8 -0
  103. package/dist/runtime/editor/features/changelog/index.vue +10 -8
  104. package/dist/runtime/editor/features/clipboard/DropElement/index.vue +152 -0
  105. package/dist/runtime/editor/features/clipboard/index.vue +13 -159
  106. package/dist/runtime/editor/features/command-palette/Palette/Item/index.vue +0 -28
  107. package/dist/runtime/editor/features/command-palette/Palette/index.vue +17 -6
  108. package/dist/runtime/editor/features/command-palette/index.vue +7 -2
  109. package/dist/runtime/editor/features/comments/index.vue +6 -3
  110. package/dist/runtime/editor/features/debug/Main.vue +168 -0
  111. package/dist/runtime/editor/features/debug/Section/Features.vue +1 -2
  112. package/dist/runtime/editor/features/debug/index.vue +6 -170
  113. package/dist/runtime/editor/features/dev-mode/index.vue +2 -1
  114. package/dist/runtime/editor/features/diff/index.vue +6 -2
  115. package/dist/runtime/editor/features/dragging-overlay/Renderer/index.vue +15 -16
  116. package/dist/runtime/editor/features/dragging-overlay/index.vue +4 -3
  117. package/dist/runtime/editor/features/droppable-field-edit/Overlay/index.d.vue.ts +15 -0
  118. package/dist/runtime/editor/features/droppable-field-edit/Overlay/index.vue +547 -0
  119. package/dist/runtime/editor/features/droppable-field-edit/Overlay/index.vue.d.ts +15 -0
  120. package/dist/runtime/editor/features/droppable-field-edit/index.d.vue.ts +3 -0
  121. package/dist/runtime/editor/features/droppable-field-edit/index.vue +231 -0
  122. package/dist/runtime/editor/features/droppable-field-edit/index.vue.d.ts +3 -0
  123. package/dist/runtime/editor/features/droppable-field-edit/types.d.ts +70 -0
  124. package/dist/runtime/editor/features/editable-field/Overlay/Frame/index.d.vue.ts +1 -0
  125. package/dist/runtime/editor/features/editable-field/Overlay/Frame/index.vue +34 -21
  126. package/dist/runtime/editor/features/editable-field/Overlay/Frame/index.vue.d.ts +1 -0
  127. package/dist/runtime/editor/features/editable-field/Overlay/Plaintext/index.d.vue.ts +2 -2
  128. package/dist/runtime/editor/features/editable-field/Overlay/Plaintext/index.vue.d.ts +2 -2
  129. package/dist/runtime/editor/features/editable-field/Overlay/ReadabilityIndicator/ChunkOverlay.vue +1 -1
  130. package/dist/runtime/editor/features/editable-field/Overlay/ReadabilityIndicator/index.vue +6 -13
  131. package/dist/runtime/editor/features/editable-field/Overlay/index.vue +4 -4
  132. package/dist/runtime/editor/features/fragments/index.vue +9 -4
  133. package/dist/runtime/editor/features/help/index.vue +7 -2
  134. package/dist/runtime/editor/features/highlights/Renderer/index.vue +11 -17
  135. package/dist/runtime/editor/features/history/index.vue +3 -2
  136. package/dist/runtime/editor/features/hover/Renderer/index.vue +87 -36
  137. package/dist/runtime/editor/features/hover/Renderer/vertex.glsl +5 -5
  138. package/dist/runtime/editor/features/hover/index.vue +1 -1
  139. package/dist/runtime/editor/features/import-existing/Dialog/Item.d.vue.ts +5 -0
  140. package/dist/runtime/editor/features/import-existing/Dialog/Item.vue +55 -0
  141. package/dist/runtime/editor/features/import-existing/Dialog/Item.vue.d.ts +5 -0
  142. package/dist/runtime/editor/features/import-existing/Dialog/index.d.vue.ts +7 -3
  143. package/dist/runtime/editor/features/import-existing/Dialog/index.vue +107 -65
  144. package/dist/runtime/editor/features/import-existing/Dialog/index.vue.d.ts +7 -3
  145. package/dist/runtime/editor/features/import-existing/index.vue +19 -6
  146. package/dist/runtime/editor/features/import-existing/types.d.ts +0 -11
  147. package/dist/runtime/editor/features/library/ReusableDialog/index.vue +7 -33
  148. package/dist/runtime/editor/features/library/index.vue +14 -5
  149. package/dist/runtime/editor/features/media-library/Library/index.vue +3 -1
  150. package/dist/runtime/editor/features/media-library/index.vue +9 -2
  151. package/dist/runtime/editor/features/media-library/types.d.ts +2 -0
  152. package/dist/runtime/editor/features/multi-select/Renderer/index.vue +16 -15
  153. package/dist/runtime/editor/features/multi-select/index.vue +9 -3
  154. package/dist/runtime/editor/features/options/Form/Radios/index.vue +4 -8
  155. package/dist/runtime/editor/features/options/index.vue +7 -2
  156. package/dist/runtime/editor/features/preview-grant/index.vue +8 -2
  157. package/dist/runtime/editor/features/publish/index.vue +3 -2
  158. package/dist/runtime/editor/features/referenced-entities/index.vue +7 -2
  159. package/dist/runtime/editor/features/responsive-preview/index.vue +13 -11
  160. package/dist/runtime/editor/features/search/index.vue +6 -2
  161. package/dist/runtime/editor/features/selection/AddButtons/Renderer/index.vue +6 -11
  162. package/dist/runtime/editor/features/selection/Renderer/index.vue +9 -14
  163. package/dist/runtime/editor/features/selection/index.vue +7 -4
  164. package/dist/runtime/editor/features/settings/index.vue +8 -3
  165. package/dist/runtime/editor/features/structure/index.vue +3 -2
  166. package/dist/runtime/editor/features/templates/CreateDialog/index.vue +1 -0
  167. package/dist/runtime/editor/features/templates/index.vue +14 -6
  168. package/dist/runtime/editor/features/theme/index.vue +2 -1
  169. package/dist/runtime/editor/features/tour/index.vue +6 -2
  170. package/dist/runtime/editor/features/translations/index.vue +7 -4
  171. package/dist/runtime/editor/features/workspace/Overlay/Item.d.vue.ts +3 -0
  172. package/dist/runtime/editor/features/workspace/Overlay/Item.vue +49 -0
  173. package/dist/runtime/editor/features/workspace/Overlay/Item.vue.d.ts +3 -0
  174. package/dist/runtime/editor/features/workspace/Overlay/index.vue +16 -104
  175. package/dist/runtime/editor/features/workspace/index.vue +6 -2
  176. package/dist/runtime/editor/helpers/webgl/index.d.ts +3 -2
  177. package/dist/runtime/editor/helpers/webgl/index.js +2 -3
  178. package/dist/runtime/editor/libraries/fzf.d.ts +3 -0
  179. package/dist/runtime/editor/libraries/fzf.js +7 -0
  180. package/dist/runtime/editor/libraries/twgl.d.ts +10 -0
  181. package/dist/runtime/editor/libraries/twgl.js +14 -0
  182. package/dist/runtime/editor/plugins/DebugOverlay/index.vue +3 -1
  183. package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue +39 -18
  184. package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +2 -0
  185. package/dist/runtime/editor/plugins/Sidebar/index.vue +12 -4
  186. package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +2 -0
  187. package/dist/runtime/editor/providers/animation.d.ts +5 -10
  188. package/dist/runtime/editor/providers/animation.js +10 -8
  189. package/dist/runtime/editor/providers/directive.d.ts +11 -0
  190. package/dist/runtime/editor/providers/directive.js +16 -0
  191. package/dist/runtime/editor/providers/features.d.ts +3 -3
  192. package/dist/runtime/editor/providers/features.js +1 -1
  193. package/dist/runtime/editor/providers/fieldValue.d.ts +27 -0
  194. package/dist/runtime/editor/providers/fieldValue.js +21 -1
  195. package/dist/runtime/editor/providers/keyboard.js +6 -3
  196. package/dist/runtime/editor/providers/readability.d.ts +28 -4
  197. package/dist/runtime/editor/providers/readability.js +30 -46
  198. package/dist/runtime/editor/providers/selection.d.ts +8 -0
  199. package/dist/runtime/editor/providers/selection.js +6 -0
  200. package/dist/runtime/editor/providers/texts.d.ts +1 -3
  201. package/dist/runtime/editor/providers/texts.js +34 -37
  202. package/dist/runtime/editor/providers/workspaces.d.ts +93 -0
  203. package/dist/runtime/editor/providers/workspaces.js +76 -0
  204. package/dist/runtime/editor/translations/de.json +918 -3616
  205. package/dist/runtime/editor/translations/fr.json +250 -3616
  206. package/dist/runtime/editor/translations/gsw_CH.json +918 -3616
  207. package/dist/runtime/editor/translations/it.json +250 -3616
  208. package/dist/runtime/editor/types/app.d.ts +2 -0
  209. package/dist/runtime/editor/types/features.d.ts +1 -1
  210. package/dist/runtime/editor/types/state.d.ts +7 -0
  211. package/dist/runtime/helpers/injections.d.ts +6 -0
  212. package/dist/runtime/helpers/injections.js +3 -0
  213. package/dist/runtime/types/definitions.d.ts +4 -0
  214. package/package.json +14 -4
  215. package/dist/runtime/editor/features/analyze/readability/builtinAnalyzer.d.ts +0 -6
  216. package/dist/runtime/editor/features/analyze/readability/builtinAnalyzer.js +0 -216
  217. package/dist/runtime/editor/features/workspace/types.d.ts +0 -59
  218. /package/dist/runtime/editor/features/{workspace → droppable-field-edit}/types.js +0 -0
@@ -0,0 +1,547 @@
1
+ <template>
2
+ <ArtboardTooltip
3
+ id="droppable-field"
4
+ :title="title"
5
+ :anchor-el="element"
6
+ placement-y="top"
7
+ class="bk-droppable-field-edit"
8
+ close-icon="bk_mdi_check"
9
+ :close-disabled="!canConfirm"
10
+ @close="save"
11
+ >
12
+ <div
13
+ ref="listEl"
14
+ class="_bk_w-[680px] _bk_max-h-300 _bk_overflow-y-auto _bk_p-10 _bk_bg-mono-200"
15
+ @pointerup="onListPointerUp"
16
+ >
17
+ <GrowOnly class="_bk_bg-white">
18
+ <div
19
+ v-for="(item, i) in localItems"
20
+ :key="item.key"
21
+ class="_bk_grid _bk_grid-cols-[minmax(0,1fr)_auto] _bk_items-center _bk_relative _bk_border-b _bk_border-b-mono-200 _bk_last:border-b-0 _bk_bg-white"
22
+ >
23
+ <div
24
+ v-if="i === 0"
25
+ class="bk-droppable-field-edit-indicator _bk_col-span-2"
26
+ :class="{
27
+ 'bk-is-visible': dragIndex !== null && dragIndex !== 0 || showExternalDropTargets,
28
+ 'bk-is-active': activeIndicator === 0
29
+ }"
30
+ />
31
+ <div
32
+ class="_bk_flex _bk_items-center _bk_gap-5 _bk_px-8 _bk_py-5 _bk_cursor-grab _bk_touch-none _bk_active:cursor-grabbing _bk_bg-white"
33
+ :class="{ '_bk_opacity-30': dragIndex === i }"
34
+ @pointerdown="onPointerDown($event, i)"
35
+ >
36
+ <div
37
+ class="_bk_size-50 _bk_rounded _bk_overflow-hidden _bk_flex _bk_items-center _bk_justify-center _bk_bg-mono-100 _bk_shrink-0 _bk_[&_img]:size-full _bk_[&_img]:object-cover _bk_[&_svg]:size-18 _bk_[&_svg]:fill-current _bk_[&_svg]:text-mono-400"
38
+ >
39
+ <img v-if="item.thumbnailSrc" :src="item.thumbnailSrc" alt="" />
40
+ <Icon v-else name="bk_mdi_image" />
41
+ </div>
42
+ <span class="_bk_flex-1 _bk_min-w-0 _bk_truncate _bk_text-sm _bk_text-mono-800">
43
+ {{ item.label }}
44
+ </span>
45
+ </div>
46
+ <button
47
+ type="button"
48
+ class="_bk_size-25 _bk_mr-8 _bk_flex _bk_items-center _bk_justify-center _bk_rounded _bk_shrink-0 _bk_text-mono-400 _bk_hover:bg-red-light _bk_hover:text-red-dark _bk_disabled:opacity-30 _bk_disabled:pointer-events-none _bk_[&_svg]:size-[14px] _bk_[&_svg]:fill-current"
49
+ @click.stop.prevent="removeItem(i)"
50
+ >
51
+ <Icon name="bk_mdi_close" />
52
+ </button>
53
+ <div
54
+ class="bk-droppable-field-edit-indicator _bk_col-span-2"
55
+ :class="{
56
+ 'bk-is-visible': dragIndex !== null && i + 1 !== dragIndex && i + 1 !== dragIndex + 1 || showExternalDropTargets,
57
+ 'bk-is-active': activeIndicator === i + 1
58
+ }"
59
+ />
60
+ </div>
61
+
62
+ <div
63
+ v-if="canAddMore"
64
+ class="_bk_flex _bk_items-center _bk_gap-5 _bk_p-8 _bk_text-sm _bk_text-mono-400 _bk_[&_svg]:size-18 _bk_[&_svg]:fill-current _bk_[&_svg]:shrink-0"
65
+ >
66
+ <Icon name="bk_mdi_image" />
67
+ {{ $t("droppableFieldDropHint", "Drop image here") }}
68
+ </div>
69
+
70
+ <div
71
+ v-if="config.required && localItems.length === 0"
72
+ class="_bk_flex _bk_items-center _bk_gap-5 _bk_p-8 _bk_text-sm _bk_text-red-dark _bk_bg-red-light _bk_[&_svg]:size-18 _bk_[&_svg]:fill-current _bk_[&_svg]:shrink-0"
73
+ >
74
+ <Icon name="bk_mdi_warning" />
75
+ {{
76
+ $t(
77
+ "droppableFieldRequiredWarning",
78
+ "This field is required. Add an item before saving, or press Discard to abort."
79
+ )
80
+ }}
81
+ </div>
82
+ </GrowOnly>
83
+ </div>
84
+
85
+ <div class="bk-artboard-tooltip-info">
86
+ <button
87
+ class="bk-artboard-tooltip-info-button bk-scheme-red"
88
+ :disabled="!hasChanged"
89
+ @click.prevent="discard"
90
+ >
91
+ {{ $t("editableFieldDiscard", "Discard") }}
92
+ </button>
93
+ <button
94
+ :disabled="!undoStack.length"
95
+ class="bk-artboard-tooltip-info-button bk-scheme-mono _bk_relative _bk_group/tooltip"
96
+ @click.prevent="undo"
97
+ >
98
+ <Icon name="bk_mdi_undo" />
99
+ </button>
100
+ <button
101
+ :disabled="!redoStack.length"
102
+ class="bk-artboard-tooltip-info-button bk-scheme-mono _bk_relative _bk_group/tooltip"
103
+ @click.prevent="redo"
104
+ >
105
+ <Icon name="bk_mdi_redo" />
106
+ </button>
107
+ <div class="_bk_px-10 _bk_text-sm _bk_text-mono-600 _bk_mr-auto">
108
+ <template v-if="config.cardinality > 0">
109
+ {{
110
+ $t("droppableFieldRemaining", "@count remaining").replace(
111
+ "@count",
112
+ String(config.cardinality - localItems.length)
113
+ )
114
+ }}
115
+ </template>
116
+ <template v-else>
117
+ {{
118
+ $t("droppableFieldItemCount", "@count items").replace(
119
+ "@count",
120
+ String(localItems.length)
121
+ )
122
+ }}
123
+ </template>
124
+ </div>
125
+ <button
126
+ v-if="canAddMore"
127
+ class="bk-artboard-tooltip-info-button bk-scheme-mono _bk_relative _bk_group/tooltip"
128
+ :disabled="ui.hasSidebarLeft.value"
129
+ @click.prevent="onAddClick"
130
+ >
131
+ <Icon name="bk_mdi_image" />
132
+ {{ $t("droppableFieldOpenLibrary", "Media Library") }}
133
+ </button>
134
+ </div>
135
+ </ArtboardTooltip>
136
+ </template>
137
+
138
+ <script setup>
139
+ import { ArtboardTooltip, GrowOnly, Icon } from "#blokkli/editor/components";
140
+ import {
141
+ computed,
142
+ ref,
143
+ watch,
144
+ onMounted,
145
+ onBeforeUnmount,
146
+ useBlokkli,
147
+ useTemplateRef
148
+ } from "#imports";
149
+ import { onBlokkliEvent } from "#blokkli/editor/composables";
150
+ import { cloneWithInlineStyles } from "#blokkli/editor/helpers/dom";
151
+ const props = defineProps({
152
+ fieldName: { type: String, required: true },
153
+ entity: { type: Object, required: true },
154
+ element: { type: null, required: true },
155
+ config: { type: Object, required: true }
156
+ });
157
+ const emit = defineEmits(["close"]);
158
+ const { $t, adapter, state, eventBus, keyboard, selection, ui } = useBlokkli();
159
+ const localItems = ref([]);
160
+ const originalItems = ref([]);
161
+ const isClosing = ref(false);
162
+ const undoStack = ref([]);
163
+ const redoStack = ref([]);
164
+ const KEYBOARD_LOCK_ID = "droppable-field-edit";
165
+ function pushUndo() {
166
+ undoStack.value.push([...localItems.value]);
167
+ redoStack.value = [];
168
+ }
169
+ function undo() {
170
+ const prev = undoStack.value.pop();
171
+ if (prev) {
172
+ redoStack.value.push([...localItems.value]);
173
+ localItems.value = prev;
174
+ }
175
+ }
176
+ function redo() {
177
+ const next = redoStack.value.pop();
178
+ if (next) {
179
+ undoStack.value.push([...localItems.value]);
180
+ localItems.value = next;
181
+ }
182
+ }
183
+ function onKeyDown(e) {
184
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "z") {
185
+ e.preventDefault();
186
+ e.stopPropagation();
187
+ if (e.shiftKey) {
188
+ redo();
189
+ } else {
190
+ undo();
191
+ }
192
+ }
193
+ }
194
+ const dragIndex = ref(null);
195
+ const dropIndex = ref(null);
196
+ const externalDropIndex = ref(null);
197
+ const listEl = useTemplateRef("listEl");
198
+ const activeIndicator = computed(() => {
199
+ if (externalDropIndex.value !== null) return externalDropIndex.value;
200
+ if (dragIndex.value === null || dropIndex.value === null) return null;
201
+ if (isNoOpDrop(dragIndex.value, dropIndex.value)) return null;
202
+ return dropIndex.value;
203
+ });
204
+ const title = computed(
205
+ () => $t("droppableFieldEditLabel", "Edit @label").replace(
206
+ "@label",
207
+ props.config.label
208
+ )
209
+ );
210
+ const hasChanged = computed(() => {
211
+ if (localItems.value.length !== originalItems.value.length) return true;
212
+ return localItems.value.some((item, i) => {
213
+ const orig = originalItems.value[i];
214
+ if (!orig) return true;
215
+ return item.id !== orig.id;
216
+ });
217
+ });
218
+ const canAddMore = computed(() => {
219
+ if (props.config.cardinality === -1) {
220
+ return true;
221
+ }
222
+ return localItems.value.length < props.config.cardinality;
223
+ });
224
+ const canConfirm = computed(() => {
225
+ if (!hasChanged.value) return true;
226
+ return !(props.config.required && localItems.value.length === 0);
227
+ });
228
+ const host = computed(() => ({
229
+ type: props.entity.type,
230
+ uuid: props.entity.uuid,
231
+ fieldName: props.fieldName
232
+ }));
233
+ const showExternalDropTargets = computed(() => {
234
+ if (!selection.isDragging.value || !canAddMore.value) {
235
+ return false;
236
+ }
237
+ const items = selection.dragItems.value;
238
+ if (items.length !== 1) {
239
+ return false;
240
+ }
241
+ const item = items[0];
242
+ if (item.itemType !== "media_library") {
243
+ return false;
244
+ }
245
+ const allowedBundles = props.config.allowed.find(
246
+ (v) => v.type === "media"
247
+ )?.bundles;
248
+ return !!allowedBundles && allowedBundles.includes(item.mediaBundle);
249
+ });
250
+ watch(showExternalDropTargets, (active) => {
251
+ if (!active) {
252
+ externalDropIndex.value = null;
253
+ }
254
+ });
255
+ function onListPointerUp(e) {
256
+ if (!showExternalDropTargets.value) return;
257
+ const items = selection.dragItems.value;
258
+ if (items.length !== 1) return;
259
+ const item = items[0];
260
+ if (item.itemType !== "media_library") return;
261
+ const position = computeDropIndex(e.clientY);
262
+ eventBus.emit("dragging:end");
263
+ pushUndo();
264
+ const newItem = {
265
+ key: `new-${Date.now()}-${item.mediaId}`,
266
+ id: item.mediaId,
267
+ label: item.label,
268
+ thumbnailSrc: item.thumbnailSrc ?? null,
269
+ entityType: "media",
270
+ bundle: item.mediaBundle,
271
+ targetBundles: item.itemBundles
272
+ };
273
+ const newList = [...localItems.value];
274
+ newList.splice(position, 0, newItem);
275
+ localItems.value = newList;
276
+ }
277
+ async function loadItems() {
278
+ const items = await adapter.getDroppableFieldItems({ host: host.value });
279
+ localItems.value = items.map((item) => ({
280
+ key: item.id,
281
+ id: item.id,
282
+ label: item.label,
283
+ thumbnailSrc: item.thumbnailSrc ?? null,
284
+ entityType: item.entityType,
285
+ bundle: item.bundle,
286
+ targetBundles: item.targetBundles
287
+ }));
288
+ originalItems.value = [...localItems.value];
289
+ }
290
+ function isNoOpDrop(from, to) {
291
+ return to === from || to === from + 1;
292
+ }
293
+ function computeDropIndex(pointerY) {
294
+ if (!listEl.value) return 0;
295
+ const indicators = listEl.value.querySelectorAll(
296
+ ".bk-droppable-field-edit-indicator"
297
+ );
298
+ let closest = 0;
299
+ let closestDist = Infinity;
300
+ for (let i = 0; i < indicators.length; i++) {
301
+ const rect = indicators[i].getBoundingClientRect();
302
+ const y = rect.top + rect.height / 2;
303
+ const dist = Math.abs(pointerY - y);
304
+ if (dist < closestDist) {
305
+ closestDist = dist;
306
+ closest = i;
307
+ }
308
+ }
309
+ return closest;
310
+ }
311
+ let ghostEl = null;
312
+ let ghostOffsetX = 0;
313
+ let ghostOffsetY = 0;
314
+ let dragHandleEl = null;
315
+ let draggedOutIndex = null;
316
+ function removeGhost() {
317
+ if (ghostEl) {
318
+ ghostEl.remove();
319
+ ghostEl = null;
320
+ }
321
+ }
322
+ function isPointerOutsideList(x, y) {
323
+ const rect = listEl.value?.getBoundingClientRect();
324
+ if (!rect) return false;
325
+ return x < rect.left || x > rect.right || y < rect.top || y > rect.bottom;
326
+ }
327
+ function createGhost(from, x, y) {
328
+ const rect = from.getBoundingClientRect();
329
+ const clone = cloneWithInlineStyles(from);
330
+ clone.style.position = "fixed";
331
+ clone.style.left = `${x - ghostOffsetX}px`;
332
+ clone.style.top = `${y - ghostOffsetY}px`;
333
+ clone.style.width = `${rect.width}px`;
334
+ clone.style.pointerEvents = "none";
335
+ clone.style.zIndex = "999999";
336
+ clone.style.background = "white";
337
+ clone.style.opacity = "0.8";
338
+ document.body.appendChild(clone);
339
+ ghostEl = clone;
340
+ }
341
+ function beginDragOut(x, y) {
342
+ if (dragIndex.value === null || !dragHandleEl) return;
343
+ const index = dragIndex.value;
344
+ const item = localItems.value[index];
345
+ if (!item) return;
346
+ removeGhost();
347
+ dragIndex.value = null;
348
+ dropIndex.value = null;
349
+ draggedOutIndex = index;
350
+ const source = dragHandleEl;
351
+ eventBus.emit("dragging:start", {
352
+ items: [
353
+ {
354
+ itemType: "droppable_field_item",
355
+ element: () => source,
356
+ itemBundles: item.targetBundles,
357
+ entityId: item.id,
358
+ entityType: item.entityType,
359
+ entityBundle: item.bundle,
360
+ label: item.label,
361
+ thumbnailSrc: item.thumbnailSrc ?? void 0
362
+ }
363
+ ],
364
+ coords: { x, y },
365
+ mode: "mouse"
366
+ });
367
+ }
368
+ function resumeInternalDrag(x, y) {
369
+ if (draggedOutIndex === null || !dragHandleEl) return;
370
+ const index = draggedOutIndex;
371
+ draggedOutIndex = null;
372
+ eventBus.emit("dragging:end");
373
+ dragIndex.value = index;
374
+ dropIndex.value = computeDropIndex(y);
375
+ createGhost(dragHandleEl, x, y);
376
+ }
377
+ const BOUNDARY_HYSTERESIS_MS = 500;
378
+ let pendingSwitch = null;
379
+ let lastPointerX = 0;
380
+ let lastPointerY = 0;
381
+ function cancelPendingSwitch() {
382
+ if (pendingSwitch !== null) {
383
+ clearTimeout(pendingSwitch);
384
+ pendingSwitch = null;
385
+ }
386
+ }
387
+ function onPointerMove(e) {
388
+ lastPointerX = e.clientX;
389
+ lastPointerY = e.clientY;
390
+ if (dragIndex.value !== null) {
391
+ const outside = isPointerOutsideList(e.clientX, e.clientY);
392
+ if (outside) {
393
+ if (pendingSwitch === null) {
394
+ pendingSwitch = setTimeout(() => {
395
+ pendingSwitch = null;
396
+ beginDragOut(lastPointerX, lastPointerY);
397
+ }, BOUNDARY_HYSTERESIS_MS);
398
+ }
399
+ } else {
400
+ cancelPendingSwitch();
401
+ }
402
+ dropIndex.value = computeDropIndex(e.clientY);
403
+ if (ghostEl) {
404
+ ghostEl.style.left = `${e.clientX - ghostOffsetX}px`;
405
+ ghostEl.style.top = `${e.clientY - ghostOffsetY}px`;
406
+ }
407
+ return;
408
+ }
409
+ if (draggedOutIndex !== null) {
410
+ const inside = !isPointerOutsideList(e.clientX, e.clientY);
411
+ if (inside) {
412
+ if (pendingSwitch === null) {
413
+ pendingSwitch = setTimeout(() => {
414
+ pendingSwitch = null;
415
+ resumeInternalDrag(lastPointerX, lastPointerY);
416
+ }, BOUNDARY_HYSTERESIS_MS);
417
+ }
418
+ } else {
419
+ cancelPendingSwitch();
420
+ }
421
+ return;
422
+ }
423
+ if (showExternalDropTargets.value) {
424
+ externalDropIndex.value = computeDropIndex(e.clientY);
425
+ }
426
+ }
427
+ function onDocumentPointerUp() {
428
+ document.removeEventListener("pointerup", onDocumentPointerUp);
429
+ cancelPendingSwitch();
430
+ removeGhost();
431
+ if (dragIndex.value === null || dropIndex.value === null) {
432
+ dragIndex.value = null;
433
+ dropIndex.value = null;
434
+ return;
435
+ }
436
+ const from = dragIndex.value;
437
+ let to = dropIndex.value;
438
+ if (!isNoOpDrop(from, to)) {
439
+ pushUndo();
440
+ const items = [...localItems.value];
441
+ const [item] = items.splice(from, 1);
442
+ if (to > from) {
443
+ to--;
444
+ }
445
+ items.splice(to, 0, item);
446
+ localItems.value = items;
447
+ }
448
+ dragIndex.value = null;
449
+ dropIndex.value = null;
450
+ }
451
+ function onPointerDown(e, index) {
452
+ if (e.button !== 0) {
453
+ return;
454
+ }
455
+ e.preventDefault();
456
+ const target = e.currentTarget;
457
+ if (!(target instanceof HTMLElement)) {
458
+ return;
459
+ }
460
+ const rect = target.getBoundingClientRect();
461
+ ghostOffsetX = e.clientX - rect.left;
462
+ ghostOffsetY = e.clientY - rect.top;
463
+ dragHandleEl = target;
464
+ dragIndex.value = index;
465
+ dropIndex.value = index;
466
+ createGhost(target, e.clientX, e.clientY);
467
+ document.addEventListener("pointerup", onDocumentPointerUp);
468
+ }
469
+ function removeItem(index) {
470
+ pushUndo();
471
+ localItems.value = localItems.value.filter((_, i) => i !== index);
472
+ }
473
+ function onAddClick() {
474
+ eventBus.emit("sidebar:open", "media_library");
475
+ }
476
+ async function save() {
477
+ if (isClosing.value) {
478
+ return;
479
+ }
480
+ if (!canConfirm.value) {
481
+ return;
482
+ }
483
+ isClosing.value = true;
484
+ if (hasChanged.value) {
485
+ const itemIds = localItems.value.map((item) => item.id);
486
+ await state.mutateWithLoadingState(
487
+ () => adapter.updateDroppableField({ host: host.value, itemIds }),
488
+ $t("droppableFieldSaveFailed", "Failed to save field.")
489
+ );
490
+ }
491
+ emit("close");
492
+ }
493
+ function discard() {
494
+ if (isClosing.value) {
495
+ return;
496
+ }
497
+ isClosing.value = true;
498
+ emit("close");
499
+ }
500
+ onBlokkliEvent("window:clickAway", () => {
501
+ if (selection.isDragging.value) {
502
+ return;
503
+ }
504
+ save();
505
+ });
506
+ onBlokkliEvent("dragging:end", () => {
507
+ draggedOutIndex = null;
508
+ cancelPendingSwitch();
509
+ });
510
+ onMounted(() => {
511
+ keyboard.lockKeyboardEvents(KEYBOARD_LOCK_ID);
512
+ document.addEventListener("keydown", onKeyDown, true);
513
+ document.addEventListener("pointermove", onPointerMove);
514
+ loadItems();
515
+ });
516
+ onBeforeUnmount(() => {
517
+ keyboard.unlockKeyboardEvents(KEYBOARD_LOCK_ID);
518
+ document.removeEventListener("keydown", onKeyDown, true);
519
+ document.removeEventListener("pointermove", onPointerMove);
520
+ document.removeEventListener("pointerup", onDocumentPointerUp);
521
+ cancelPendingSwitch();
522
+ removeGhost();
523
+ });
524
+ </script>
525
+
526
+ <style>
527
+ .bk.bk-droppable-field-edit {
528
+ --bk-bg: white;
529
+ --bk-header-bg: rgb(var(--bk-theme-teal-normal) / 1);
530
+ --bk-header-text: rgb(var(--bk-theme-teal-dark) / 1);
531
+ --bk-border: rgb(var(--bk-theme-teal-normal) / 1);
532
+ --bk-header-hover: rgb(var(--bk-theme-teal-dark) / 0.2);
533
+ }
534
+
535
+ .bk.bk-droppable-field-edit .bk-droppable-field-edit-indicator {
536
+ height: 4px;
537
+ }
538
+
539
+ .bk.bk-droppable-field-edit .bk-droppable-field-edit-indicator.bk-is-visible {
540
+ background-color: rgb(var(--bk-theme-teal-normal) / 0.3);
541
+ }
542
+
543
+ .bk.bk-droppable-field-edit .bk-droppable-field-edit-indicator.bk-is-active {
544
+ --bk-tw-bg-opacity: 1;
545
+ background-color: rgb(var(--bk-theme-teal-normal) / var(--bk-tw-bg-opacity, 1));
546
+ }
547
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { EntityContext } from '#blokkli/types';
2
+ import type { DroppableFieldConfig } from '#blokkli/editor/features/editable-field/types';
3
+ type __VLS_Props = {
4
+ fieldName: string;
5
+ entity: EntityContext;
6
+ element: HTMLElement;
7
+ config: DroppableFieldConfig;
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
+ close: () => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ onClose?: (() => any) | undefined;
13
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const _default: typeof __VLS_export;
2
+ export default _default;
3
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;