@blokkli/editor 2.0.0-alpha.17 → 2.0.0-alpha.18
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 +380 -59
- package/dist/modules/drupal/graphql/base/fragment.paragraphsFieldItem.graphql +3 -1
- package/dist/modules/drupal/graphql/base/query.pbConfig.graphql +1 -10
- package/dist/modules/drupal/graphql/mutations/set_paragraph_schedule.graphql +15 -0
- package/dist/modules/drupal/index.mjs +33 -0
- package/dist/modules/drupal/runtime/adapter/index.js +10 -2
- package/dist/runtime/adapter/index.d.ts +21 -0
- package/dist/runtime/blokkliPlugins/ContextMenu/Menu/index.vue +3 -0
- package/dist/runtime/blokkliPlugins/ItemAction/index.vue +23 -13
- package/dist/runtime/blokkliPlugins/ItemAction/index.vue.d.ts +20 -44
- package/dist/runtime/blokkliPlugins/TourItem/index.vue +10 -5
- package/dist/runtime/components/BlokkliEditable.vue +13 -13
- package/dist/runtime/components/BlokkliField.vue +3 -0
- package/dist/runtime/components/BlokkliField.vue.d.ts +3 -3
- package/dist/runtime/components/BlokkliItem.vue +1 -1
- package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
- package/dist/runtime/components/BlokkliProvider.vue +12 -8
- package/dist/runtime/components/Edit/Actions/index.vue +27 -16
- package/dist/runtime/components/Edit/AnimationCanvas/index.vue +26 -10
- package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +3 -0
- package/dist/runtime/components/Edit/Dialog/index.vue +6 -4
- package/dist/runtime/components/Edit/DraggableList.vue +15 -7
- package/dist/runtime/components/Edit/DraggableList.vue.d.ts +5 -5
- package/dist/runtime/components/Edit/EditProvider.vue +29 -16
- package/dist/runtime/components/Edit/EditProvider.vue.d.ts +1 -0
- package/dist/runtime/components/Edit/Features/AddList/index.vue +9 -11
- package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +9 -6
- package/dist/runtime/components/Edit/Features/Analyze/Renderer.vue +1 -1
- package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +15 -11
- package/dist/runtime/components/Edit/Features/Anchors/Renderer.vue +19 -102
- package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +3 -0
- package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +28 -52
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue +154 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue.d.ts +27 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +222 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue.d.ts +11 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +96 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue.d.ts +2 -0
- package/dist/runtime/components/Edit/Features/Clipboard/index.vue +15 -16
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +51 -0
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/{Group → Item}/index.vue.d.ts +9 -13
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +46 -66
- package/dist/runtime/components/Edit/Features/Comments/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/Conversions/index.vue +4 -7
- package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Debug/index.vue +4 -1
- package/dist/runtime/components/Edit/Features/Delete/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +13 -5
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +14 -11
- package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +30 -18
- package/dist/runtime/components/Edit/Features/Duplicate/index.vue +6 -8
- package/dist/runtime/components/Edit/Features/Edit/index.vue +15 -21
- package/dist/runtime/components/Edit/Features/EditForm/index.vue +7 -6
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +8 -3
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue.d.ts +2 -2
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +29 -12
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue.d.ts +2 -2
- package/dist/runtime/components/Edit/Features/EditableField/index.vue +40 -42
- package/dist/runtime/components/Edit/Features/Fragments/Dialog/index.vue +11 -9
- package/dist/runtime/components/Edit/Features/Fragments/index.vue +3 -3
- package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +16 -25
- package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +5 -7
- package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +5 -5
- package/dist/runtime/components/Edit/Features/Library/index.vue +27 -23
- package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +6 -3
- package/dist/runtime/components/Edit/Features/MediaLibrary/index.vue +15 -12
- package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Options/Form/index.vue +7 -6
- package/dist/runtime/components/Edit/Features/Options/index.vue +6 -6
- package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +68 -15
- package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +15 -15
- package/dist/runtime/components/Edit/Features/Search/index.vue +4 -1
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +3 -3
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +34 -11
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +21 -20
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue.d.ts +2 -2
- package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +3 -3
- package/dist/runtime/components/Edit/Features/Selection/OverlayFallback/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Selection/index.vue +61 -27
- package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Structure/List/Item/index.vue +13 -6
- package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +3 -0
- package/dist/runtime/components/Edit/Features/Transform/index.vue +2 -27
- package/dist/runtime/components/Edit/Features/Translations/index.vue +7 -7
- package/dist/runtime/components/Edit/Features/Validations/SidebarItem/index.vue +5 -5
- package/dist/runtime/components/Edit/Features/index.vue +17 -7
- package/dist/runtime/components/Edit/Form/Toggle/index.vue +4 -3
- package/dist/runtime/components/Edit/Form/Toggle/index.vue.d.ts +12 -2
- package/dist/runtime/components/Edit/InfoBox/index.vue +6 -2
- package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +12 -2
- package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue → ScheduleDate/index.vue} +6 -58
- package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue.d.ts → ScheduleDate/index.vue.d.ts} +11 -1
- package/dist/runtime/components/Edit/ShortcutIndicator/index.vue +3 -0
- package/dist/runtime/components/Edit/Transition/Height.vue +95 -0
- package/dist/runtime/components/Edit/Transition/Height.vue.d.ts +36 -0
- package/dist/runtime/components/Edit/index.d.ts +3 -1
- package/dist/runtime/components/Edit/index.js +5 -1
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/animationProvider.d.ts +2 -1
- package/dist/runtime/helpers/animationProvider.js +6 -2
- package/dist/runtime/helpers/composables/useStateBasedCache.d.ts +4 -0
- package/dist/runtime/helpers/composables/useStateBasedCache.js +13 -0
- package/dist/runtime/helpers/definitionProvider.d.ts +1 -1
- package/dist/runtime/helpers/dom/index.d.ts +1 -1
- package/dist/runtime/helpers/domProvider.d.ts +10 -16
- package/dist/runtime/helpers/domProvider.js +80 -135
- package/dist/runtime/helpers/index.d.ts +1 -8
- package/dist/runtime/helpers/index.js +1 -84
- package/dist/runtime/helpers/providers/blocks.d.ts +10 -0
- package/dist/runtime/helpers/providers/blocks.js +91 -0
- package/dist/runtime/helpers/providers/directive.d.ts +24 -0
- package/dist/runtime/helpers/{editableProvider.js → providers/directive.js} +90 -29
- package/dist/runtime/helpers/providers/element.d.ts +6 -0
- package/dist/runtime/helpers/providers/element.js +35 -0
- package/dist/runtime/helpers/providers/fields.d.ts +8 -0
- package/dist/runtime/helpers/providers/fields.js +47 -0
- package/dist/runtime/helpers/selectionProvider.d.ts +11 -11
- package/dist/runtime/helpers/selectionProvider.js +38 -45
- package/dist/runtime/helpers/stateProvider.d.ts +1 -0
- package/dist/runtime/helpers/stateProvider.js +21 -15
- package/dist/runtime/helpers/themeProvider.d.ts +2 -1
- package/dist/runtime/helpers/themeProvider.js +24 -14
- package/dist/runtime/helpers/typesProvider.js +10 -26
- package/dist/runtime/helpers/uiProvider.d.ts +3 -2
- package/dist/runtime/helpers/uiProvider.js +11 -15
- package/dist/runtime/icons/calendar.svg +1 -0
- package/dist/runtime/icons/clock.svg +1 -0
- package/dist/runtime/icons/comment_add.svg +1 -5
- package/dist/runtime/icons/delete.svg +1 -8
- package/dist/runtime/icons/duplicate.svg +1 -12
- package/dist/runtime/icons/edit.svg +1 -8
- package/dist/runtime/icons/reusable.svg +1 -5
- package/dist/runtime/plugins/{blokkliEditable.js → blokkliDirectives.js} +14 -20
- package/dist/runtime/types/index.d.ts +55 -36
- package/package.json +1 -1
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Group/index.vue +0 -63
- package/dist/runtime/helpers/editableProvider.d.ts +0 -14
- /package/dist/runtime/plugins/{blokkliEditable.d.ts → blokkliDirectives.d.ts} +0 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
id="duplicate"
|
|
4
4
|
:title="$t('duplicate', 'Duplicate')"
|
|
5
5
|
:disabled="!canDuplicate"
|
|
6
|
+
edit-only
|
|
6
7
|
meta
|
|
7
8
|
key-code="D"
|
|
8
9
|
multiple
|
|
@@ -31,22 +32,19 @@ function onClick(items) {
|
|
|
31
32
|
);
|
|
32
33
|
}
|
|
33
34
|
const canDuplicate = computed(() => {
|
|
34
|
-
if (state.editMode.value !== "editing") {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
35
|
const blocksByField = {};
|
|
38
36
|
const fieldsByKey = {};
|
|
39
|
-
const selectedCount = selection.
|
|
37
|
+
const selectedCount = selection.items.value.length;
|
|
40
38
|
for (let i = 0; i < selectedCount; i++) {
|
|
41
|
-
const block = selection.
|
|
42
|
-
const field = state.getMutatedField(block.
|
|
39
|
+
const block = selection.items.value[i];
|
|
40
|
+
const field = state.getMutatedField(block.host.uuid, block.host.fieldName);
|
|
43
41
|
if (!field) {
|
|
44
42
|
continue;
|
|
45
43
|
}
|
|
46
44
|
const fieldKey = getFieldKey(field.entityUuid, field.name);
|
|
47
45
|
const fieldConfig = types.getFieldConfig(
|
|
48
46
|
field.entityType,
|
|
49
|
-
block.
|
|
47
|
+
block.host.bundle,
|
|
50
48
|
field.name
|
|
51
49
|
);
|
|
52
50
|
if (!fieldConfig) {
|
|
@@ -77,7 +75,7 @@ const canDuplicate = computed(() => {
|
|
|
77
75
|
if (field.cardinality !== -1 && count + blocks.length > field.cardinality) {
|
|
78
76
|
return false;
|
|
79
77
|
}
|
|
80
|
-
const bundles = blocks.map((v) => v.
|
|
78
|
+
const bundles = blocks.map((v) => v.bundle);
|
|
81
79
|
if (!field.allowedBundles.length || bundles.some((bundle) => !field.allowedBundles.includes(bundle))) {
|
|
82
80
|
return false;
|
|
83
81
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PluginItemAction
|
|
3
|
-
v-if="isEditing"
|
|
4
3
|
id="edit"
|
|
4
|
+
edit-only
|
|
5
5
|
:title="$t('edit', 'Edit...')"
|
|
6
6
|
:disabled="!canEdit"
|
|
7
7
|
meta
|
|
@@ -24,27 +24,21 @@ defineBlokkliFeature({
|
|
|
24
24
|
requiredAdapterMethods: ["formFrameBuilder"]
|
|
25
25
|
});
|
|
26
26
|
const { eventBus, selection, state, $t, adapter, definitions } = useBlokkli();
|
|
27
|
-
const block = computed(() => {
|
|
28
|
-
if (selection.blocks.value.length !== 1) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
return selection.blocks.value[0];
|
|
32
|
-
});
|
|
33
|
-
const isEditing = computed(() => state.editMode.value === "editing");
|
|
34
27
|
const canEdit = computed(() => {
|
|
35
|
-
|
|
28
|
+
const item = selection.item.value;
|
|
29
|
+
if (!item) {
|
|
36
30
|
return false;
|
|
37
31
|
}
|
|
38
32
|
const definition = definitions.getBlockDefinition(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
item.bundle,
|
|
34
|
+
item.fieldListType,
|
|
35
|
+
item.parentBlockBundle
|
|
42
36
|
);
|
|
43
37
|
if (definition?.editor?.disableEdit) {
|
|
44
38
|
return false;
|
|
45
39
|
}
|
|
46
|
-
if (
|
|
47
|
-
return !!adapter.getLibraryItemEditUrl && (state.editMode.value === "editing" || state.editMode.value === "translating") && !
|
|
40
|
+
if (item.library?.libraryItemUuid) {
|
|
41
|
+
return !!adapter.getLibraryItemEditUrl && (state.editMode.value === "editing" || state.editMode.value === "translating") && !item.isNew;
|
|
48
42
|
}
|
|
49
43
|
return state.editMode.value === "editing";
|
|
50
44
|
});
|
|
@@ -56,22 +50,22 @@ function onClick(items) {
|
|
|
56
50
|
return;
|
|
57
51
|
}
|
|
58
52
|
const item = items[0];
|
|
59
|
-
if (item.libraryItemUuid && adapter.getLibraryItemEditUrl) {
|
|
60
|
-
const url = adapter.getLibraryItemEditUrl(item.libraryItemUuid);
|
|
53
|
+
if (item.library?.libraryItemUuid && adapter.getLibraryItemEditUrl) {
|
|
54
|
+
const url = adapter.getLibraryItemEditUrl(item.library.libraryItemUuid);
|
|
61
55
|
eventBus.emit("library:edit-item", {
|
|
62
56
|
url,
|
|
63
|
-
label: item.
|
|
64
|
-
uuid: item.libraryItemUuid
|
|
57
|
+
label: item.library.label,
|
|
58
|
+
uuid: item.library.libraryItemUuid
|
|
65
59
|
});
|
|
66
60
|
return;
|
|
67
61
|
}
|
|
68
62
|
eventBus.emit("item:edit", {
|
|
69
63
|
uuid: item.uuid,
|
|
70
|
-
bundle: item.
|
|
64
|
+
bundle: item.bundle
|
|
71
65
|
});
|
|
72
66
|
}
|
|
73
|
-
onBlokkliEvent("item:doubleClick", function(
|
|
74
|
-
onClick([
|
|
67
|
+
onBlokkliEvent("item:doubleClick", function(block) {
|
|
68
|
+
onClick([block]);
|
|
75
69
|
});
|
|
76
70
|
</script>
|
|
77
71
|
|
|
@@ -24,6 +24,7 @@ import { ref, computed, useBlokkli, defineBlokkliFeature } from "#imports";
|
|
|
24
24
|
import { FormOverlay, BlokkliTransition } from "#blokkli/components";
|
|
25
25
|
import FormFrame from "./Frame/index.vue";
|
|
26
26
|
import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
|
|
27
|
+
import { itemEntityType } from "#blokkli-build/config";
|
|
27
28
|
const { adapter } = defineBlokkliFeature({
|
|
28
29
|
id: "edit-form",
|
|
29
30
|
icon: "form",
|
|
@@ -31,7 +32,7 @@ const { adapter } = defineBlokkliFeature({
|
|
|
31
32
|
description: "Listens to edit events and renders an iframe containing the edit form.",
|
|
32
33
|
requiredAdapterMethods: ["formFrameBuilder"]
|
|
33
34
|
});
|
|
34
|
-
const { types, state, context, $t, dom, definitions } = useBlokkli();
|
|
35
|
+
const { types, state, context, $t, dom, definitions, blocks } = useBlokkli();
|
|
35
36
|
const form = ref(null);
|
|
36
37
|
const formUrl = computed(() => {
|
|
37
38
|
if (form.value) {
|
|
@@ -99,13 +100,13 @@ onBlokkliEvent("item:edit", (e) => {
|
|
|
99
100
|
if (!state.canEdit.value) {
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
|
-
const block =
|
|
103
|
+
const block = blocks.getBlock(e.uuid);
|
|
103
104
|
if (!block) {
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
106
107
|
const definition = definitions.getBlockDefinition(
|
|
107
108
|
e.bundle,
|
|
108
|
-
block.
|
|
109
|
+
block.fieldListType,
|
|
109
110
|
block.parentBlockBundle
|
|
110
111
|
);
|
|
111
112
|
if (definition?.editor?.disableEdit) {
|
|
@@ -156,12 +157,12 @@ onBlokkliEvent("add:block:new", (e) => {
|
|
|
156
157
|
if (!state.canEdit.value) {
|
|
157
158
|
return;
|
|
158
159
|
}
|
|
159
|
-
const field = dom.
|
|
160
|
-
if (field) {
|
|
160
|
+
const field = dom.getRegisteredField(e.host.uuid, e.host.fieldName);
|
|
161
|
+
if (field?.entity.type === itemEntityType) {
|
|
161
162
|
const definition = definitions.getBlockDefinition(
|
|
162
163
|
e.bundle,
|
|
163
164
|
field.fieldListType,
|
|
164
|
-
field.
|
|
165
|
+
field.entity.bundle
|
|
165
166
|
);
|
|
166
167
|
if (definition?.editor?.disableEdit) {
|
|
167
168
|
return;
|
|
@@ -18,7 +18,8 @@ import {
|
|
|
18
18
|
onBeforeUnmount,
|
|
19
19
|
useTemplateRef
|
|
20
20
|
} from "#imports";
|
|
21
|
-
|
|
21
|
+
import { itemEntityType } from "#blokkli-build/config";
|
|
22
|
+
const { adapter, ui, element } = useBlokkli();
|
|
22
23
|
const PROPAGATE_WHEEL = false;
|
|
23
24
|
const rootElement = ui.rootElement();
|
|
24
25
|
const props = defineProps({
|
|
@@ -40,7 +41,11 @@ function onIframeLoad() {
|
|
|
40
41
|
let ckEditor = null;
|
|
41
42
|
iframe.value.contentDocument.addEventListener("wheel", (e) => {
|
|
42
43
|
if (!ckEditor) {
|
|
43
|
-
const el =
|
|
44
|
+
const el = element.query(
|
|
45
|
+
iframeDoc.documentElement,
|
|
46
|
+
".ck-editor__editable",
|
|
47
|
+
"Find CKEditor in editable iframe."
|
|
48
|
+
);
|
|
44
49
|
if (el) {
|
|
45
50
|
ckEditor = el;
|
|
46
51
|
}
|
|
@@ -80,7 +85,7 @@ function onIframeLoad() {
|
|
|
80
85
|
}
|
|
81
86
|
const height = ref(props.initialHeight);
|
|
82
87
|
const url = computed(() => {
|
|
83
|
-
if (
|
|
88
|
+
if (props.host.type === itemEntityType) {
|
|
84
89
|
return adapter.buildEditableFrameUrl({
|
|
85
90
|
uuid: props.host.uuid,
|
|
86
91
|
fieldName: props.fieldName
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EditableFieldType, EntityContext } from '#blokkli/types';
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
modelValue: string;
|
|
4
4
|
type: EditableFieldType;
|
|
5
5
|
fieldName: string;
|
|
6
|
-
host:
|
|
6
|
+
host: EntityContext;
|
|
7
7
|
initialHeight: number;
|
|
8
8
|
};
|
|
9
9
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -71,7 +71,16 @@ import InputPlaintext from "./Plaintext/index.vue";
|
|
|
71
71
|
import InputContenteditable from "./Contenteditable/index.vue";
|
|
72
72
|
import InputFrame from "./Frame/index.vue";
|
|
73
73
|
import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
|
|
74
|
-
|
|
74
|
+
import { itemEntityType } from "#blokkli-build/config";
|
|
75
|
+
const {
|
|
76
|
+
eventBus,
|
|
77
|
+
selection,
|
|
78
|
+
state,
|
|
79
|
+
adapter,
|
|
80
|
+
$t,
|
|
81
|
+
types,
|
|
82
|
+
element: elementProvider
|
|
83
|
+
} = useBlokkli();
|
|
75
84
|
const props = defineProps({
|
|
76
85
|
fieldName: { type: String, required: true },
|
|
77
86
|
host: { type: Object, required: true },
|
|
@@ -102,12 +111,7 @@ const inputStyle = ref({});
|
|
|
102
111
|
const form = ref(null);
|
|
103
112
|
const input = ref(null);
|
|
104
113
|
const hasChanged = computed(() => modelValue.value !== originalText.value);
|
|
105
|
-
const itemBundle = computed(() =>
|
|
106
|
-
if ("itemBundle" in props.host) {
|
|
107
|
-
return props.host.itemBundle;
|
|
108
|
-
}
|
|
109
|
-
return void 0;
|
|
110
|
-
});
|
|
114
|
+
const itemBundle = computed(() => props.host.bundle);
|
|
111
115
|
const maxlength = computed(() => props.config.maxLength);
|
|
112
116
|
const required = computed(() => !!props.config.required);
|
|
113
117
|
const title = computed(() => {
|
|
@@ -138,7 +142,7 @@ const close = async () => {
|
|
|
138
142
|
}
|
|
139
143
|
const el = getElement();
|
|
140
144
|
if (shouldSave.value && modelValue.value !== originalText.value) {
|
|
141
|
-
if (
|
|
145
|
+
if (props.host.type === itemEntityType) {
|
|
142
146
|
await state.mutateWithLoadingState(
|
|
143
147
|
() => adapter.updateFieldValue({
|
|
144
148
|
uuid: props.host.uuid,
|
|
@@ -187,17 +191,30 @@ const focusInput = (el) => {
|
|
|
187
191
|
if (!el) {
|
|
188
192
|
return;
|
|
189
193
|
}
|
|
190
|
-
const
|
|
194
|
+
const queryEl = el instanceof Document ? el.documentElement : el;
|
|
195
|
+
const textarea = elementProvider.query(
|
|
196
|
+
queryEl,
|
|
197
|
+
"textarea",
|
|
198
|
+
"Focus editable field textarea"
|
|
199
|
+
);
|
|
191
200
|
if (textarea) {
|
|
192
201
|
textarea.focus();
|
|
193
202
|
return;
|
|
194
203
|
}
|
|
195
|
-
const editable =
|
|
196
|
-
|
|
204
|
+
const editable = elementProvider.query(
|
|
205
|
+
queryEl,
|
|
206
|
+
"[contenteditable]",
|
|
207
|
+
"Focus editable field contenteditable"
|
|
208
|
+
);
|
|
209
|
+
if (editable) {
|
|
197
210
|
editable.focus();
|
|
198
211
|
return;
|
|
199
212
|
}
|
|
200
|
-
const iframe =
|
|
213
|
+
const iframe = elementProvider.query(
|
|
214
|
+
queryEl,
|
|
215
|
+
"iframe",
|
|
216
|
+
"Find iframe in editable field"
|
|
217
|
+
);
|
|
201
218
|
if (iframe?.contentDocument) {
|
|
202
219
|
focusInput(iframe.contentDocument);
|
|
203
220
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EntityContext, EditableFieldConfig } from '#blokkli/types';
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
fieldName: string;
|
|
4
|
-
host:
|
|
4
|
+
host: EntityContext;
|
|
5
5
|
element: HTMLElement;
|
|
6
6
|
config: EditableFieldConfig;
|
|
7
7
|
isComponent?: boolean;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Teleport to="body">
|
|
3
3
|
<BlokkliTransition name="caret-tooltip" :enabled="hasTransition">
|
|
4
|
-
<Overlay
|
|
4
|
+
<Overlay
|
|
5
|
+
v-if="selectedEditable"
|
|
6
|
+
v-bind="selectedEditable"
|
|
7
|
+
:key="key"
|
|
8
|
+
@close="close"
|
|
9
|
+
/>
|
|
5
10
|
</BlokkliTransition>
|
|
6
11
|
</Teleport>
|
|
7
12
|
</template>
|
|
@@ -19,6 +24,7 @@ import { BlokkliTransition } from "#blokkli/components";
|
|
|
19
24
|
import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
|
|
20
25
|
import defineCommands from "#blokkli/helpers/composables/defineCommands";
|
|
21
26
|
import { falsy } from "#blokkli/helpers";
|
|
27
|
+
import { itemEntityType } from "#blokkli-build/config";
|
|
22
28
|
defineBlokkliFeature({
|
|
23
29
|
id: "editable-field",
|
|
24
30
|
icon: "textbox",
|
|
@@ -26,41 +32,47 @@ defineBlokkliFeature({
|
|
|
26
32
|
requiredAdapterMethods: ["updateFieldValue", "getEditableFieldConfig"],
|
|
27
33
|
description: "Implements a form overlay to edit a single field of a block."
|
|
28
34
|
});
|
|
29
|
-
const { selection, adapter, types, $t,
|
|
30
|
-
const
|
|
35
|
+
const { selection, adapter, types, $t, state, directive, blocks, context } = useBlokkli();
|
|
36
|
+
const selectedEditable = ref(null);
|
|
31
37
|
const hasTransition = ref(false);
|
|
32
38
|
const key = computed(() => {
|
|
33
|
-
if (!
|
|
39
|
+
if (!selectedEditable.value) {
|
|
34
40
|
return "";
|
|
35
41
|
}
|
|
36
|
-
return
|
|
42
|
+
return selectedEditable.value.host.uuid + selectedEditable.value.fieldName;
|
|
37
43
|
});
|
|
38
44
|
const getHost = (uuid) => {
|
|
39
45
|
if (uuid) {
|
|
40
|
-
const block =
|
|
46
|
+
const block = blocks.getBlock(uuid);
|
|
41
47
|
if (block) {
|
|
42
|
-
return
|
|
48
|
+
return {
|
|
49
|
+
type: itemEntityType,
|
|
50
|
+
bundle: block.bundle,
|
|
51
|
+
uuid: block.uuid
|
|
52
|
+
};
|
|
43
53
|
}
|
|
44
54
|
}
|
|
45
|
-
return
|
|
55
|
+
return {
|
|
56
|
+
type: context.value.entityType,
|
|
57
|
+
bundle: context.value.entityBundle,
|
|
58
|
+
uuid: context.value.entityUuid
|
|
59
|
+
};
|
|
46
60
|
};
|
|
47
61
|
const buildEditable = (fieldName, uuid) => {
|
|
48
62
|
const host = getHost(uuid);
|
|
49
63
|
if (!host) {
|
|
50
64
|
return;
|
|
51
65
|
}
|
|
52
|
-
|
|
53
|
-
const hostEntityBundle = "bundle" in host ? host.bundle : host.itemBundle;
|
|
54
|
-
if (hostEntityBundle === "from_library") {
|
|
66
|
+
if (host.bundle === "from_library") {
|
|
55
67
|
return;
|
|
56
68
|
}
|
|
57
69
|
const config = types.editableFieldConfig.forName(
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
host.type,
|
|
71
|
+
host.bundle,
|
|
60
72
|
fieldName
|
|
61
73
|
);
|
|
62
74
|
if (!config) {
|
|
63
|
-
let message = `Failed to load editable field config for field "${fieldName}" on entity type "${
|
|
75
|
+
let message = `Failed to load editable field config for field "${fieldName}" on entity type "${host.type}" of bundle "${host.bundle}"`;
|
|
64
76
|
if (uuid) {
|
|
65
77
|
message += ` with uuid "${uuid}"`;
|
|
66
78
|
}
|
|
@@ -69,10 +81,7 @@ const buildEditable = (fieldName, uuid) => {
|
|
|
69
81
|
if (config.type === "frame" && !adapter.buildEditableFrameUrl) {
|
|
70
82
|
return;
|
|
71
83
|
}
|
|
72
|
-
const
|
|
73
|
-
const element = hostElement.querySelector(
|
|
74
|
-
`[data-blokkli-editable-field="${fieldName}"]`
|
|
75
|
-
);
|
|
84
|
+
const element = directive.findEditableElement(fieldName, host);
|
|
76
85
|
if (!(element instanceof HTMLElement)) {
|
|
77
86
|
return;
|
|
78
87
|
}
|
|
@@ -89,30 +98,19 @@ onBlokkliEvent("editable:focus", (e) => {
|
|
|
89
98
|
if (!state.canEdit.value) {
|
|
90
99
|
return;
|
|
91
100
|
}
|
|
92
|
-
hasTransition.value = !
|
|
93
|
-
|
|
94
|
-
if (
|
|
101
|
+
hasTransition.value = !selectedEditable.value;
|
|
102
|
+
selectedEditable.value = buildEditable(e.fieldName, e.uuid) || null;
|
|
103
|
+
if (selectedEditable.value) {
|
|
95
104
|
selection.editableActive.value = true;
|
|
96
105
|
}
|
|
97
106
|
});
|
|
98
107
|
defineCommands(() => {
|
|
99
|
-
|
|
100
|
-
return [
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (!(block instanceof HTMLElement)) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
if (block.dataset.uuid !== v.uuid) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const name = el.dataset.blokkliEditableField;
|
|
112
|
-
if (!name) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
return buildEditable(name, block.dataset.uuid);
|
|
108
|
+
if (selection.items.value.length > 5) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
const editables = selection.items.value.flatMap((item) => {
|
|
112
|
+
return directive.getEditablesForBlock(item.uuid).map((v) => {
|
|
113
|
+
return buildEditable(v.fieldName, item.uuid);
|
|
116
114
|
}).filter(falsy);
|
|
117
115
|
});
|
|
118
116
|
return editables.map((v) => {
|
|
@@ -126,7 +124,7 @@ defineCommands(() => {
|
|
|
126
124
|
icon: "textbox",
|
|
127
125
|
disabled: false,
|
|
128
126
|
callback: () => {
|
|
129
|
-
|
|
127
|
+
selectedEditable.value = v;
|
|
130
128
|
}
|
|
131
129
|
};
|
|
132
130
|
});
|
|
@@ -134,16 +132,16 @@ defineCommands(() => {
|
|
|
134
132
|
watch(selection.editableActive, (isActive) => {
|
|
135
133
|
if (!isActive) {
|
|
136
134
|
hasTransition.value = true;
|
|
137
|
-
|
|
135
|
+
selectedEditable.value = null;
|
|
138
136
|
}
|
|
139
137
|
});
|
|
140
|
-
watch(
|
|
138
|
+
watch(selectedEditable, (v) => {
|
|
141
139
|
if (!v && selection.editableActive.value) {
|
|
142
140
|
selection.editableActive.value = false;
|
|
143
141
|
}
|
|
144
142
|
});
|
|
145
143
|
const close = () => {
|
|
146
|
-
|
|
144
|
+
selectedEditable.value = null;
|
|
147
145
|
selection.editableActive.value = false;
|
|
148
146
|
};
|
|
149
147
|
</script>
|
|
@@ -37,14 +37,16 @@
|
|
|
37
37
|
<ul class="bk-library-dialog-list">
|
|
38
38
|
<li
|
|
39
39
|
v-for="(item, index) in fragments"
|
|
40
|
+
v-show="visible === null || visible.includes(item.name)"
|
|
41
|
+
ref="itemElements"
|
|
40
42
|
:key="item.name"
|
|
41
43
|
:class="{
|
|
42
44
|
'bk-is-selected': selectedItem === item.name
|
|
43
45
|
}"
|
|
46
|
+
:data-bk-fragment-name="item.name"
|
|
44
47
|
@click="selectedItem = item.name"
|
|
45
48
|
>
|
|
46
49
|
<FragmentItem
|
|
47
|
-
v-show="visible === null || visible.includes(item.name)"
|
|
48
50
|
:name="item.name"
|
|
49
51
|
:label="item.label"
|
|
50
52
|
:description="item.description"
|
|
@@ -65,7 +67,7 @@
|
|
|
65
67
|
<script setup>
|
|
66
68
|
import { FormOverlay } from "#blokkli/components";
|
|
67
69
|
import { falsy } from "#blokkli/helpers";
|
|
68
|
-
import { ref, useBlokkli, computed, watch } from "#imports";
|
|
70
|
+
import { ref, useBlokkli, computed, watch, useTemplateRef } from "#imports";
|
|
69
71
|
import FragmentItem from "./Item/index.vue";
|
|
70
72
|
const props = defineProps({
|
|
71
73
|
field: { type: Object, required: true }
|
|
@@ -73,7 +75,7 @@ const props = defineProps({
|
|
|
73
75
|
const { $t, definitions } = useBlokkli();
|
|
74
76
|
const emit = defineEmits(["close", "submit"]);
|
|
75
77
|
const searchText = ref("");
|
|
76
|
-
const
|
|
78
|
+
const itemElements = useTemplateRef("itemElements");
|
|
77
79
|
const selectedItem = ref("");
|
|
78
80
|
const allowedInField = computed(() => props.field.allowedFragments || []);
|
|
79
81
|
const fragments = computed(
|
|
@@ -91,15 +93,15 @@ const onClose = () => {
|
|
|
91
93
|
};
|
|
92
94
|
const elements = ref([]);
|
|
93
95
|
const buildElements = () => {
|
|
94
|
-
if (!
|
|
96
|
+
if (!itemElements.value) {
|
|
95
97
|
return;
|
|
96
98
|
}
|
|
97
|
-
elements.value =
|
|
99
|
+
elements.value = itemElements.value.map((el) => {
|
|
98
100
|
if (el instanceof HTMLElement) {
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
101
|
+
const name = el.dataset.bkFragmentName;
|
|
102
|
+
if (name) {
|
|
101
103
|
return {
|
|
102
|
-
|
|
104
|
+
name,
|
|
103
105
|
text: el.textContent?.toLowerCase() || ""
|
|
104
106
|
};
|
|
105
107
|
}
|
|
@@ -115,6 +117,6 @@ const visible = computed(() => {
|
|
|
115
117
|
if (!searchText.value || !elements.value.length) {
|
|
116
118
|
return null;
|
|
117
119
|
}
|
|
118
|
-
return elements.value.filter((v) => v.text.includes(searchText.value.toLowerCase())).map((v) => v.
|
|
120
|
+
return elements.value.filter((v) => v.text.includes(searchText.value.toLowerCase())).map((v) => v.name);
|
|
119
121
|
});
|
|
120
122
|
</script>
|
|
@@ -45,9 +45,9 @@ const { adapter } = defineBlokkliFeature({
|
|
|
45
45
|
});
|
|
46
46
|
const { state, $t, types, selection, dom } = useBlokkli();
|
|
47
47
|
const isEnabled = computed(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const field = dom.
|
|
48
|
+
const item = selection.item.value;
|
|
49
|
+
if (item) {
|
|
50
|
+
const field = dom.getRegisteredField(item.host.uuid, item.host.fieldName);
|
|
51
51
|
return !!field?.allowedFragments.length;
|
|
52
52
|
}
|
|
53
53
|
return true;
|
|
@@ -14,9 +14,8 @@ import { toShaderColor, isInsideRect } from "#blokkli/helpers";
|
|
|
14
14
|
const props = defineProps({
|
|
15
15
|
gl: { type: null, required: true }
|
|
16
16
|
});
|
|
17
|
-
const { animation, theme, dom, selection, state, ui,
|
|
17
|
+
const { animation, theme, dom, selection, state, ui, directive, blocks } = useBlokkli();
|
|
18
18
|
const programInfo = animation.registerProgram("hover", props.gl, [vs, fs]);
|
|
19
|
-
const DEBUG = false;
|
|
20
19
|
const MAX_RECTS = 11;
|
|
21
20
|
function getDeepestUuid(uuids) {
|
|
22
21
|
if (uuids.length === 0) {
|
|
@@ -90,18 +89,14 @@ function updateHoverState(mouseX, mouseY, offset, scale, artboardSize) {
|
|
|
90
89
|
};
|
|
91
90
|
const isOutsideArtboard = mouseX < artboardRect.x || mouseX > artboardRect.x + artboardRect.width || mouseY < artboardRect.y || mouseY > artboardRect.y + artboardRect.height;
|
|
92
91
|
if (isOutsideArtboard) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
return false;
|
|
92
|
+
const needsUpdate = previousHoveredUuids.length > 0 || previousEditableFieldRect !== null || isHoveringEditableField.value || isHoveringSelectedBlock.value;
|
|
93
|
+
hoverState.visible.fill(0);
|
|
94
|
+
isHoveringEditableField.value = false;
|
|
95
|
+
isHoveringSelectedBlock.value = false;
|
|
96
|
+
previousHoveredUuids = [];
|
|
97
|
+
previousDeepestUuid = null;
|
|
98
|
+
previousEditableFieldRect = null;
|
|
99
|
+
return needsUpdate;
|
|
105
100
|
}
|
|
106
101
|
const artboardMouseX = mouseX / scale - offset.x / scale;
|
|
107
102
|
const artboardMouseY = mouseY / scale - offset.y / scale;
|
|
@@ -132,7 +127,7 @@ function updateHoverState(mouseX, mouseY, offset, scale, artboardSize) {
|
|
|
132
127
|
(uuid, i) => uuid !== previousHoveredUuids[i]
|
|
133
128
|
) || deepestUuid !== previousDeepestUuid;
|
|
134
129
|
let hoveredEditableFieldRect = null;
|
|
135
|
-
const editableRects =
|
|
130
|
+
const editableRects = directive.getVisible("editable");
|
|
136
131
|
for (let i = 0; i < editableRects.length; i++) {
|
|
137
132
|
const editableRect = editableRects[i];
|
|
138
133
|
if (isInsideRect(artboardMouseX, artboardMouseY, editableRect)) {
|
|
@@ -140,7 +135,7 @@ function updateHoverState(mouseX, mouseY, offset, scale, artboardSize) {
|
|
|
140
135
|
break;
|
|
141
136
|
}
|
|
142
137
|
}
|
|
143
|
-
if (!hoveredChanged
|
|
138
|
+
if (!hoveredChanged) {
|
|
144
139
|
const editableFieldChanged = hoveredEditableFieldRect === null !== (previousEditableFieldRect === null) || hoveredEditableFieldRect && previousEditableFieldRect && (hoveredEditableFieldRect.x !== previousEditableFieldRect.x || hoveredEditableFieldRect.y !== previousEditableFieldRect.y || hoveredEditableFieldRect.width !== previousEditableFieldRect.width || hoveredEditableFieldRect.height !== previousEditableFieldRect.height);
|
|
145
140
|
if (!editableFieldChanged) {
|
|
146
141
|
return false;
|
|
@@ -158,7 +153,7 @@ function updateHoverState(mouseX, mouseY, offset, scale, artboardSize) {
|
|
|
158
153
|
}
|
|
159
154
|
for (const [level, uuid] of nestingMap) {
|
|
160
155
|
const rect = dom.getBlockRect(uuid);
|
|
161
|
-
const block =
|
|
156
|
+
const block = blocks.getBlock(uuid);
|
|
162
157
|
if (!rect || !block) continue;
|
|
163
158
|
const el = dom.getDragElement(block);
|
|
164
159
|
if (!el) continue;
|
|
@@ -197,15 +192,11 @@ function updateHoverState(mouseX, mouseY, offset, scale, artboardSize) {
|
|
|
197
192
|
hoverState.types[10] = 2;
|
|
198
193
|
hoverState.visible[10] = 1;
|
|
199
194
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
previousEditableFieldRect = hoveredEditableFieldRect;
|
|
204
|
-
}
|
|
195
|
+
previousHoveredUuids = unselectedHoveredUuids;
|
|
196
|
+
previousDeepestUuid = deepestUuid;
|
|
197
|
+
previousEditableFieldRect = hoveredEditableFieldRect;
|
|
205
198
|
isHoveringEditableField.value = hoveredEditableFieldRect !== null;
|
|
206
|
-
isHoveringSelectedBlock.value =
|
|
207
|
-
(uuid) => selectedUuids.includes(uuid)
|
|
208
|
-
);
|
|
199
|
+
isHoveringSelectedBlock.value = deepestUuid !== null && selectedUuids.includes(deepestUuid);
|
|
209
200
|
return true;
|
|
210
201
|
}
|
|
211
202
|
const uniforms = computed(() => {
|
|
@@ -46,16 +46,15 @@ const props = defineProps({
|
|
|
46
46
|
uuid: { type: String, required: true },
|
|
47
47
|
label: { type: String, required: false }
|
|
48
48
|
});
|
|
49
|
+
const { $t, element } = useBlokkli();
|
|
49
50
|
const DURATION = 530;
|
|
50
51
|
const emit = defineEmits(["submit", "close"]);
|
|
51
52
|
function getOriginatingElement() {
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
return element.query(
|
|
54
|
+
document.documentElement,
|
|
55
|
+
`[data-bk-library-item-uuid="${props.uuid}"]`,
|
|
56
|
+
"Get originating library item element"
|
|
54
57
|
);
|
|
55
|
-
if (el instanceof HTMLElement) {
|
|
56
|
-
return el;
|
|
57
|
-
}
|
|
58
|
-
return null;
|
|
59
58
|
}
|
|
60
59
|
function onEnter(el, done) {
|
|
61
60
|
if (el instanceof HTMLElement) {
|
|
@@ -125,7 +124,6 @@ function onAfterLeave(el) {
|
|
|
125
124
|
emit("close");
|
|
126
125
|
}
|
|
127
126
|
}
|
|
128
|
-
const { $t } = useBlokkli();
|
|
129
127
|
const iframe = ref(null);
|
|
130
128
|
const isLoaded = ref(false);
|
|
131
129
|
const isLoading = ref(true);
|