@blokkli/editor 1.0.4 → 1.1.1
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.
- package/dist/module.json +1 -1
- package/dist/module.mjs +345 -16
- package/dist/runtime/adapter/drupal/graphql/base.graphql +2 -1
- package/dist/runtime/adapter/drupal/graphqlMiddleware.js +4 -1
- package/dist/runtime/adapter/index.d.ts +12 -1
- package/dist/runtime/blokkliPlugins/Sidebar/Detached/index.vue +41 -39
- package/dist/runtime/blokkliPlugins/Sidebar/index.vue +10 -16
- package/dist/runtime/blokkliPlugins/ViewOption/index.vue +2 -0
- package/dist/runtime/components/BlokkliField.vue +75 -17
- package/dist/runtime/components/BlokkliItem.vue +34 -6
- package/dist/runtime/components/BlokkliProvider.vue +18 -1
- package/dist/runtime/components/Edit/BlockProxy/index.vue +102 -0
- package/dist/runtime/components/Edit/DragInteractions/index.vue +49 -25
- package/dist/runtime/components/Edit/DraggableList.vue +140 -30
- package/dist/runtime/components/Edit/EditProvider.vue +4 -0
- package/dist/runtime/components/Edit/Features/AddList/index.vue +3 -0
- package/dist/runtime/components/Edit/Features/Artboard/Overview/index.vue +111 -0
- package/dist/runtime/components/Edit/Features/Artboard/Scrollbar/index.vue +47 -0
- package/dist/runtime/components/Edit/Features/Artboard/index.vue +301 -9
- package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +29 -4
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +3 -4
- package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +27 -0
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +24 -3
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/fragment.glsl +56 -24
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +184 -29
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/vertex.glsl +36 -16
- package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +4 -0
- package/dist/runtime/components/Edit/Features/Duplicate/index.vue +1 -13
- package/dist/runtime/components/Edit/Features/EditableMask/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/History/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/Options/Form/Checkbox/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Options/Form/Checkboxes/index.vue +28 -25
- package/dist/runtime/components/Edit/Features/Options/Form/Color/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +67 -39
- package/dist/runtime/components/Edit/Features/Options/Form/Number/index.vue +6 -2
- package/dist/runtime/components/Edit/Features/Options/Form/Radios/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/Options/Form/Range/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Options/Form/Text/index.vue +2 -1
- package/dist/runtime/components/Edit/Features/Options/Form/index.vue +83 -33
- package/dist/runtime/components/Edit/Features/ProxyView/index.vue +38 -0
- package/dist/runtime/components/Edit/Features/Publish/index.vue +53 -6
- package/dist/runtime/components/Edit/Features/Search/Overlay/index.vue +3 -13
- package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/Settings/Dialog/index.vue +2 -0
- package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +3 -3
- package/dist/runtime/components/Edit/Features/Structure/index.vue +3 -3
- package/dist/runtime/components/Edit/ScrollBoundary/index.vue +24 -0
- package/dist/runtime/components/Edit/index.d.ts +2 -1
- package/dist/runtime/components/Edit/index.js +3 -1
- package/dist/runtime/composables/defineBlokkli.js +10 -5
- package/dist/runtime/constants/index.d.ts +1 -1
- package/dist/runtime/constants/index.js +6 -1
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/animationProvider.js +10 -4
- package/dist/runtime/helpers/domProvider.d.ts +12 -4
- package/dist/runtime/helpers/domProvider.js +70 -26
- package/dist/runtime/helpers/featuresProvider.d.ts +1 -1
- package/dist/runtime/helpers/runtimeHelpers/index.d.ts +6 -0
- package/dist/runtime/helpers/runtimeHelpers/index.js +25 -0
- package/dist/runtime/helpers/selectionProvider.d.ts +2 -1
- package/dist/runtime/helpers/selectionProvider.js +7 -8
- package/dist/runtime/helpers/symbols.d.ts +7 -0
- package/dist/runtime/helpers/symbols.js +7 -0
- package/dist/runtime/helpers/typesProvider.d.ts +1 -1
- package/dist/runtime/helpers/uiProvider.d.ts +1 -0
- package/dist/runtime/helpers/uiProvider.js +16 -3
- package/dist/runtime/helpers/webgl/index.d.ts +6 -1
- package/dist/runtime/helpers/webgl/index.js +38 -5
- package/dist/runtime/icons/eye.svg +1 -0
- package/dist/runtime/types/generatedModuleTypes.d.ts +12 -4
- package/dist/runtime/types/index.d.ts +30 -1
- package/package.json +7 -5
- package/dist/runtime/components/Edit/Features/Artboard/Manager/Artboard.d.ts +0 -204
- package/dist/runtime/components/Edit/Features/Artboard/Manager/Artboard.js +0 -748
- package/dist/runtime/components/Edit/Features/Artboard/Manager/Scrollbar/index.vue +0 -176
- package/dist/runtime/components/Edit/Features/Artboard/Manager/index.vue +0 -317
- package/dist/runtime/helpers/Artboard/index.d.ts +0 -16
- package/dist/runtime/helpers/Artboard/index.js +0 -20
|
@@ -3,13 +3,19 @@
|
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
falsy,
|
|
8
|
+
getDistance,
|
|
9
|
+
getInteractionCoordinates,
|
|
10
|
+
isInsideRect,
|
|
11
|
+
} from '#blokkli/helpers'
|
|
7
12
|
import onBlokkliEvent from '#blokkli/helpers/composables/onBlokkliEvent'
|
|
8
13
|
import type { Coord, Rectangle } from '#blokkli/types'
|
|
9
14
|
import { watch, ref, useBlokkli, onMounted, onBeforeUnmount } from '#imports'
|
|
10
15
|
|
|
11
|
-
const { dom, eventBus, selection, keyboard, ui,
|
|
12
|
-
|
|
16
|
+
const { dom, eventBus, selection, keyboard, ui, state } = useBlokkli()
|
|
17
|
+
|
|
18
|
+
const rootEl = ui.rootElement()
|
|
13
19
|
|
|
14
20
|
const rects = ref<{ uuid: string; rect: Rectangle }[]>([])
|
|
15
21
|
|
|
@@ -93,17 +99,36 @@ function getInteractedElement(
|
|
|
93
99
|
return { editableFieldName, uuid, timestamp: Date.now(), x, y }
|
|
94
100
|
}
|
|
95
101
|
|
|
102
|
+
// Try to find a block to select by matching its rects.
|
|
103
|
+
// Some blocks might not render anything and thus have a height of 0.
|
|
104
|
+
// All registered block rects enfore a minimum height. That way we might
|
|
105
|
+
// still be able to select a block.
|
|
106
|
+
const visibleUuids = dom.getVisibleBlocks()
|
|
107
|
+
for (let i = 0; i < visibleUuids.length; i++) {
|
|
108
|
+
const rect = dom.getBlockRect(visibleUuids[i])
|
|
109
|
+
if (rect) {
|
|
110
|
+
const relativeRect = ui.getViewportRelativeRect(rect)
|
|
111
|
+
if (isInsideRect(x, y, relativeRect)) {
|
|
112
|
+
return {
|
|
113
|
+
uuid: visibleUuids[i],
|
|
114
|
+
timestamp: Date.now(),
|
|
115
|
+
x,
|
|
116
|
+
y,
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
96
122
|
return null
|
|
97
123
|
}
|
|
98
124
|
|
|
99
125
|
function onPointerMove(e: PointerEvent) {
|
|
100
|
-
e.preventDefault()
|
|
101
|
-
e.stopPropagation()
|
|
102
|
-
e.stopImmediatePropagation()
|
|
103
|
-
animation.setMouseCoords(e.clientX, e.clientY)
|
|
104
126
|
if (keyboard.isPressingSpace.value || state.editMode.value !== 'editing') {
|
|
105
127
|
return
|
|
106
128
|
}
|
|
129
|
+
e.preventDefault()
|
|
130
|
+
e.stopPropagation()
|
|
131
|
+
e.stopImmediatePropagation()
|
|
107
132
|
if (e.pointerType === 'touch') {
|
|
108
133
|
return onTouchMove(e)
|
|
109
134
|
}
|
|
@@ -150,6 +175,7 @@ function onPointerMove(e: PointerEvent) {
|
|
|
150
175
|
}
|
|
151
176
|
|
|
152
177
|
let pointerDownTimestamp = 0
|
|
178
|
+
let pointerUpTimestamp = 0
|
|
153
179
|
|
|
154
180
|
function onPointerDown(e: PointerEvent) {
|
|
155
181
|
if (!keyboard.isPressingSpace.value) {
|
|
@@ -158,6 +184,9 @@ function onPointerDown(e: PointerEvent) {
|
|
|
158
184
|
e.stopImmediatePropagation()
|
|
159
185
|
}
|
|
160
186
|
|
|
187
|
+
rootEl.removeEventListener('pointermove', onPointerMove)
|
|
188
|
+
rootEl.addEventListener('pointermove', onPointerMove)
|
|
189
|
+
|
|
161
190
|
if (e.pointerType === 'touch') {
|
|
162
191
|
return onTouchStart(e)
|
|
163
192
|
}
|
|
@@ -171,17 +200,19 @@ function onPointerDown(e: PointerEvent) {
|
|
|
171
200
|
|
|
172
201
|
pointerDownTimestamp = Date.now()
|
|
173
202
|
const coords = { x: e.clientX, y: e.clientY }
|
|
203
|
+
mouseStartCoordinates = coords
|
|
174
204
|
|
|
175
205
|
const interacted = getInteractedElement(e)
|
|
176
206
|
pointerDownElement = interacted
|
|
177
207
|
if (interacted) {
|
|
178
208
|
return
|
|
179
209
|
}
|
|
180
|
-
|
|
210
|
+
|
|
181
211
|
eventBus.emit('mouse:down', { ...coords, type: 'mouse', distance: 0 })
|
|
182
212
|
}
|
|
183
213
|
|
|
184
214
|
function onPointerUp(e: PointerEvent) {
|
|
215
|
+
rootEl.removeEventListener('pointermove', onPointerMove)
|
|
185
216
|
e.preventDefault()
|
|
186
217
|
e.stopPropagation()
|
|
187
218
|
e.stopImmediatePropagation()
|
|
@@ -223,11 +254,12 @@ function onPointerUp(e: PointerEvent) {
|
|
|
223
254
|
// Handle double clicking.
|
|
224
255
|
if (
|
|
225
256
|
clicked &&
|
|
257
|
+
pointerUpTimestamp &&
|
|
226
258
|
lastInteractedElement &&
|
|
227
259
|
(clicked.uuid === lastInteractedElement.uuid ||
|
|
228
260
|
clicked.editableFieldName === lastInteractedElement.editableFieldName)
|
|
229
261
|
) {
|
|
230
|
-
const deltaTime = Date.now() -
|
|
262
|
+
const deltaTime = Date.now() - pointerUpTimestamp
|
|
231
263
|
const deltaX = Math.abs(lastInteractedElement.x - e.clientX)
|
|
232
264
|
const deltaY = Math.abs(lastInteractedElement.y - e.clientY)
|
|
233
265
|
if (deltaTime < 400 && deltaX < 3 && deltaY < 3) {
|
|
@@ -248,6 +280,7 @@ function onPointerUp(e: PointerEvent) {
|
|
|
248
280
|
}
|
|
249
281
|
}
|
|
250
282
|
lastInteractedElement = clicked
|
|
283
|
+
pointerUpTimestamp = Date.now()
|
|
251
284
|
if (clicked?.uuid) {
|
|
252
285
|
dom.refreshBlockRect(clicked.uuid)
|
|
253
286
|
if (keyboard.isPressingControl.value || selection.isMultiSelecting.value) {
|
|
@@ -387,51 +420,42 @@ function onClick(e: MouseEvent) {
|
|
|
387
420
|
}
|
|
388
421
|
|
|
389
422
|
onMounted(() => {
|
|
390
|
-
const el = ui.rootElement()
|
|
391
423
|
const providerElement = ui.providerElement()
|
|
392
424
|
|
|
393
425
|
providerElement.addEventListener('click', onClick, {
|
|
394
426
|
capture: true,
|
|
395
427
|
})
|
|
396
428
|
|
|
397
|
-
|
|
429
|
+
rootEl.addEventListener('click', onClick, {
|
|
398
430
|
capture: true,
|
|
399
431
|
})
|
|
400
432
|
|
|
401
|
-
|
|
433
|
+
rootEl.addEventListener('pointerdown', onPointerDown, {
|
|
402
434
|
capture: true,
|
|
403
435
|
})
|
|
404
436
|
|
|
405
|
-
|
|
406
|
-
capture: true,
|
|
407
|
-
})
|
|
408
|
-
|
|
409
|
-
el.addEventListener('pointerup', onPointerUp, {
|
|
437
|
+
rootEl.addEventListener('pointerup', onPointerUp, {
|
|
410
438
|
capture: true,
|
|
411
439
|
})
|
|
412
440
|
})
|
|
413
441
|
|
|
414
442
|
onBeforeUnmount(() => {
|
|
415
|
-
const el = ui.rootElement()
|
|
416
443
|
const providerElement = ui.providerElement()
|
|
417
444
|
|
|
418
445
|
providerElement.removeEventListener('click', onClick, {
|
|
419
446
|
capture: true,
|
|
420
447
|
})
|
|
421
448
|
|
|
422
|
-
|
|
423
|
-
capture: true,
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
el.removeEventListener('pointerdown', onPointerDown, {
|
|
449
|
+
rootEl.removeEventListener('click', onClick, {
|
|
427
450
|
capture: true,
|
|
428
451
|
})
|
|
429
452
|
|
|
430
|
-
|
|
453
|
+
rootEl.removeEventListener('pointerdown', onPointerDown, {
|
|
431
454
|
capture: true,
|
|
432
455
|
})
|
|
456
|
+
rootEl.removeEventListener('pointermove', onPointerMove)
|
|
433
457
|
|
|
434
|
-
|
|
458
|
+
rootEl.removeEventListener('pointerup', onPointerUp, {
|
|
435
459
|
capture: true,
|
|
436
460
|
})
|
|
437
461
|
})
|
|
@@ -1,22 +1,54 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-if="proxyMode || globalProxyMode"
|
|
4
|
+
class="bk bk-field-list-proxy"
|
|
5
|
+
:class="[
|
|
6
|
+
{
|
|
7
|
+
'bk-is-visible': proxyVisible,
|
|
8
|
+
},
|
|
9
|
+
'bk-is-' +
|
|
10
|
+
(dropAlignment || (nestingLevel === 0 ? 'vertical' : 'horizontal')),
|
|
11
|
+
]"
|
|
12
|
+
>
|
|
13
|
+
<div
|
|
14
|
+
ref="root"
|
|
15
|
+
class="bk-field-list-proxy-list bk-draggable-list-container"
|
|
16
|
+
v-bind="fieldAttributes"
|
|
17
|
+
>
|
|
18
|
+
<BlokkliItem
|
|
19
|
+
v-for="(item, i) in list"
|
|
20
|
+
:key="item.uuid + fieldListType"
|
|
21
|
+
:uuid="item.uuid"
|
|
22
|
+
:bundle="item.bundle"
|
|
23
|
+
:is-new="item.isNew"
|
|
24
|
+
:options="item.options"
|
|
25
|
+
:props="item.props"
|
|
26
|
+
is-editing
|
|
27
|
+
:index="i"
|
|
28
|
+
:parent-type="isNested ? entity.bundle : ''"
|
|
29
|
+
data-editing="true"
|
|
30
|
+
data-element-type="existing"
|
|
31
|
+
:data-sortli-id="item.uuid"
|
|
32
|
+
:data-uuid="item.uuid"
|
|
33
|
+
:data-host-type="entity.type"
|
|
34
|
+
:data-host-bundle="entity.bundle"
|
|
35
|
+
:data-host-uuid="entity.uuid"
|
|
36
|
+
:data-item-bundle="item.bundle"
|
|
37
|
+
:data-host-field-name="name"
|
|
38
|
+
:data-host-field-list-type="fieldListType"
|
|
39
|
+
:data-is-nested="isNested"
|
|
40
|
+
:data-is-new="item.isNew"
|
|
41
|
+
:data-entity-type="runtimeConfig.itemEntityType"
|
|
42
|
+
:data-bk-is-muted="isMuted(item)"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
2
46
|
<Component
|
|
3
47
|
:is="tag"
|
|
48
|
+
v-else
|
|
4
49
|
ref="root"
|
|
5
|
-
class="bk-draggable-list-container"
|
|
6
|
-
|
|
7
|
-
:data-field-label="fieldConfig?.label"
|
|
8
|
-
:data-field-is-nested="isNested"
|
|
9
|
-
:data-host-entity-type="entity.type"
|
|
10
|
-
:data-host-entity-uuid="entity.uuid"
|
|
11
|
-
:data-host-entity-bundle="entity.bundle"
|
|
12
|
-
:data-field-key="fieldKey"
|
|
13
|
-
:data-field-drop-alignment="dropAlignment"
|
|
14
|
-
:data-allowed-fragments="
|
|
15
|
-
allowedFragments ? allowedFragments.join(',') : undefined
|
|
16
|
-
"
|
|
17
|
-
:data-field-allowed-bundles="allowedBundles"
|
|
18
|
-
:data-field-list-type="fieldListType"
|
|
19
|
-
:data-field-cardinality="fieldConfig?.cardinality"
|
|
50
|
+
:class="['bk-draggable-list-container', attrs.class]"
|
|
51
|
+
v-bind="fieldAttributes"
|
|
20
52
|
>
|
|
21
53
|
<BlokkliItem
|
|
22
54
|
v-for="(item, i) in list"
|
|
@@ -42,31 +74,71 @@
|
|
|
42
74
|
:data-is-nested="isNested"
|
|
43
75
|
:data-is-new="item.isNew"
|
|
44
76
|
:data-entity-type="runtimeConfig.itemEntityType"
|
|
77
|
+
:data-bk-is-muted="isMuted(item)"
|
|
45
78
|
/>
|
|
46
79
|
</Component>
|
|
47
80
|
</template>
|
|
48
81
|
|
|
49
82
|
<script lang="ts" setup>
|
|
50
|
-
import {
|
|
83
|
+
import {
|
|
84
|
+
computed,
|
|
85
|
+
useBlokkli,
|
|
86
|
+
ref,
|
|
87
|
+
onMounted,
|
|
88
|
+
onBeforeUnmount,
|
|
89
|
+
useAttrs,
|
|
90
|
+
provide,
|
|
91
|
+
watch,
|
|
92
|
+
} from '#imports'
|
|
51
93
|
import type { FieldListItem, EntityContext, FieldConfig } from '#blokkli/types'
|
|
52
94
|
import type { BlokkliFragmentName } from '#blokkli/definitions'
|
|
53
95
|
import BlokkliItem from './../BlokkliItem.vue'
|
|
96
|
+
import { isVisibleByOptions } from '#blokkli/helpers/runtimeHelpers'
|
|
97
|
+
import {
|
|
98
|
+
INJECT_FIELD_PROXY_MODE,
|
|
99
|
+
INJECT_IS_EDITING,
|
|
100
|
+
} from '#blokkli/helpers/symbols'
|
|
54
101
|
|
|
55
|
-
const { dom, types, runtimeConfig } = useBlokkli()
|
|
102
|
+
const { dom, types, runtimeConfig, selection } = useBlokkli()
|
|
56
103
|
|
|
57
104
|
const root = ref<HTMLElement | null>(null)
|
|
58
105
|
|
|
59
|
-
const props =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
106
|
+
const props = withDefaults(
|
|
107
|
+
defineProps<{
|
|
108
|
+
name: string
|
|
109
|
+
fieldKey: string
|
|
110
|
+
list: FieldListItem[]
|
|
111
|
+
entity: EntityContext
|
|
112
|
+
language?: string
|
|
113
|
+
tag?: string
|
|
114
|
+
isNested: boolean
|
|
115
|
+
fieldListType: string
|
|
116
|
+
allowedFragments?: BlokkliFragmentName[]
|
|
117
|
+
dropAlignment?: 'vertical' | 'horizontal'
|
|
118
|
+
proxyMode?: boolean
|
|
119
|
+
globalProxyMode?: boolean
|
|
120
|
+
nestingLevel: number
|
|
121
|
+
}>(),
|
|
122
|
+
{
|
|
123
|
+
tag: 'div',
|
|
124
|
+
allowedFragments: undefined,
|
|
125
|
+
dropAlignment: undefined,
|
|
126
|
+
language: undefined,
|
|
127
|
+
},
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
const attrs = useAttrs()
|
|
131
|
+
|
|
132
|
+
provide(INJECT_FIELD_PROXY_MODE, props.proxyMode)
|
|
133
|
+
provide(INJECT_IS_EDITING, true)
|
|
134
|
+
|
|
135
|
+
const proxyVisible = computed(
|
|
136
|
+
() =>
|
|
137
|
+
props.proxyMode &&
|
|
138
|
+
(selection.uuids.value.length ||
|
|
139
|
+
selection.isDragging.value ||
|
|
140
|
+
selection.isMultiSelecting.value),
|
|
141
|
+
)
|
|
70
142
|
|
|
71
143
|
const fieldConfig = computed<FieldConfig>(() => {
|
|
72
144
|
const match = types.getFieldConfig(
|
|
@@ -98,13 +170,51 @@ const allowedBundles = computed<string>(() => {
|
|
|
98
170
|
return bundles.join(',')
|
|
99
171
|
})
|
|
100
172
|
|
|
173
|
+
const fieldAttributes = computed(() => {
|
|
174
|
+
return {
|
|
175
|
+
'data-field-name': props.name,
|
|
176
|
+
'data-field-label': fieldConfig.value.label,
|
|
177
|
+
'data-field-is-nested': props.isNested,
|
|
178
|
+
'data-bk-nesting-level': props.nestingLevel,
|
|
179
|
+
'data-host-entity-type': props.entity.type,
|
|
180
|
+
'data-host-entity-uuid': props.entity.uuid,
|
|
181
|
+
'data-host-entity-bundle': props.entity.bundle,
|
|
182
|
+
'data-field-key': props.fieldKey,
|
|
183
|
+
'data-field-drop-alignment': props.dropAlignment,
|
|
184
|
+
'data-allowed-fragments': props.allowedFragments
|
|
185
|
+
? props.allowedFragments.join(',')
|
|
186
|
+
: undefined,
|
|
187
|
+
'data-field-allowed-bundles': allowedBundles.value,
|
|
188
|
+
'data-field-list-type': props.fieldListType,
|
|
189
|
+
'data-field-cardinality': fieldConfig.value.cardinality,
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
// @TODO: This should be handled differently to prevent constant updates in the
|
|
194
|
+
// component when the options change.
|
|
195
|
+
// Ideally this is handled as an overlay on top of the blocks, similar to how
|
|
196
|
+
// selection or multi-select works.
|
|
197
|
+
function isMuted(item?: FieldListItem) {
|
|
198
|
+
return !isVisibleByOptions(item, props.language)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
watch(root, function (newRoot) {
|
|
202
|
+
if (newRoot) {
|
|
203
|
+
dom.updateFieldElement(props.entity, props.name, newRoot)
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
|
|
101
207
|
onMounted(() => {
|
|
102
208
|
if (root.value) {
|
|
103
|
-
dom.registerField(props.entity
|
|
209
|
+
dom.registerField(props.entity, props.name, root.value)
|
|
104
210
|
}
|
|
105
211
|
})
|
|
106
212
|
|
|
107
213
|
onBeforeUnmount(() => {
|
|
108
|
-
dom.unregisterField(props.entity
|
|
214
|
+
dom.unregisterField(props.entity, props.name)
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
defineOptions({
|
|
218
|
+
inheritAttrs: false,
|
|
109
219
|
})
|
|
110
220
|
</script>
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
INJECT_EDIT_CONTEXT,
|
|
71
71
|
INJECT_EDIT_FIELD_LIST_COMPONENT,
|
|
72
72
|
INJECT_EDIT_LOGGER,
|
|
73
|
+
INJECT_GLOBAL_PROXY_MODE,
|
|
73
74
|
INJECT_IS_EDITING,
|
|
74
75
|
} from '#blokkli/helpers/symbols'
|
|
75
76
|
import type { AdapterContext } from '#blokkli/adapter'
|
|
@@ -211,4 +212,7 @@ provide<BlokkliApp>(INJECT_APP, {
|
|
|
211
212
|
dropAreas,
|
|
212
213
|
debug,
|
|
213
214
|
})
|
|
215
|
+
|
|
216
|
+
const isProxyMode = computed(() => ui.isProxyMode.value)
|
|
217
|
+
provide(INJECT_GLOBAL_PROXY_MODE, isProxyMode)
|
|
214
218
|
</script>
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="overviewEl"
|
|
4
|
+
class="bk bk-artboard-overview"
|
|
5
|
+
@touchstart.stop
|
|
6
|
+
@pointerdown.stop
|
|
7
|
+
@mousedown.stop
|
|
8
|
+
@mousemove.stop
|
|
9
|
+
>
|
|
10
|
+
<div ref="overviewArtboardEl" class="bk-artboard-overview-artboard">
|
|
11
|
+
<canvas ref="canvas" />
|
|
12
|
+
</div>
|
|
13
|
+
<div class="bk-artboard-overview-visible">
|
|
14
|
+
<button ref="overviewVisibleEl" />
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup lang="ts">
|
|
20
|
+
import { type Artboard, type ArtboardPlugin, overview } from 'artboard-deluxe'
|
|
21
|
+
import { onBeforeUnmount, onMounted, ref, useBlokkli, computed } from '#imports'
|
|
22
|
+
import onBlokkliEvent from '#blokkli/helpers/composables/onBlokkliEvent'
|
|
23
|
+
|
|
24
|
+
const props = defineProps<{
|
|
25
|
+
artboard: Artboard
|
|
26
|
+
}>()
|
|
27
|
+
|
|
28
|
+
const { theme, dom, ui, selection } = useBlokkli()
|
|
29
|
+
|
|
30
|
+
const overviewFillColor = computed(() => {
|
|
31
|
+
return theme.getColorString('mono', '500', 0.2)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const selectedColor = computed(() => {
|
|
35
|
+
return theme.getColorString('accent', '700', 1)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const overviewEl = ref<HTMLDivElement>()
|
|
39
|
+
const overviewArtboardEl = ref<HTMLDivElement>()
|
|
40
|
+
const overviewVisibleEl = ref<HTMLDivElement>()
|
|
41
|
+
const canvas = ref<HTMLCanvasElement>()
|
|
42
|
+
|
|
43
|
+
let pluginOverview: ArtboardPlugin | null = null
|
|
44
|
+
|
|
45
|
+
function updateCanvas() {
|
|
46
|
+
const ctx = canvas.value?.getContext('2d')
|
|
47
|
+
|
|
48
|
+
if (!ctx || !canvas.value || !overviewArtboardEl.value) {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const rect = overviewArtboardEl.value.getBoundingClientRect()
|
|
53
|
+
|
|
54
|
+
canvas.value.width = rect.width
|
|
55
|
+
canvas.value.height = rect.height
|
|
56
|
+
|
|
57
|
+
ctx.clearRect(0, 0, rect.width, rect.height)
|
|
58
|
+
|
|
59
|
+
const rects = Object.entries(dom.getBlockRects())
|
|
60
|
+
|
|
61
|
+
const scale = rect.width / ui.artboardSize.value.width
|
|
62
|
+
|
|
63
|
+
ctx.fillStyle = overviewFillColor.value
|
|
64
|
+
ctx.lineWidth = 1
|
|
65
|
+
ctx.strokeStyle = selectedColor.value
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < rects.length; i++) {
|
|
68
|
+
const [uuid, blockRect] = rects[i]
|
|
69
|
+
ctx.fillRect(
|
|
70
|
+
Math.round(blockRect.x * scale),
|
|
71
|
+
Math.round(blockRect.y * scale),
|
|
72
|
+
Math.round(blockRect.width * scale),
|
|
73
|
+
Math.round(blockRect.height * scale),
|
|
74
|
+
)
|
|
75
|
+
if (selection.isBlockSelected(uuid)) {
|
|
76
|
+
ctx.strokeRect(
|
|
77
|
+
Math.round(blockRect.x * scale) + 0.5,
|
|
78
|
+
Math.round(blockRect.y * scale) + 0.5,
|
|
79
|
+
Math.round(blockRect.width * scale),
|
|
80
|
+
Math.round(blockRect.height * scale),
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
onBlokkliEvent('animationFrame', updateCanvas)
|
|
87
|
+
|
|
88
|
+
onMounted(() => {
|
|
89
|
+
if (overviewEl.value && overviewArtboardEl.value && overviewVisibleEl.value) {
|
|
90
|
+
pluginOverview = props.artboard.addPlugin(
|
|
91
|
+
overview({
|
|
92
|
+
element: overviewEl.value,
|
|
93
|
+
artboardElement: overviewArtboardEl.value,
|
|
94
|
+
visibleAreaElement: overviewVisibleEl.value,
|
|
95
|
+
padding: 20,
|
|
96
|
+
autoHeight: true,
|
|
97
|
+
}),
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
onBeforeUnmount(() => {
|
|
103
|
+
if (pluginOverview) {
|
|
104
|
+
props.artboard.removePlugin(pluginOverview)
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
defineOptions({
|
|
109
|
+
name: 'ArtboardOverview',
|
|
110
|
+
})
|
|
111
|
+
</script>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Teleport to="body">
|
|
3
|
+
<div
|
|
4
|
+
class="bk bk-artboard-scrollbar"
|
|
5
|
+
:class="'bk-orientation-' + orientation"
|
|
6
|
+
>
|
|
7
|
+
<div ref="el">
|
|
8
|
+
<button ref="thumb" />
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
</Teleport>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { type Artboard, type ArtboardPlugin, scrollbar } from 'artboard-deluxe'
|
|
16
|
+
import { onBeforeUnmount, onMounted, ref } from '#imports'
|
|
17
|
+
|
|
18
|
+
const props = defineProps<{
|
|
19
|
+
artboard: Artboard
|
|
20
|
+
orientation: 'x' | 'y'
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
const el = ref<HTMLDivElement>()
|
|
24
|
+
const thumb = ref<HTMLButtonElement>()
|
|
25
|
+
let scrollbarPlugin: ArtboardPlugin | null = null
|
|
26
|
+
|
|
27
|
+
onMounted(() => {
|
|
28
|
+
if (el.value && thumb.value) {
|
|
29
|
+
const plugin = scrollbar({
|
|
30
|
+
element: el.value,
|
|
31
|
+
thumbElement: thumb.value,
|
|
32
|
+
orientation: props.orientation,
|
|
33
|
+
})
|
|
34
|
+
scrollbarPlugin = props.artboard.addPlugin(plugin)
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
onBeforeUnmount(() => {
|
|
39
|
+
if (scrollbarPlugin) {
|
|
40
|
+
props.artboard.removePlugin(scrollbarPlugin)
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
defineOptions({
|
|
45
|
+
name: 'ArtboardScrollbar',
|
|
46
|
+
})
|
|
47
|
+
</script>
|