@blokkli/editor 1.0.4 → 1.1.0

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 (77) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +334 -9
  3. package/dist/runtime/adapter/drupal/graphql/base.graphql +2 -1
  4. package/dist/runtime/adapter/drupal/graphqlMiddleware.js +4 -1
  5. package/dist/runtime/adapter/index.d.ts +12 -1
  6. package/dist/runtime/blokkliPlugins/Sidebar/Detached/index.vue +41 -39
  7. package/dist/runtime/blokkliPlugins/Sidebar/index.vue +10 -16
  8. package/dist/runtime/blokkliPlugins/ViewOption/index.vue +2 -0
  9. package/dist/runtime/components/BlokkliField.vue +75 -17
  10. package/dist/runtime/components/BlokkliItem.vue +34 -6
  11. package/dist/runtime/components/BlokkliProvider.vue +18 -1
  12. package/dist/runtime/components/Edit/BlockProxy/index.vue +102 -0
  13. package/dist/runtime/components/Edit/DragInteractions/index.vue +49 -25
  14. package/dist/runtime/components/Edit/DraggableList.vue +138 -28
  15. package/dist/runtime/components/Edit/EditProvider.vue +4 -0
  16. package/dist/runtime/components/Edit/Features/AddList/index.vue +3 -0
  17. package/dist/runtime/components/Edit/Features/Artboard/Overview/index.vue +111 -0
  18. package/dist/runtime/components/Edit/Features/Artboard/Scrollbar/index.vue +47 -0
  19. package/dist/runtime/components/Edit/Features/Artboard/index.vue +301 -9
  20. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +3 -4
  21. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +27 -0
  22. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +24 -3
  23. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/fragment.glsl +56 -24
  24. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +184 -29
  25. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/vertex.glsl +36 -16
  26. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +4 -0
  27. package/dist/runtime/components/Edit/Features/Duplicate/index.vue +1 -13
  28. package/dist/runtime/components/Edit/Features/EditableMask/index.vue +2 -2
  29. package/dist/runtime/components/Edit/Features/History/index.vue +1 -1
  30. package/dist/runtime/components/Edit/Features/Options/Form/Checkbox/index.vue +2 -2
  31. package/dist/runtime/components/Edit/Features/Options/Form/Checkboxes/index.vue +28 -25
  32. package/dist/runtime/components/Edit/Features/Options/Form/Color/index.vue +1 -1
  33. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +67 -39
  34. package/dist/runtime/components/Edit/Features/Options/Form/Number/index.vue +6 -2
  35. package/dist/runtime/components/Edit/Features/Options/Form/Radios/index.vue +1 -1
  36. package/dist/runtime/components/Edit/Features/Options/Form/Range/index.vue +2 -2
  37. package/dist/runtime/components/Edit/Features/Options/Form/Text/index.vue +2 -1
  38. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +83 -33
  39. package/dist/runtime/components/Edit/Features/ProxyView/index.vue +38 -0
  40. package/dist/runtime/components/Edit/Features/Publish/index.vue +53 -6
  41. package/dist/runtime/components/Edit/Features/Search/Overlay/index.vue +3 -13
  42. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +1 -1
  43. package/dist/runtime/components/Edit/Features/Settings/Dialog/index.vue +2 -0
  44. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +3 -3
  45. package/dist/runtime/components/Edit/Features/Structure/index.vue +3 -3
  46. package/dist/runtime/components/Edit/ScrollBoundary/index.vue +24 -0
  47. package/dist/runtime/components/Edit/index.d.ts +2 -1
  48. package/dist/runtime/components/Edit/index.js +3 -1
  49. package/dist/runtime/composables/defineBlokkli.js +10 -5
  50. package/dist/runtime/constants/index.d.ts +1 -1
  51. package/dist/runtime/constants/index.js +6 -1
  52. package/dist/runtime/css/output.css +1 -1
  53. package/dist/runtime/helpers/animationProvider.js +10 -4
  54. package/dist/runtime/helpers/domProvider.d.ts +4 -2
  55. package/dist/runtime/helpers/domProvider.js +42 -19
  56. package/dist/runtime/helpers/featuresProvider.d.ts +1 -1
  57. package/dist/runtime/helpers/runtimeHelpers/index.d.ts +6 -0
  58. package/dist/runtime/helpers/runtimeHelpers/index.js +25 -0
  59. package/dist/runtime/helpers/selectionProvider.d.ts +2 -1
  60. package/dist/runtime/helpers/selectionProvider.js +7 -8
  61. package/dist/runtime/helpers/symbols.d.ts +7 -0
  62. package/dist/runtime/helpers/symbols.js +7 -0
  63. package/dist/runtime/helpers/typesProvider.d.ts +1 -1
  64. package/dist/runtime/helpers/uiProvider.d.ts +1 -0
  65. package/dist/runtime/helpers/uiProvider.js +16 -3
  66. package/dist/runtime/helpers/webgl/index.d.ts +6 -1
  67. package/dist/runtime/helpers/webgl/index.js +38 -5
  68. package/dist/runtime/icons/eye.svg +1 -0
  69. package/dist/runtime/types/generatedModuleTypes.d.ts +12 -4
  70. package/dist/runtime/types/index.d.ts +30 -1
  71. package/package.json +7 -5
  72. package/dist/runtime/components/Edit/Features/Artboard/Manager/Artboard.d.ts +0 -204
  73. package/dist/runtime/components/Edit/Features/Artboard/Manager/Artboard.js +0 -748
  74. package/dist/runtime/components/Edit/Features/Artboard/Manager/Scrollbar/index.vue +0 -176
  75. package/dist/runtime/components/Edit/Features/Artboard/Manager/index.vue +0 -317
  76. package/dist/runtime/helpers/Artboard/index.d.ts +0 -16
  77. package/dist/runtime/helpers/Artboard/index.js +0 -20
@@ -1,176 +0,0 @@
1
- <template>
2
- <Teleport to="body">
3
- <div
4
- ref="scrollbarEl"
5
- class="bk bk-artboard-scrollbar"
6
- :class="[
7
- { 'bk-is-active': isDraggingThumb },
8
- 'bk-orientation-' + orientation,
9
- ]"
10
- @touchstart.prevent
11
- @mousedown.stop.prevent="onClickScrollbar"
12
- >
13
- <button ref="button" @mousedown.capture.prevent.stop="onThumbMouseDown" />
14
- </div>
15
- </Teleport>
16
- </template>
17
-
18
- <script lang="ts" setup>
19
- import onBlokkliEvent from '#blokkli/helpers/composables/onBlokkliEvent'
20
- import { ref, onBeforeUnmount, onMounted } from '#imports'
21
-
22
- const isDraggingThumb = ref(false)
23
-
24
- const props = defineProps<{
25
- padding: number
26
- offset: number
27
- rootSize: number
28
- artboardSize: number
29
- scale: number
30
- orientation: 'height' | 'width'
31
- }>()
32
-
33
- type ScrollbarOptions = {
34
- padding?: number
35
- orientation?: 'height' | 'width'
36
- }
37
-
38
- class Scrollbar {
39
- scrollStart = 0
40
- thumbStart = 0
41
- scrollbarSize = 0
42
- padding = 50
43
- offset = 0
44
- rootSize = 0
45
- artboardSize = 0
46
- scale = 1
47
- orientation: 'height' | 'width' = 'height'
48
-
49
- constructor(options?: ScrollbarOptions) {
50
- this.padding = options?.padding || this.padding
51
- this.orientation = options?.orientation || this.orientation
52
- }
53
-
54
- getMouseCoordinate(e: MouseEvent): number {
55
- return this.orientation === 'height' ? e.clientY : e.clientX
56
- }
57
- }
58
-
59
- const scrollbar = new Scrollbar(props)
60
-
61
- const scrollbarEl = ref<HTMLElement | null>(null)
62
- const button = ref<HTMLButtonElement | null>(null)
63
-
64
- const emit = defineEmits(['pageUp', 'pageDown', 'setOffset'])
65
-
66
- let scrollStart = 0
67
- let thumbStart = 0
68
- let scrollbarSize = 300
69
-
70
- const scrollTop = () =>
71
- Math.round(props.offset - props.rootSize + props.padding)
72
-
73
- // The scroll progress as a value from 0 to 1.
74
- const scrollProgress = () => Math.abs(scrollTop() / scrollSize())
75
- const thumbOffset = () => (scrollbarSize - scrollThumbSize()) * scrollProgress()
76
-
77
- const scrollSize = () =>
78
- props.artboardSize * props.scale + props.rootSize - 2 * props.padding
79
-
80
- const scrollThumbSize = () => (props.rootSize / scrollSize()) * props.rootSize
81
-
82
- function onThumbMouseDown(e: MouseEvent) {
83
- isDraggingThumb.value = true
84
- scrollStart = scrollbar.getMouseCoordinate(e)
85
- thumbStart = thumbOffset()
86
- document.body.addEventListener('mouseup', onMouseUp, {
87
- passive: false,
88
- capture: true,
89
- })
90
- document.body.addEventListener('mousemove', onThumbMouseMove, {
91
- passive: false,
92
- capture: true,
93
- })
94
- }
95
-
96
- function onMouseUp() {
97
- isDraggingThumb.value = false
98
- document.body.removeEventListener('mousemove', onThumbMouseMove, {
99
- capture: true,
100
- })
101
- document.body.removeEventListener('mouseup', onMouseUp, {
102
- capture: true,
103
- })
104
- }
105
-
106
- function getOffsetFromThumb(newThumb: number): number {
107
- const maxThumb = scrollbarSize - scrollThumbSize()
108
- const newScrollProgress = newThumb / maxThumb
109
- const newScrollOffset = newScrollProgress * scrollSize()
110
- return newScrollOffset + props.rootSize - props.padding
111
- }
112
-
113
- function onThumbMouseMove(e: MouseEvent) {
114
- const diff = scrollStart - scrollbar.getMouseCoordinate(e)
115
- const newThumb = Math.max(
116
- Math.min(-thumbStart + diff, 0),
117
- -(scrollbarSize - scrollThumbSize()),
118
- )
119
- emit('setOffset', getOffsetFromThumb(newThumb))
120
- }
121
-
122
- function getStyle() {
123
- const offset = thumbOffset()
124
- const size = scrollThumbSize()
125
- if (props.orientation === 'height') {
126
- return {
127
- height: size + 'px',
128
- transform: `translateY(${offset}px)`,
129
- }
130
- }
131
- return {
132
- width: size + 'px',
133
- transform: `translateX(${offset}px)`,
134
- }
135
- }
136
-
137
- function onClickScrollbar(e: MouseEvent) {
138
- if (e.offsetY < thumbOffset()) {
139
- emit('pageUp')
140
- } else {
141
- emit('pageDown')
142
- }
143
- }
144
-
145
- const observer = new ResizeObserver((entries) => {
146
- const size = entries[0]?.contentBoxSize?.[0]
147
- if (!size) {
148
- return
149
- }
150
-
151
- scrollbarSize =
152
- props.orientation === 'height' ? size.blockSize : size.inlineSize
153
- })
154
-
155
- onBlokkliEvent('animationFrame', () => {
156
- if (!button.value) {
157
- return
158
- }
159
-
160
- const style = getStyle()
161
-
162
- button.value.style.width = style.width || ''
163
- button.value.style.height = style.height || ''
164
- button.value.style.transform = style.transform
165
- })
166
-
167
- onMounted(() => {
168
- if (scrollbarEl.value) {
169
- observer.observe(scrollbarEl.value)
170
- }
171
- })
172
-
173
- onBeforeUnmount(() => {
174
- observer.disconnect()
175
- })
176
- </script>
@@ -1,317 +0,0 @@
1
- <template>
2
- <PluginToolbarButton
3
- id="artboard_reset_zoom"
4
- :title="$t('artboardResetZoom', 'Reset zoom')"
5
- :shortcut-group="$t('artboard', 'Artboard')"
6
- :tour-text="
7
- $t(
8
- 'artboardToolbarButtonTourText',
9
- 'Shows the current zoom factor. Click on it to reset the zoom back to 100%.',
10
- )
11
- "
12
- icon="magnifier"
13
- meta
14
- key-code="0"
15
- region="view-options"
16
- weight="10"
17
- @click="resetZoom"
18
- >
19
- <div class="bk-feature-canvas-button">
20
- <span>{{ zoomLevel }}</span>
21
- </div>
22
- </PluginToolbarButton>
23
-
24
- <Scrollbar
25
- :padding="props.padding"
26
- :offset="ui.artboardOffset.value.y"
27
- :root-size="ui.viewport.value.height"
28
- :artboard-size="ui.artboardSize.value.height"
29
- :scale="ui.artboardScale.value"
30
- orientation="height"
31
- @page-down="onPageDown"
32
- @page-up="onPageUp"
33
- @set-offset="setOffset('y', $event)"
34
- />
35
-
36
- <Scrollbar
37
- :padding="props.padding"
38
- :offset="ui.artboardOffset.value.x"
39
- :root-size="ui.viewport.value.width"
40
- :artboard-size="ui.artboardSize.value.width"
41
- :scale="ui.artboardScale.value"
42
- orientation="width"
43
- @page-down="onPageDown"
44
- @page-up="onPageUp"
45
- @set-offset="setOffset('x', $event)"
46
- />
47
-
48
- <Teleport v-if="showDebug" to="body">
49
- <div class="bk-artboard-debug">
50
- <div v-for="v in debugValues" :key="v.key">
51
- <div>{{ v.key }}</div>
52
- <div>{{ v.value }}</div>
53
- </div>
54
- </div>
55
- </Teleport>
56
- </template>
57
-
58
- <script lang="ts" setup>
59
- import {
60
- ref,
61
- watch,
62
- computed,
63
- useBlokkli,
64
- onMounted,
65
- onBeforeUnmount,
66
- } from '#imports'
67
- import type { Coord } from '#blokkli/types'
68
- import { PluginToolbarButton } from '#blokkli/plugins'
69
- import Scrollbar from './Scrollbar/index.vue'
70
- import onBlokkliEvent from '#blokkli/helpers/composables/onBlokkliEvent'
71
- import defineShortcut from '#blokkli/helpers/composables/defineShortcut'
72
- import { Artboard, type ArtboardOptions } from './Artboard'
73
-
74
- const { context, storage, ui, animation, $t, dom } = useBlokkli()
75
-
76
- const zoomLevel = computed(() => Math.round(ui.artboardScale.value * 100) + '%')
77
-
78
- const showDebug = ref(false)
79
-
80
- const props = withDefaults(
81
- defineProps<{
82
- padding?: number
83
- minScale?: number
84
- maxScale?: number
85
- persist?: boolean
86
- scrollSpeed?: number
87
- }>(),
88
- {
89
- padding: 50,
90
- minScale: 0.05,
91
- maxScale: 3.5,
92
- scrollSpeed: 1,
93
- },
94
- )
95
-
96
- const options = computed<ArtboardOptions>(() => {
97
- return {
98
- maxScale: ui.isMobile.value ? 1 : 3,
99
- scrollSpeed: props.scrollSpeed,
100
- }
101
- })
102
-
103
- watch(options, function (newOptions) {
104
- artboard.setOptions(newOptions)
105
- })
106
-
107
- type SavedState = {
108
- offset: Coord
109
- scale: number
110
- }
111
- const storageKey = computed(() => 'artboard:' + context.value.entityUuid)
112
- const savedState = storage.use<SavedState | null>(storageKey, null)
113
-
114
- const saveState = () => {
115
- if (!props.persist) {
116
- return
117
- }
118
- savedState.value = { offset: artboard.offset, scale: artboard.scale }
119
- }
120
-
121
- function getArtboard(): Artboard {
122
- return new Artboard(ui.artboardElement(), ui.rootElement(), {
123
- x: savedState.value?.offset.x,
124
- y: savedState.value?.offset.y,
125
- scale: savedState.value?.scale,
126
- ...options.value,
127
- })
128
- }
129
-
130
- const artboard = getArtboard()
131
-
132
- function setOffset(key: 'x' | 'y', value: number) {
133
- artboard.stopAnimate()
134
- artboard.offset[key] = value
135
- }
136
-
137
- type DebugValue = {
138
- key: string
139
- value: string | number | boolean
140
- }
141
-
142
- const debugValues = ref<DebugValue[]>([])
143
-
144
- const coordToString = (v: Coord): string =>
145
- `x: ${Math.round(v.x)}, y: ${Math.round(v.y)}`
146
-
147
- onBlokkliEvent('animationFrame:before', () => {
148
- artboard.loop()
149
- ui.artboardSize.value.height = artboard.artboardSize.height
150
- ui.artboardSize.value.width = artboard.artboardSize.width
151
- // We don't need much precision here, so we can round it.
152
- // This also prevents updating rects in WebGL buffers for small changes.
153
- ui.artboardOffset.value.x = Math.round(artboard.offset.x)
154
- ui.artboardOffset.value.y = Math.round(artboard.offset.y)
155
- ui.artboardScale.value = artboard.scale
156
- animation.requestDraw()
157
- if (!showDebug.value) {
158
- return
159
- }
160
- debugValues.value = [
161
- {
162
- key: 'scale',
163
- value: artboard.scale.toString(),
164
- },
165
- {
166
- key: 'isScaling',
167
- value: artboard.isScaling,
168
- },
169
- {
170
- key: 'isDragging',
171
- value: artboard.isDragging,
172
- },
173
- {
174
- key: 'isTouching',
175
- value: artboard.isTouching,
176
- },
177
- {
178
- key: 'maxScale',
179
- value: artboard.maxScale,
180
- },
181
- {
182
- key: 'isMomentumScrolling',
183
- value: artboard.isMomentumScrolling,
184
- },
185
- {
186
- key: 'scaleMidpoint',
187
- value: artboard.scaleMidpoint
188
- ? coordToString(artboard.scaleMidpoint)
189
- : 'undefined',
190
- },
191
- ]
192
- })
193
-
194
- onMounted(() => {
195
- window.addEventListener('beforeunload', saveState)
196
- })
197
-
198
- onBeforeUnmount(() => {
199
- saveState()
200
- artboard.destroy()
201
- window.removeEventListener('beforeunload', saveState)
202
- })
203
-
204
- const resetZoom = () => {
205
- artboard.resetZoom()
206
- }
207
-
208
- function onPageUp() {
209
- artboard.scrollPageUp()
210
- animation.requestDraw()
211
- }
212
-
213
- function onPageDown() {
214
- artboard.scrollPageDown()
215
- animation.requestDraw()
216
- }
217
-
218
- onBlokkliEvent('keyPressed', (e) => {
219
- if (e.code === 'Home') {
220
- artboard.scrollToTop()
221
- animation.requestDraw()
222
- } else if (e.code === 'End') {
223
- artboard.scrollToEnd()
224
- animation.requestDraw()
225
- } else if (e.code === 'PageUp') {
226
- onPageUp()
227
- } else if (e.code === 'PageDown') {
228
- onPageDown()
229
- } else if (e.code === 'ArrowUp') {
230
- artboard.animateOrJumpBy(200)
231
- animation.requestDraw()
232
- } else if (e.code === 'ArrowDown') {
233
- artboard.animateOrJumpBy(-200)
234
- animation.requestDraw()
235
- } else if (e.code === '0' && e.meta) {
236
- artboard.resetZoom()
237
- animation.requestDraw()
238
- } else if (e.code === '1' && e.meta) {
239
- artboard.scaleToFit()
240
- animation.requestDraw()
241
- }
242
- })
243
-
244
- defineShortcut(
245
- [
246
- {
247
- code: 'Home',
248
- label: $t('artboardScrollToTop', 'Scroll to top'),
249
- },
250
- {
251
- code: 'End',
252
- label: $t('artboardScrollToEnd', 'Scroll to end'),
253
- },
254
- {
255
- code: 'PageUp',
256
- label: $t('artboardScrollOnePageUp', 'Scroll one page up'),
257
- },
258
- {
259
- code: 'PageDown',
260
- label: $t('artboardScrollOnePageDown', 'Scroll one page down'),
261
- },
262
- {
263
- code: 'ArrowUp',
264
- label: $t('artboardScrollUp', 'Scroll up'),
265
- },
266
- {
267
- code: 'ArrowDown',
268
- label: $t('artboardScrollDown', 'Scroll down'),
269
- },
270
- {
271
- code: '1',
272
- label: $t('artboardScaleToFit', 'Scale to fit'),
273
- meta: true,
274
- },
275
- ].map((v) => {
276
- return { ...v, group: $t('artboard', 'Artboard') }
277
- }),
278
- )
279
-
280
- onBlokkliEvent('scrollIntoView', (e) => {
281
- artboard.stopAnimate()
282
- const visible = dom.getBlockVisibilities()[e.uuid]
283
- if (visible) {
284
- return
285
- }
286
-
287
- const rect = dom.getBlockRect(e.uuid)
288
- if (!rect) {
289
- return
290
- }
291
-
292
- const rectY = rect.y * artboard.scale + artboard.offset.y
293
-
294
- let targetY: number | null = null
295
- const currentY = artboard.animationTarget?.y || artboard.offset.y
296
- const rootHeight = ui.visibleViewportPadded.value.height
297
-
298
- if (e.center) {
299
- targetY =
300
- currentY - rectY + props.padding + rootHeight / 2 - rect.height / 2
301
- } else if (rectY < 70) {
302
- targetY = currentY - (rectY - props.padding) + 70
303
- } else if (rectY + rect.height > rootHeight) {
304
- targetY = currentY + (rootHeight - (rectY + rect.height) - 40)
305
- }
306
-
307
- if (targetY) {
308
- artboard.setOffset(artboard.offset.x, targetY)
309
- }
310
- })
311
- </script>
312
-
313
- <script lang="ts">
314
- export default {
315
- name: 'ArtboardManager',
316
- }
317
- </script>
@@ -1,16 +0,0 @@
1
- type ArtboardOptions = {
2
- x?: number;
3
- y?: number;
4
- scale?: number;
5
- };
6
- export default class Artboard {
7
- el: HTMLElement;
8
- scale: number;
9
- x: number;
10
- y: number;
11
- height: number;
12
- width: number;
13
- constructor(el: HTMLElement, options?: ArtboardOptions);
14
- updateStyles(): void;
15
- }
16
- export {};
@@ -1,20 +0,0 @@
1
- export default class Artboard {
2
- el;
3
- scale;
4
- x;
5
- y;
6
- height;
7
- width;
8
- constructor(el, options) {
9
- this.el = el;
10
- this.scale = options?.scale || 0;
11
- this.x = options?.x || 0;
12
- this.y = options?.y || 0;
13
- this.height = el.offsetHeight;
14
- this.width = el.offsetWidth;
15
- }
16
- updateStyles() {
17
- this.el.style.scale = this.scale.toString();
18
- this.el.style.translate = `${Math.round(this.x)}px ${Math.round(this.y)}px`;
19
- }
20
- }