@blokkli/editor 2.0.0-alpha.54 → 2.0.0-alpha.56

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 (214) 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/index.d.ts +11 -10
  82. package/dist/runtime/editor/components/index.js +32 -10
  83. package/dist/runtime/editor/composables/defineRenderer.d.ts +2 -2
  84. package/dist/runtime/editor/composables/defineRenderer.js +8 -3
  85. package/dist/runtime/editor/css/output.css +1 -1
  86. package/dist/runtime/editor/events/index.d.ts +6 -0
  87. package/dist/runtime/editor/features/analyze/Main.d.vue.ts +1 -0
  88. package/dist/runtime/editor/features/analyze/Main.vue +9 -8
  89. package/dist/runtime/editor/features/analyze/Main.vue.d.ts +1 -0
  90. package/dist/runtime/editor/features/analyze/Results/ResultsItem.vue +7 -15
  91. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodesTarget.vue +4 -2
  92. package/dist/runtime/editor/features/analyze/analyzers/axe.js +9 -9
  93. package/dist/runtime/editor/features/analyze/analyzers/readability.js +7 -7
  94. package/dist/runtime/editor/features/analyze/index.vue +26 -26
  95. package/dist/runtime/editor/features/analyze/readability/types.d.ts +18 -14
  96. package/dist/runtime/editor/features/anchors/index.vue +6 -2
  97. package/dist/runtime/editor/features/artboard/Renderer.vue +3 -2
  98. package/dist/runtime/editor/features/block-scheduler/Dialog/index.vue +78 -0
  99. package/dist/runtime/editor/features/block-scheduler/index.vue +34 -89
  100. package/dist/runtime/editor/features/breadcrumbs/index.vue +2 -2
  101. package/dist/runtime/editor/features/changelog/changelog.json +8 -0
  102. package/dist/runtime/editor/features/changelog/index.vue +10 -8
  103. package/dist/runtime/editor/features/clipboard/DropElement/index.vue +152 -0
  104. package/dist/runtime/editor/features/clipboard/index.vue +13 -159
  105. package/dist/runtime/editor/features/command-palette/Palette/Item/index.vue +0 -28
  106. package/dist/runtime/editor/features/command-palette/Palette/index.vue +17 -6
  107. package/dist/runtime/editor/features/command-palette/index.vue +7 -2
  108. package/dist/runtime/editor/features/comments/index.vue +6 -3
  109. package/dist/runtime/editor/features/debug/Main.vue +168 -0
  110. package/dist/runtime/editor/features/debug/Section/Features.vue +1 -2
  111. package/dist/runtime/editor/features/debug/index.vue +6 -170
  112. package/dist/runtime/editor/features/dev-mode/index.vue +2 -1
  113. package/dist/runtime/editor/features/diff/index.vue +6 -2
  114. package/dist/runtime/editor/features/dragging-overlay/Renderer/index.vue +15 -16
  115. package/dist/runtime/editor/features/dragging-overlay/index.vue +4 -3
  116. package/dist/runtime/editor/features/droppable-field-edit/Overlay/index.d.vue.ts +15 -0
  117. package/dist/runtime/editor/features/droppable-field-edit/Overlay/index.vue +547 -0
  118. package/dist/runtime/editor/features/droppable-field-edit/Overlay/index.vue.d.ts +15 -0
  119. package/dist/runtime/editor/features/droppable-field-edit/index.d.vue.ts +3 -0
  120. package/dist/runtime/editor/features/droppable-field-edit/index.vue +231 -0
  121. package/dist/runtime/editor/features/droppable-field-edit/index.vue.d.ts +3 -0
  122. package/dist/runtime/editor/features/droppable-field-edit/types.d.ts +70 -0
  123. package/dist/runtime/editor/features/editable-field/Overlay/Plaintext/index.d.vue.ts +2 -2
  124. package/dist/runtime/editor/features/editable-field/Overlay/Plaintext/index.vue.d.ts +2 -2
  125. package/dist/runtime/editor/features/editable-field/Overlay/ReadabilityIndicator/ChunkOverlay.vue +1 -1
  126. package/dist/runtime/editor/features/editable-field/Overlay/ReadabilityIndicator/index.vue +6 -13
  127. package/dist/runtime/editor/features/editable-field/Overlay/index.vue +3 -4
  128. package/dist/runtime/editor/features/fragments/index.vue +9 -4
  129. package/dist/runtime/editor/features/help/index.vue +7 -2
  130. package/dist/runtime/editor/features/highlights/Renderer/index.vue +11 -17
  131. package/dist/runtime/editor/features/history/index.vue +3 -2
  132. package/dist/runtime/editor/features/hover/Renderer/index.vue +87 -36
  133. package/dist/runtime/editor/features/hover/Renderer/vertex.glsl +5 -5
  134. package/dist/runtime/editor/features/hover/index.vue +1 -1
  135. package/dist/runtime/editor/features/import-existing/Dialog/Item.d.vue.ts +5 -0
  136. package/dist/runtime/editor/features/import-existing/Dialog/Item.vue +55 -0
  137. package/dist/runtime/editor/features/import-existing/Dialog/Item.vue.d.ts +5 -0
  138. package/dist/runtime/editor/features/import-existing/Dialog/index.d.vue.ts +7 -3
  139. package/dist/runtime/editor/features/import-existing/Dialog/index.vue +107 -65
  140. package/dist/runtime/editor/features/import-existing/Dialog/index.vue.d.ts +7 -3
  141. package/dist/runtime/editor/features/import-existing/index.vue +19 -6
  142. package/dist/runtime/editor/features/import-existing/types.d.ts +0 -11
  143. package/dist/runtime/editor/features/library/ReusableDialog/index.vue +7 -33
  144. package/dist/runtime/editor/features/library/index.vue +14 -5
  145. package/dist/runtime/editor/features/media-library/Library/index.vue +3 -1
  146. package/dist/runtime/editor/features/media-library/index.vue +9 -2
  147. package/dist/runtime/editor/features/media-library/types.d.ts +2 -0
  148. package/dist/runtime/editor/features/multi-select/Renderer/index.vue +16 -15
  149. package/dist/runtime/editor/features/multi-select/index.vue +9 -3
  150. package/dist/runtime/editor/features/options/Form/Radios/index.vue +4 -8
  151. package/dist/runtime/editor/features/options/index.vue +7 -2
  152. package/dist/runtime/editor/features/preview-grant/index.vue +8 -2
  153. package/dist/runtime/editor/features/publish/index.vue +3 -2
  154. package/dist/runtime/editor/features/referenced-entities/index.vue +7 -2
  155. package/dist/runtime/editor/features/responsive-preview/index.vue +13 -11
  156. package/dist/runtime/editor/features/search/index.vue +6 -2
  157. package/dist/runtime/editor/features/selection/AddButtons/Renderer/index.vue +6 -11
  158. package/dist/runtime/editor/features/selection/Renderer/index.vue +9 -14
  159. package/dist/runtime/editor/features/selection/index.vue +7 -4
  160. package/dist/runtime/editor/features/settings/index.vue +8 -3
  161. package/dist/runtime/editor/features/structure/index.vue +3 -2
  162. package/dist/runtime/editor/features/templates/CreateDialog/index.vue +1 -0
  163. package/dist/runtime/editor/features/templates/index.vue +14 -6
  164. package/dist/runtime/editor/features/theme/index.vue +2 -1
  165. package/dist/runtime/editor/features/tour/index.vue +6 -2
  166. package/dist/runtime/editor/features/translations/index.vue +7 -4
  167. package/dist/runtime/editor/features/workspace/Overlay/Item.d.vue.ts +3 -0
  168. package/dist/runtime/editor/features/workspace/Overlay/Item.vue +49 -0
  169. package/dist/runtime/editor/features/workspace/Overlay/Item.vue.d.ts +3 -0
  170. package/dist/runtime/editor/features/workspace/Overlay/index.vue +16 -104
  171. package/dist/runtime/editor/features/workspace/index.vue +6 -2
  172. package/dist/runtime/editor/helpers/webgl/index.d.ts +3 -2
  173. package/dist/runtime/editor/helpers/webgl/index.js +2 -3
  174. package/dist/runtime/editor/libraries/fzf.d.ts +3 -0
  175. package/dist/runtime/editor/libraries/fzf.js +7 -0
  176. package/dist/runtime/editor/libraries/twgl.d.ts +10 -0
  177. package/dist/runtime/editor/libraries/twgl.js +14 -0
  178. package/dist/runtime/editor/plugins/DebugOverlay/index.vue +3 -1
  179. package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue +39 -18
  180. package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +2 -0
  181. package/dist/runtime/editor/plugins/Sidebar/index.vue +12 -4
  182. package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +2 -0
  183. package/dist/runtime/editor/providers/animation.d.ts +5 -10
  184. package/dist/runtime/editor/providers/animation.js +10 -8
  185. package/dist/runtime/editor/providers/directive.d.ts +11 -0
  186. package/dist/runtime/editor/providers/directive.js +16 -0
  187. package/dist/runtime/editor/providers/features.d.ts +3 -3
  188. package/dist/runtime/editor/providers/features.js +1 -1
  189. package/dist/runtime/editor/providers/fieldValue.d.ts +27 -0
  190. package/dist/runtime/editor/providers/fieldValue.js +21 -1
  191. package/dist/runtime/editor/providers/keyboard.js +6 -3
  192. package/dist/runtime/editor/providers/readability.d.ts +28 -4
  193. package/dist/runtime/editor/providers/readability.js +30 -46
  194. package/dist/runtime/editor/providers/selection.d.ts +8 -0
  195. package/dist/runtime/editor/providers/selection.js +6 -0
  196. package/dist/runtime/editor/providers/texts.d.ts +1 -3
  197. package/dist/runtime/editor/providers/texts.js +34 -37
  198. package/dist/runtime/editor/providers/workspaces.d.ts +93 -0
  199. package/dist/runtime/editor/providers/workspaces.js +76 -0
  200. package/dist/runtime/editor/translations/de.json +918 -3616
  201. package/dist/runtime/editor/translations/fr.json +250 -3616
  202. package/dist/runtime/editor/translations/gsw_CH.json +918 -3616
  203. package/dist/runtime/editor/translations/it.json +250 -3616
  204. package/dist/runtime/editor/types/app.d.ts +2 -0
  205. package/dist/runtime/editor/types/features.d.ts +1 -1
  206. package/dist/runtime/editor/types/state.d.ts +7 -0
  207. package/dist/runtime/helpers/injections.d.ts +6 -0
  208. package/dist/runtime/helpers/injections.js +3 -0
  209. package/dist/runtime/types/definitions.d.ts +4 -0
  210. package/package.json +14 -4
  211. package/dist/runtime/editor/features/analyze/readability/builtinAnalyzer.d.ts +0 -6
  212. package/dist/runtime/editor/features/analyze/readability/builtinAnalyzer.js +0 -216
  213. package/dist/runtime/editor/features/workspace/types.d.ts +0 -59
  214. /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>;