@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.
- package/dist/module.json +1 -1
- package/dist/module.mjs +334 -9
- 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 +138 -28
- 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/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 +4 -2
- package/dist/runtime/helpers/domProvider.js +42 -19
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Teleport to="body">
|
|
3
|
-
<slot :color="
|
|
3
|
+
<slot :color="activeColorHex" :label="active?.label" />
|
|
4
4
|
</Teleport>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
@@ -41,9 +41,15 @@ const props = defineProps<{
|
|
|
41
41
|
isTouch: boolean
|
|
42
42
|
}>()
|
|
43
43
|
|
|
44
|
+
const MIN_GAP = 20
|
|
45
|
+
|
|
44
46
|
enum RectRenderType {
|
|
45
|
-
FIELD,
|
|
46
47
|
DROP_AREA,
|
|
48
|
+
FIELD_1,
|
|
49
|
+
FIELD_2,
|
|
50
|
+
FIELD_3,
|
|
51
|
+
FIELD_4,
|
|
52
|
+
ACTIVE_AREA,
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
type Orientation = 'horizontal' | 'vertical'
|
|
@@ -66,7 +72,7 @@ type FieldRect = Rectangle & {
|
|
|
66
72
|
|
|
67
73
|
type DrawnRect = Rectangle & {
|
|
68
74
|
id: string
|
|
69
|
-
type: 'field' | 'drop-area'
|
|
75
|
+
type: 'field' | 'drop-area' | 'active-area'
|
|
70
76
|
label: string
|
|
71
77
|
color: string
|
|
72
78
|
colorAlpha: string
|
|
@@ -293,7 +299,7 @@ function getGapSize(orientation: Orientation, element: HTMLElement): number {
|
|
|
293
299
|
}
|
|
294
300
|
}
|
|
295
301
|
|
|
296
|
-
return
|
|
302
|
+
return MIN_GAP
|
|
297
303
|
}
|
|
298
304
|
|
|
299
305
|
const fieldChildCache: Record<string, FieldRectChild[]> = {}
|
|
@@ -358,6 +364,15 @@ const buildChildren = (
|
|
|
358
364
|
continue
|
|
359
365
|
}
|
|
360
366
|
|
|
367
|
+
// Get the rect of the block. Use a cached one if possible.
|
|
368
|
+
const elRect =
|
|
369
|
+
dom.getBlockRect(uuid) ||
|
|
370
|
+
ui.getAbsoluteElementRect(el.getBoundingClientRect())
|
|
371
|
+
|
|
372
|
+
// Calculate the offset to the parent. We can not use el.offsetTop/el.offsetLeft here because the value could be 0.
|
|
373
|
+
const elOffsetTop = elRect.y - field.y
|
|
374
|
+
const elOffsetLeft = elRect.x - field.x
|
|
375
|
+
|
|
361
376
|
// Last element.
|
|
362
377
|
if (isLast) {
|
|
363
378
|
const id = buildChildId(field.field, uuid, 'last', uuid)
|
|
@@ -365,18 +380,18 @@ const buildChildren = (
|
|
|
365
380
|
childrenForUuid.push({
|
|
366
381
|
id,
|
|
367
382
|
width: field.width,
|
|
368
|
-
height:
|
|
383
|
+
height: MIN_GAP,
|
|
369
384
|
x: 0,
|
|
370
|
-
y:
|
|
385
|
+
y: elOffsetTop + el.scrollHeight,
|
|
371
386
|
label: field.label,
|
|
372
387
|
})
|
|
373
388
|
} else {
|
|
374
389
|
childrenForUuid.push({
|
|
375
390
|
id,
|
|
376
|
-
width:
|
|
391
|
+
width: MIN_GAP,
|
|
377
392
|
height: el.offsetHeight,
|
|
378
|
-
x: el.
|
|
379
|
-
y:
|
|
393
|
+
x: elOffsetLeft + el.offsetWidth + (field.gap - MIN_GAP) / 2,
|
|
394
|
+
y: elOffsetTop,
|
|
380
395
|
label: field.label,
|
|
381
396
|
})
|
|
382
397
|
}
|
|
@@ -397,18 +412,20 @@ const buildChildren = (
|
|
|
397
412
|
childrenForUuid.push({
|
|
398
413
|
id,
|
|
399
414
|
width: field.width,
|
|
400
|
-
height:
|
|
415
|
+
height: MIN_GAP,
|
|
401
416
|
x: 0,
|
|
402
|
-
y:
|
|
417
|
+
y: elOffsetTop - field.gap / 2,
|
|
403
418
|
label: field.label,
|
|
404
419
|
})
|
|
405
420
|
} else {
|
|
406
421
|
childrenForUuid.push({
|
|
407
422
|
id,
|
|
408
|
-
width:
|
|
409
|
-
height: Math.max(el.offsetHeight,
|
|
410
|
-
x:
|
|
411
|
-
|
|
423
|
+
width: MIN_GAP,
|
|
424
|
+
height: Math.max(el.offsetHeight, MIN_GAP),
|
|
425
|
+
x:
|
|
426
|
+
Math.max(elOffsetLeft - field.gap, -field.gap) +
|
|
427
|
+
(field.gap - MIN_GAP) / 2,
|
|
428
|
+
y: elOffsetTop,
|
|
412
429
|
label: field.label,
|
|
413
430
|
})
|
|
414
431
|
}
|
|
@@ -495,7 +512,7 @@ const buildEmptyChild = (
|
|
|
495
512
|
x: 0,
|
|
496
513
|
y: 0,
|
|
497
514
|
width: fieldWidth,
|
|
498
|
-
height: fieldHeight
|
|
515
|
+
height: Math.max(fieldHeight, MIN_GAP),
|
|
499
516
|
label: getInsertText(field),
|
|
500
517
|
}
|
|
501
518
|
}
|
|
@@ -524,8 +541,9 @@ const buildFieldRect = (key: string): FieldRect | undefined => {
|
|
|
524
541
|
}
|
|
525
542
|
const x = rect.x
|
|
526
543
|
const y = rect.y
|
|
527
|
-
const
|
|
528
|
-
|
|
544
|
+
const width = Math.max(rect.width, MIN_GAP)
|
|
545
|
+
|
|
546
|
+
const height = Math.max(rect.height, MIN_GAP)
|
|
529
547
|
const emptyChild = buildEmptyChild(
|
|
530
548
|
field,
|
|
531
549
|
childElements,
|
|
@@ -533,7 +551,8 @@ const buildFieldRect = (key: string): FieldRect | undefined => {
|
|
|
533
551
|
width,
|
|
534
552
|
height,
|
|
535
553
|
)
|
|
536
|
-
|
|
554
|
+
|
|
555
|
+
const gap = Math.max(getGapSize(orientation, field.element), MIN_GAP)
|
|
537
556
|
|
|
538
557
|
const fieldRect = {
|
|
539
558
|
key: field.key,
|
|
@@ -566,8 +585,8 @@ const buildDropAreaRect = (area: DropArea): Rectangle => {
|
|
|
566
585
|
const dropAreaRect: Rectangle = {
|
|
567
586
|
x: rect.x,
|
|
568
587
|
y: rect.y,
|
|
569
|
-
width: Math.max(rect.width,
|
|
570
|
-
height: Math.max(rect.height,
|
|
588
|
+
width: Math.max(rect.width, MIN_GAP),
|
|
589
|
+
height: Math.max(rect.height, MIN_GAP),
|
|
571
590
|
}
|
|
572
591
|
|
|
573
592
|
cachedDropAreaRects[area.id] = dropAreaRect
|
|
@@ -579,6 +598,17 @@ const colorTealAlpha = rgbaToString(theme.teal.value.normal, 0.7)
|
|
|
579
598
|
const colorAccent = rgbaToString(theme.accent.value[800])
|
|
580
599
|
const colorAccentAlpha = rgbaToString(theme.accent.value[800], 0.7)
|
|
581
600
|
|
|
601
|
+
function getRectType(field: BlokkliFieldElement): RectRenderType {
|
|
602
|
+
if (field.nestingLevel >= 3) {
|
|
603
|
+
return RectRenderType.FIELD_4
|
|
604
|
+
} else if (field.nestingLevel >= 2) {
|
|
605
|
+
return RectRenderType.FIELD_3
|
|
606
|
+
} else if (field.nestingLevel >= 1) {
|
|
607
|
+
return RectRenderType.FIELD_2
|
|
608
|
+
}
|
|
609
|
+
return RectRenderType.FIELD_1
|
|
610
|
+
}
|
|
611
|
+
|
|
582
612
|
class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnRect> {
|
|
583
613
|
getBufferInfo(): { info: BufferInfo | null; hasChanged: boolean } {
|
|
584
614
|
const visibleFields = dom.getVisibleFields()
|
|
@@ -589,6 +619,7 @@ class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnR
|
|
|
589
619
|
for (let i = 0; i < visibleFields.length; i++) {
|
|
590
620
|
const key = visibleFields[i]
|
|
591
621
|
const fieldRect = buildFieldRect(key)
|
|
622
|
+
|
|
592
623
|
if (!fieldRect) {
|
|
593
624
|
continue
|
|
594
625
|
}
|
|
@@ -598,6 +629,7 @@ class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnR
|
|
|
598
629
|
if (this.added.has(child.id)) {
|
|
599
630
|
continue
|
|
600
631
|
}
|
|
632
|
+
const type = getRectType(fieldRect.field)
|
|
601
633
|
this.addRectangle(
|
|
602
634
|
{
|
|
603
635
|
id: child.id,
|
|
@@ -611,7 +643,8 @@ class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnR
|
|
|
611
643
|
height: child.height,
|
|
612
644
|
field: fieldRect,
|
|
613
645
|
},
|
|
614
|
-
|
|
646
|
+
type,
|
|
647
|
+
true,
|
|
615
648
|
)
|
|
616
649
|
}
|
|
617
650
|
}
|
|
@@ -641,6 +674,7 @@ class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnR
|
|
|
641
674
|
height: areaRect.height,
|
|
642
675
|
},
|
|
643
676
|
RectRenderType.DROP_AREA,
|
|
677
|
+
false,
|
|
644
678
|
)
|
|
645
679
|
}
|
|
646
680
|
|
|
@@ -659,6 +693,9 @@ class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnR
|
|
|
659
693
|
const rects = Object.values(this.rects)
|
|
660
694
|
for (let i = 0; i < rects.length; i++) {
|
|
661
695
|
const rect = rects[i]
|
|
696
|
+
if (rect.type === 'active-area') {
|
|
697
|
+
continue
|
|
698
|
+
}
|
|
662
699
|
if (intersects(box, rect)) {
|
|
663
700
|
candidates.push(rect)
|
|
664
701
|
}
|
|
@@ -678,6 +715,9 @@ class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnR
|
|
|
678
715
|
|
|
679
716
|
for (let i = 0; i < rects.length; i++) {
|
|
680
717
|
const rect = rects[i]
|
|
718
|
+
if (rect.type === 'active-area') {
|
|
719
|
+
continue
|
|
720
|
+
}
|
|
681
721
|
if (isInsideRect(coord.x, coord.y, rect)) {
|
|
682
722
|
return rect
|
|
683
723
|
}
|
|
@@ -689,14 +729,91 @@ class DropTargetRectangleBufferCollector extends RectangleBufferCollector<DrawnR
|
|
|
689
729
|
|
|
690
730
|
const collector = new DropTargetRectangleBufferCollector(gl)
|
|
691
731
|
|
|
732
|
+
// Add a rectangle that we will use to display the hovered field area.
|
|
733
|
+
// The vertex shader will dynamically transform the quad to match the currently hovered field area.
|
|
734
|
+
collector.addRectangle(
|
|
735
|
+
{
|
|
736
|
+
id: 'active-hover-rect',
|
|
737
|
+
type: 'active-area',
|
|
738
|
+
label: 'Field Area',
|
|
739
|
+
color: 'red',
|
|
740
|
+
colorAlpha: 'red',
|
|
741
|
+
x: 0,
|
|
742
|
+
y: 0,
|
|
743
|
+
width: ui.artboardSize.value.width,
|
|
744
|
+
height: ui.artboardSize.value.height,
|
|
745
|
+
},
|
|
746
|
+
RectRenderType.ACTIVE_AREA,
|
|
747
|
+
false,
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
const fieldColors = computed(() => {
|
|
751
|
+
return {
|
|
752
|
+
'0': theme.accent.value[900],
|
|
753
|
+
'1': theme.accent.value[400],
|
|
754
|
+
'2': theme.accent.value[600],
|
|
755
|
+
'3': theme.accent.value[500],
|
|
756
|
+
}
|
|
757
|
+
})
|
|
758
|
+
|
|
759
|
+
function getColorForField(field?: FieldRect | null) {
|
|
760
|
+
const nestingLevel = field?.field.nestingLevel || 0
|
|
761
|
+
if (nestingLevel >= 3) {
|
|
762
|
+
return fieldColors.value[3]
|
|
763
|
+
} else if (nestingLevel >= 2) {
|
|
764
|
+
return fieldColors.value[2]
|
|
765
|
+
} else if (nestingLevel >= 1) {
|
|
766
|
+
return fieldColors.value[1]
|
|
767
|
+
}
|
|
768
|
+
return fieldColors.value[0]
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
const activeColorRgb = computed(() => {
|
|
772
|
+
if (active.value?.type === 'drop-area') {
|
|
773
|
+
return theme.teal.value.normal
|
|
774
|
+
}
|
|
775
|
+
return getColorForField(active.value?.field)
|
|
776
|
+
})
|
|
777
|
+
|
|
778
|
+
const activeColorHex = computed(() => {
|
|
779
|
+
if (activeColorRgb.value) {
|
|
780
|
+
return rgbaToString(activeColorRgb.value)
|
|
781
|
+
}
|
|
782
|
+
return ''
|
|
783
|
+
})
|
|
784
|
+
|
|
785
|
+
const activeHoverField = ref<FieldRect | null>(null)
|
|
786
|
+
|
|
787
|
+
const activeHoverRect = computed(() => {
|
|
788
|
+
if (!activeHoverField.value) {
|
|
789
|
+
return [0, 0, 0, 0]
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
const outset = activeHoverField.value.field.nestingLevel === 0 ? 0 : 20
|
|
793
|
+
|
|
794
|
+
return [
|
|
795
|
+
activeHoverField.value.x - outset,
|
|
796
|
+
activeHoverField.value.y - outset,
|
|
797
|
+
activeHoverField.value.width + 2 * outset,
|
|
798
|
+
activeHoverField.value.height + 2 * outset,
|
|
799
|
+
]
|
|
800
|
+
})
|
|
801
|
+
|
|
802
|
+
const activeHoverColor = computed(() => {
|
|
803
|
+
return getColorForField(activeHoverField.value)
|
|
804
|
+
})
|
|
805
|
+
|
|
692
806
|
const uniforms = computed(() => {
|
|
693
807
|
const index = active.value?.index
|
|
694
808
|
return {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
809
|
+
u_color_field_0: toShaderColor(fieldColors.value[0]),
|
|
810
|
+
u_color_field_1: toShaderColor(fieldColors.value[1]),
|
|
811
|
+
u_color_field_2: toShaderColor(fieldColors.value[2]),
|
|
812
|
+
u_color_field_3: toShaderColor(fieldColors.value[3]),
|
|
813
|
+
u_color_hover_area: toShaderColor(activeHoverColor.value),
|
|
814
|
+
u_color_area: toShaderColor(theme.teal.value.normal),
|
|
699
815
|
u_active_rect_id: index === undefined ? -1 : index,
|
|
816
|
+
u_active_hover_rect: activeHoverRect.value,
|
|
700
817
|
}
|
|
701
818
|
})
|
|
702
819
|
|
|
@@ -716,6 +833,45 @@ function toCanvasSpaceCoordinates(x: number, y: number): Coord {
|
|
|
716
833
|
}
|
|
717
834
|
}
|
|
718
835
|
|
|
836
|
+
function setHoveredFieldArea(box: Rectangle, mouse: Coord) {
|
|
837
|
+
if (active.value?.field) {
|
|
838
|
+
if (activeHoverField.value?.key !== active.value.field.key) {
|
|
839
|
+
activeHoverField.value = active.value.field
|
|
840
|
+
}
|
|
841
|
+
return
|
|
842
|
+
}
|
|
843
|
+
const fields = Object.values(fieldCache)
|
|
844
|
+
|
|
845
|
+
let highestNestingLevel = 0
|
|
846
|
+
let candidate: FieldRect | null = null
|
|
847
|
+
|
|
848
|
+
for (let i = 0; i < fields.length; i++) {
|
|
849
|
+
const field = fields[i]
|
|
850
|
+
if (!field.canAddChildren) {
|
|
851
|
+
continue
|
|
852
|
+
}
|
|
853
|
+
if (
|
|
854
|
+
isInsideRect(mouse.x, mouse.y, field) &&
|
|
855
|
+
field.field.nestingLevel >= highestNestingLevel
|
|
856
|
+
) {
|
|
857
|
+
candidate = field
|
|
858
|
+
highestNestingLevel = field.field.nestingLevel
|
|
859
|
+
continue
|
|
860
|
+
}
|
|
861
|
+
if (
|
|
862
|
+
intersects(box, field) &&
|
|
863
|
+
field.field.nestingLevel >= highestNestingLevel
|
|
864
|
+
) {
|
|
865
|
+
highestNestingLevel = field.field.nestingLevel
|
|
866
|
+
candidate = field
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
if (candidate && candidate.key !== activeHoverField.value?.key) {
|
|
871
|
+
activeHoverField.value = candidate
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
719
875
|
onBlokkliEvent('canvas:draw', () => {
|
|
720
876
|
const scale = ui.artboardScale.value
|
|
721
877
|
const offset = { ...ui.artboardOffset.value }
|
|
@@ -734,10 +890,8 @@ onBlokkliEvent('canvas:draw', () => {
|
|
|
734
890
|
animation.setSharedUniforms(gl, programInfo)
|
|
735
891
|
}
|
|
736
892
|
|
|
737
|
-
const isInsideClipped = cursorIsInsideClipped()
|
|
738
|
-
|
|
739
893
|
if (!props.isTouch) {
|
|
740
|
-
if (
|
|
894
|
+
if (cursorIsInsideClipped()) {
|
|
741
895
|
const closest = collector.getClosestIntersectingRect(
|
|
742
896
|
dragBox.value,
|
|
743
897
|
mouseAbsolute,
|
|
@@ -753,6 +907,7 @@ onBlokkliEvent('canvas:draw', () => {
|
|
|
753
907
|
|
|
754
908
|
// WebGL rendering.
|
|
755
909
|
if (programInfo && gl) {
|
|
910
|
+
setHoveredFieldArea(dragBox.value, mouseAbsolute)
|
|
756
911
|
setUniforms(programInfo, uniforms.value)
|
|
757
912
|
|
|
758
913
|
// Nothing to draw.
|
|
@@ -10,18 +10,31 @@ uniform float u_offset_x;
|
|
|
10
10
|
uniform float u_offset_y;
|
|
11
11
|
uniform vec2 u_resolution;
|
|
12
12
|
uniform float u_active_rect_id;
|
|
13
|
-
uniform vec3
|
|
14
|
-
uniform vec3
|
|
15
|
-
uniform vec3
|
|
16
|
-
uniform vec3
|
|
13
|
+
uniform vec3 u_color_field_0;
|
|
14
|
+
uniform vec3 u_color_field_1;
|
|
15
|
+
uniform vec3 u_color_field_2;
|
|
16
|
+
uniform vec3 u_color_field_3;
|
|
17
|
+
uniform vec3 u_color_area;
|
|
18
|
+
uniform vec3 u_color_hover_area;
|
|
19
|
+
uniform vec4 u_active_hover_rect;
|
|
17
20
|
uniform float u_dpi;
|
|
18
21
|
|
|
19
22
|
varying vec4 v_quad;
|
|
20
23
|
varying float v_intersecting;
|
|
21
|
-
varying
|
|
22
|
-
varying vec3
|
|
24
|
+
varying float v_is_hover_area;
|
|
25
|
+
varying vec3 v_color;
|
|
26
|
+
|
|
27
|
+
vec4 getQuad() {
|
|
28
|
+
if (a_rect_type >= 5.0) {
|
|
29
|
+
// Return the quad coming in via uniform.
|
|
30
|
+
return u_active_hover_rect;
|
|
31
|
+
}
|
|
32
|
+
// Use the provided quad.
|
|
33
|
+
return a_quad;
|
|
34
|
+
}
|
|
23
35
|
|
|
24
36
|
void main() {
|
|
37
|
+
vec4 quad = getQuad();
|
|
25
38
|
vec2 offsetPosition = a_position * u_scale;
|
|
26
39
|
offsetPosition.x += u_offset_x;
|
|
27
40
|
offsetPosition.y += u_offset_y;
|
|
@@ -38,20 +51,27 @@ void main() {
|
|
|
38
51
|
|
|
39
52
|
// Transform the quad.
|
|
40
53
|
vec4 transformed_quad = vec4(
|
|
41
|
-
(
|
|
42
|
-
(u_resolution.y -
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
a_quad.w * u_scale * u_dpi
|
|
54
|
+
(quad.x * u_scale + u_offset_x) * u_dpi,
|
|
55
|
+
(u_resolution.y - quad.y * u_scale - quad.w * u_scale - u_offset_y) * u_dpi,
|
|
56
|
+
quad.z * u_scale * u_dpi,
|
|
57
|
+
quad.w * u_scale * u_dpi
|
|
46
58
|
);
|
|
47
59
|
v_quad = transformed_quad;
|
|
48
60
|
|
|
61
|
+
v_is_hover_area = a_rect_type >= 5.0 ? 1.0 : 0.0;
|
|
62
|
+
|
|
49
63
|
// Set correct colors based on type.
|
|
50
|
-
if (a_rect_type < 0
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
if (a_rect_type < 1.0) {
|
|
65
|
+
v_color = u_color_area;
|
|
66
|
+
} else if (a_rect_type < 2.0) {
|
|
67
|
+
v_color = u_color_field_0;
|
|
68
|
+
} else if (a_rect_type < 3.0) {
|
|
69
|
+
v_color = u_color_field_1;
|
|
70
|
+
} else if (a_rect_type < 4.0) {
|
|
71
|
+
v_color = u_color_field_2;
|
|
72
|
+
} else if (a_rect_type < 5.0) {
|
|
73
|
+
v_color = u_color_field_3;
|
|
53
74
|
} else {
|
|
54
|
-
|
|
55
|
-
v_color_active = u_color_area_active;
|
|
75
|
+
v_color = u_color_hover_area;
|
|
56
76
|
}
|
|
57
77
|
}
|
|
@@ -376,6 +376,10 @@ onBlokkliEvent('dragging:start', (e) => {
|
|
|
376
376
|
document.addEventListener('pointermove', onMouseMove, { capture: true })
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
|
+
|
|
380
|
+
// Before showing the drop targets we update all currently visible rects to
|
|
381
|
+
// ensure the user sees the correct drop targets right away.
|
|
382
|
+
dom.updateVisibleRects()
|
|
379
383
|
dragItems.value = e.items
|
|
380
384
|
})
|
|
381
385
|
|
|
@@ -38,14 +38,6 @@ function onClick(items: DraggableExistingBlock[]) {
|
|
|
38
38
|
)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const findField = (uuid: string): BlokkliFieldElement | undefined => {
|
|
42
|
-
try {
|
|
43
|
-
return dom.getBlockField(uuid)
|
|
44
|
-
} catch (_e) {
|
|
45
|
-
// Noop.
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
41
|
const canDuplicate = computed<boolean>(() => {
|
|
50
42
|
if (state.editMode.value !== 'editing') {
|
|
51
43
|
return false
|
|
@@ -57,11 +49,7 @@ const canDuplicate = computed<boolean>(() => {
|
|
|
57
49
|
const selectedCount = selection.blocks.value.length
|
|
58
50
|
for (let i = 0; i < selectedCount; i++) {
|
|
59
51
|
const block = selection.blocks.value[i]
|
|
60
|
-
const field =
|
|
61
|
-
if (!field) {
|
|
62
|
-
return false
|
|
63
|
-
}
|
|
64
|
-
|
|
52
|
+
const field = dom.getBlockField(block.uuid)
|
|
65
53
|
const count = state.getFieldBlockCount(field.key)
|
|
66
54
|
|
|
67
55
|
// Early return if the field is already full.
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
id="mask"
|
|
4
4
|
v-model="isActive"
|
|
5
5
|
:label="$t('maskToggle', 'Toggle non-editable areas')"
|
|
6
|
-
:title-on="$t('
|
|
7
|
-
:title-off="$t('
|
|
6
|
+
:title-on="$t('maskHide', 'Hide non-editable areas')"
|
|
7
|
+
:title-off="$t('maskShow', 'Show non-editable areas')"
|
|
8
8
|
:tour-text="
|
|
9
9
|
$t(
|
|
10
10
|
'maskTourText',
|
|
@@ -15,7 +15,7 @@ const { $t, state } = useBlokkli()
|
|
|
15
15
|
const props = defineProps<{
|
|
16
16
|
label: string
|
|
17
17
|
property: string
|
|
18
|
-
modelValue
|
|
18
|
+
modelValue?: string
|
|
19
19
|
}>()
|
|
20
20
|
|
|
21
21
|
const emit = defineEmits(['update:modelValue'])
|
|
@@ -25,7 +25,7 @@ const checked = computed({
|
|
|
25
25
|
return props.modelValue === '1'
|
|
26
26
|
},
|
|
27
27
|
set(v: any) {
|
|
28
|
-
emit('update:modelValue', v ? '1' : '')
|
|
28
|
+
emit('update:modelValue', v ? '1' : '0')
|
|
29
29
|
},
|
|
30
30
|
})
|
|
31
31
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
class="bk-blokkli-item-options-checkboxes"
|
|
4
|
-
:class="{ 'bk-is-active': isOpen }"
|
|
4
|
+
:class="{ 'bk-is-active': isOpen, 'bk-is-grouped': isGrouped }"
|
|
5
5
|
>
|
|
6
|
-
<button @click="isOpen = !isOpen">
|
|
7
|
-
<span>{{
|
|
6
|
+
<button v-if="!isGrouped" @click="isOpen = !isOpen">
|
|
7
|
+
<span>{{ visibleLabel }}</span>
|
|
8
8
|
<div>
|
|
9
9
|
<template v-if="checked.length < 4">
|
|
10
10
|
<span v-for="item in checked" :key="item" class="bk-pill">{{
|
|
@@ -15,20 +15,20 @@
|
|
|
15
15
|
</div>
|
|
16
16
|
<Icon name="caret" />
|
|
17
17
|
</button>
|
|
18
|
-
<div v-if="isOpen">
|
|
18
|
+
<div v-if="isOpen || isGrouped">
|
|
19
19
|
<label
|
|
20
|
-
v-for="option in
|
|
21
|
-
:key="option.
|
|
20
|
+
v-for="option in options"
|
|
21
|
+
:key="option.value"
|
|
22
22
|
class="bk-blokkli-item-options-checkbox"
|
|
23
23
|
>
|
|
24
24
|
<input
|
|
25
25
|
v-model="checked"
|
|
26
26
|
type="checkbox"
|
|
27
27
|
class="peer"
|
|
28
|
-
:value="option.
|
|
28
|
+
:value="option.value"
|
|
29
29
|
/>
|
|
30
30
|
<div />
|
|
31
|
-
<span>{{ option.
|
|
31
|
+
<span>{{ option.label }}</span>
|
|
32
32
|
</label>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
@@ -38,21 +38,23 @@
|
|
|
38
38
|
import { computed, ref, useBlokkli } from '#imports'
|
|
39
39
|
import { Icon } from '#blokkli/components'
|
|
40
40
|
import defineCommands from '#blokkli/helpers/composables/defineCommands'
|
|
41
|
+
import { BK_VISIBLE_LANGUAGES } from '#blokkli/helpers/symbols'
|
|
41
42
|
|
|
42
43
|
const { $t, state } = useBlokkli()
|
|
43
44
|
|
|
44
45
|
const props = defineProps<{
|
|
45
46
|
label: string
|
|
46
47
|
property: string
|
|
47
|
-
modelValue
|
|
48
|
-
options:
|
|
48
|
+
modelValue?: string
|
|
49
|
+
options: { value: string; label: string }[]
|
|
50
|
+
isGrouped?: boolean
|
|
49
51
|
}>()
|
|
50
52
|
|
|
51
53
|
const emit = defineEmits(['update:modelValue'])
|
|
52
54
|
|
|
53
55
|
const isOpen = ref(false)
|
|
54
56
|
|
|
55
|
-
const optionOrder = computed(() =>
|
|
57
|
+
const optionOrder = computed(() => props.options.map((v) => v.value))
|
|
56
58
|
|
|
57
59
|
const checked = computed<string[]>({
|
|
58
60
|
get() {
|
|
@@ -72,6 +74,13 @@ const checked = computed<string[]>({
|
|
|
72
74
|
},
|
|
73
75
|
})
|
|
74
76
|
|
|
77
|
+
const visibleLabel = computed(() => {
|
|
78
|
+
if (props.property === BK_VISIBLE_LANGUAGES && !checked.value.length) {
|
|
79
|
+
return $t('optionBkVisibleLanguagesAll', 'All languages')
|
|
80
|
+
}
|
|
81
|
+
return props.label
|
|
82
|
+
})
|
|
83
|
+
|
|
75
84
|
const toggle = (key: string) => {
|
|
76
85
|
if (!checked.value.includes(key)) {
|
|
77
86
|
checked.value = [...checked.value, key]
|
|
@@ -80,43 +89,37 @@ const toggle = (key: string) => {
|
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
91
|
|
|
83
|
-
const mappedOptions = computed(() => {
|
|
84
|
-
return Object.entries(props.options).map(([key, value]) => {
|
|
85
|
-
return { key, value }
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
|
|
89
92
|
defineCommands(() => {
|
|
90
93
|
if (state.editMode.value !== 'editing') {
|
|
91
94
|
return
|
|
92
95
|
}
|
|
93
|
-
return
|
|
94
|
-
if (checked.value.includes(
|
|
96
|
+
return props.options.map((option) => {
|
|
97
|
+
if (checked.value.includes(option.value)) {
|
|
95
98
|
return {
|
|
96
|
-
id: 'options:' + props.property + ':select:' +
|
|
99
|
+
id: 'options:' + props.property + ':select:' + option.value,
|
|
97
100
|
label: $t(
|
|
98
101
|
'optionsCommand.unselectCheckboxValue',
|
|
99
102
|
'Unselect "@value" in "@option"',
|
|
100
103
|
)
|
|
101
104
|
.replace('@option', props.label)
|
|
102
|
-
.replace('@value',
|
|
105
|
+
.replace('@value', option.label),
|
|
103
106
|
group: 'selection',
|
|
104
107
|
icon: 'form',
|
|
105
|
-
callback: () => toggle(
|
|
108
|
+
callback: () => toggle(option.value),
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
return {
|
|
110
|
-
id: 'options:' + props.property + ':unselect:' +
|
|
113
|
+
id: 'options:' + props.property + ':unselect:' + option.value,
|
|
111
114
|
label: $t(
|
|
112
115
|
'optionsCommand.selectCheckboxValue',
|
|
113
116
|
'Select "@value" in "@option"',
|
|
114
117
|
)
|
|
115
118
|
.replace('@option', props.label)
|
|
116
|
-
.replace('@value',
|
|
119
|
+
.replace('@value', option.label),
|
|
117
120
|
group: 'selection',
|
|
118
121
|
icon: 'form',
|
|
119
|
-
callback: () => toggle(
|
|
122
|
+
callback: () => toggle(option.value),
|
|
120
123
|
}
|
|
121
124
|
})
|
|
122
125
|
})
|