@blokkli/editor 2.0.0-alpha.16 → 2.0.0-alpha.17
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 +265 -83
- package/dist/modules/drupal/graphql/base/fragment.blokkliProps.graphql +1 -1
- package/dist/modules/drupal/graphql/features/comments.graphql +11 -8
- package/dist/modules/drupal/runtime/adapter/index.js +2 -2
- package/dist/runtime/blokkliPlugins/ItemAction/index.vue +1 -3
- package/dist/runtime/components/Blocks/FromLibrary/index.vue +4 -2
- package/dist/runtime/components/BlokkliEditable.vue +22 -4
- package/dist/runtime/components/BlokkliProvider.vue +29 -20
- package/dist/runtime/components/BlokkliProvider.vue.d.ts +2 -1
- package/dist/runtime/components/Edit/Actions/index.vue +9 -4
- package/dist/runtime/components/Edit/AnimationCanvas/index.vue +420 -25
- package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +80 -0
- package/dist/runtime/components/Edit/ArtboardTooltip/index.vue.d.ts +32 -0
- package/dist/runtime/components/Edit/Banner/index.vue +51 -0
- package/dist/runtime/components/Edit/Banner/index.vue.d.ts +18 -0
- package/dist/runtime/components/Edit/EditIndicator.vue +118 -44
- package/dist/runtime/components/Edit/EditIndicator.vue.d.ts +3 -0
- package/dist/runtime/components/Edit/EditProvider.vue +79 -22
- package/dist/runtime/components/Edit/EditProvider.vue.d.ts +2 -0
- package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +19 -20
- package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +2 -0
- package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue +35 -20
- package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue.d.ts +5 -3
- package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue +29 -0
- package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue.d.ts +13 -0
- package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue +22 -16
- package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue.d.ts +1 -0
- package/dist/runtime/components/Edit/Features/Comments/Overlay/index.vue +15 -6
- package/dist/runtime/components/Edit/Features/Comments/index.vue +20 -8
- package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +26 -35
- package/dist/runtime/components/Edit/Features/Debug/Renderer.vue +240 -0
- package/dist/runtime/components/Edit/Features/Debug/Renderer.vue.d.ts +6 -0
- package/dist/runtime/components/Edit/Features/Debug/index.vue +4 -165
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +41 -37
- package/dist/runtime/components/Edit/Features/Edit/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +63 -3
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/Plaintext/index.vue +13 -9
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +17 -76
- package/dist/runtime/components/Edit/Features/EditableField/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/History/index.vue +5 -2
- package/dist/runtime/components/Edit/Features/Hover/Overlay/fragment.glsl +139 -0
- package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +270 -0
- package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue.d.ts +6 -0
- package/dist/runtime/components/Edit/Features/Hover/Overlay/vertex.glsl +117 -0
- package/dist/runtime/components/Edit/Features/Hover/index.vue +25 -0
- package/dist/runtime/components/Edit/Features/Library/LibraryDialog/index.vue +19 -27
- package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +27 -23
- package/dist/runtime/components/Edit/Features/Library/index.vue +2 -1
- package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +34 -27
- package/dist/runtime/components/Edit/Features/MultiSelect/index.vue +2 -4
- package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +6 -1
- package/dist/runtime/components/Edit/Features/Options/Form/index.vue +1 -0
- package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue +35 -0
- package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue.d.ts +6 -0
- package/dist/runtime/components/Edit/Features/Ownership/index.vue +7 -25
- package/dist/runtime/components/Edit/Features/ProxyView/index.vue +5 -1
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +39 -74
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +4 -2
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/fragment.glsl +106 -0
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +417 -0
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue.d.ts +32 -0
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/vertex.glsl +102 -0
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +33 -106
- package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +88 -29
- package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +2 -0
- package/dist/runtime/components/Edit/Features/Selection/Overlay/vertex.glsl +11 -2
- package/dist/runtime/components/Edit/Features/Selection/index.vue +5 -12
- package/dist/runtime/components/Edit/Features/Translations/Banner/index.vue +17 -11
- package/dist/runtime/components/Edit/Features/Translations/index.vue +13 -16
- package/dist/runtime/components/Edit/Form/Text/index.vue +2 -1
- package/dist/runtime/components/Edit/Form/Text/index.vue.d.ts +1 -0
- package/dist/runtime/components/Edit/Indicators/index.vue +1 -1
- package/dist/runtime/components/Edit/Konami/Game/index.vue +5 -5
- package/dist/runtime/components/Edit/index.d.ts +5 -3
- package/dist/runtime/components/Edit/index.js +8 -4
- package/dist/runtime/composables/defineBlokkli.js +4 -2
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/animationProvider.d.ts +34 -1
- package/dist/runtime/helpers/animationProvider.js +175 -48
- package/dist/runtime/helpers/composables/defineRenderer.d.ts +8 -0
- package/dist/runtime/helpers/composables/defineRenderer.js +8 -0
- package/dist/runtime/helpers/composables/useStickyToolbar.d.ts +4 -1
- package/dist/runtime/helpers/composables/useStickyToolbar.js +53 -35
- package/dist/runtime/helpers/dom/index.d.ts +1 -0
- package/dist/runtime/helpers/domProvider.d.ts +46 -0
- package/dist/runtime/helpers/domProvider.js +95 -6
- package/dist/runtime/helpers/editableProvider.d.ts +14 -0
- package/dist/runtime/helpers/editableProvider.js +144 -0
- package/dist/runtime/helpers/stateProvider.d.ts +6 -2
- package/dist/runtime/helpers/stateProvider.js +66 -3
- package/dist/runtime/helpers/storageProvider.d.ts +3 -2
- package/dist/runtime/helpers/storageProvider.js +6 -2
- package/dist/runtime/helpers/symbols.d.ts +1 -0
- package/dist/runtime/helpers/symbols.js +1 -0
- package/dist/runtime/helpers/uiProvider.d.ts +8 -1
- package/dist/runtime/helpers/uiProvider.js +34 -2
- package/dist/runtime/plugins/blokkliEditable.js +74 -3
- package/dist/runtime/types/index.d.ts +13 -1
- package/package.json +1 -1
- package/dist/runtime/components/Edit/DragInteractions/index.vue +0 -401
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue +0 -54
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue.d.ts +0 -14
- /package/dist/runtime/components/Edit/{DragInteractions → Features/Hover}/index.vue.d.ts +0 -0
|
@@ -23,36 +23,40 @@
|
|
|
23
23
|
)
|
|
24
24
|
"
|
|
25
25
|
/>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
<FormItem>
|
|
27
|
+
<FormText
|
|
28
|
+
id="reusable_label"
|
|
29
|
+
v-model="label"
|
|
30
|
+
:label="$t('libraryDialogDescriptionLabel', 'Description')"
|
|
31
|
+
type="text"
|
|
32
|
+
:placeholder="
|
|
33
|
+
$t(
|
|
34
|
+
'libraryDialogTitleInputPlaceholder',
|
|
35
|
+
'e.g. Teaser Campaign 2024'
|
|
36
|
+
)
|
|
36
37
|
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
38
|
+
required
|
|
39
|
+
/>
|
|
40
|
+
</FormItem>
|
|
41
|
+
<FormItem>
|
|
42
|
+
<div class="bk-form-label">
|
|
43
|
+
{{ $t("libraryPreviewLabel", "Preview") }}
|
|
44
|
+
</div>
|
|
45
|
+
<div
|
|
46
|
+
class="bk-dialog-content-element"
|
|
47
|
+
:class="[backgroundClass, { 'bk-default-bg': !backgroundClass }]"
|
|
48
|
+
:style="backgroundClass ? {} : { backgroundColor }"
|
|
49
|
+
>
|
|
50
|
+
<div ref="previewEl" />
|
|
51
|
+
</div>
|
|
52
|
+
</FormItem>
|
|
49
53
|
</div>
|
|
50
54
|
</DialogModal>
|
|
51
55
|
</template>
|
|
52
56
|
|
|
53
57
|
<script setup>
|
|
54
58
|
import { ref, useBlokkli, onMounted } from "#imports";
|
|
55
|
-
import { DialogModal, InfoBox } from "#blokkli/components";
|
|
59
|
+
import { DialogModal, InfoBox, FormText, FormItem } from "#blokkli/components";
|
|
56
60
|
import { realBackgroundColor } from "#blokkli/helpers";
|
|
57
61
|
defineEmits(["confirm", "cancel"]);
|
|
58
62
|
const { dom, $t } = useBlokkli();
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
id="library_detach"
|
|
5
5
|
:title="$t('libraryDetach', 'Detach from library')"
|
|
6
6
|
icon="detach"
|
|
7
|
+
:disabled="state.editMode.value !== 'editing'"
|
|
7
8
|
multiple
|
|
8
9
|
:weight="-70"
|
|
9
10
|
@click="onDetach"
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
<PluginItemAction
|
|
12
13
|
v-else-if="!isReusable"
|
|
13
14
|
id="library_make_reusable"
|
|
14
|
-
:title="$t('libraryAdd', 'Add to library')"
|
|
15
|
+
:title="$t('libraryAdd', 'Add to library...')"
|
|
15
16
|
:disabled="!canMakeReusable || state.editMode.value !== 'editing'"
|
|
16
17
|
icon="reusable"
|
|
17
18
|
:weight="-70"
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<script setup>
|
|
8
8
|
import { useBlokkli, onBeforeUnmount } from "#imports";
|
|
9
9
|
import { intersects, toShaderColor } from "#blokkli/helpers";
|
|
10
|
-
import
|
|
10
|
+
import defineRenderer from "#blokkli/helpers/composables/defineRenderer";
|
|
11
11
|
import vs from "./vertex.glsl?raw";
|
|
12
12
|
import fs from "./fragment.glsl?raw";
|
|
13
13
|
import {
|
|
@@ -181,32 +181,40 @@ function getSelectRect(offset, scale) {
|
|
|
181
181
|
};
|
|
182
182
|
return { shader, check };
|
|
183
183
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
184
|
+
defineRenderer("multiselect-overlay", {
|
|
185
|
+
zIndex: 450,
|
|
186
|
+
only: true,
|
|
187
|
+
cursor: () => "crosshair",
|
|
188
|
+
render: (ctx) => {
|
|
189
|
+
mouseX = ctx.mouseX;
|
|
190
|
+
mouseY = ctx.mouseY;
|
|
191
|
+
const { shader, check } = getSelectRect(
|
|
192
|
+
ctx.artboardOffset,
|
|
193
|
+
ctx.artboardScale
|
|
194
|
+
);
|
|
195
|
+
const { nested } = collector.getSelectedUuids(check);
|
|
196
|
+
const shouldSelectAll = props.isPressingControl || !nested.length;
|
|
197
|
+
ctx.gl.useProgram(programInfo.program);
|
|
198
|
+
const time = (Date.now() - startTimestamp) / 1e3;
|
|
199
|
+
setUniforms(programInfo, uniforms);
|
|
200
|
+
setUniforms(programInfo, {
|
|
201
|
+
u_select_all: shouldSelectAll ? 1 : 0,
|
|
202
|
+
u_select_rect: [shader.x, shader.y, shader.width, shader.height],
|
|
203
|
+
u_time: time
|
|
204
|
+
});
|
|
205
|
+
animation.setSharedUniforms(ctx.gl, programInfo);
|
|
206
|
+
const { info, hasChanged } = collector.getBufferInfo(
|
|
207
|
+
ctx.artboardOffset,
|
|
208
|
+
ctx.artboardScale
|
|
209
|
+
);
|
|
210
|
+
if (!info) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (hasChanged) {
|
|
214
|
+
setBuffersAndAttributes(ctx.gl, programInfo, info);
|
|
215
|
+
}
|
|
216
|
+
drawBufferInfo(ctx.gl, info, ctx.gl.TRIANGLES);
|
|
208
217
|
}
|
|
209
|
-
drawBufferInfo(props.gl, info, props.gl.TRIANGLES);
|
|
210
218
|
});
|
|
211
219
|
function getUuidsToSelect() {
|
|
212
220
|
const { check } = getSelectRect(
|
|
@@ -222,7 +230,6 @@ function getUuidsToSelect() {
|
|
|
222
230
|
return nested;
|
|
223
231
|
}
|
|
224
232
|
onBeforeUnmount(() => {
|
|
225
|
-
props.gl.clear(props.gl.COLOR_BUFFER_BIT);
|
|
226
233
|
const diff = Date.now() - startTimestamp;
|
|
227
234
|
if (diff > 175) {
|
|
228
235
|
eventBus.emit("select:end", getUuidsToSelect());
|
|
@@ -20,11 +20,9 @@ defineBlokkliFeature({
|
|
|
20
20
|
description: "Implements support for selecting multiple blocks using a select rectangle.",
|
|
21
21
|
viewports: ["desktop"]
|
|
22
22
|
});
|
|
23
|
-
const { keyboard, eventBus, selection,
|
|
23
|
+
const { keyboard, eventBus, selection, animation } = useBlokkli();
|
|
24
24
|
const gl = animation.gl();
|
|
25
|
-
const enabled = computed(
|
|
26
|
-
() => !selection.editableActive.value && (state.editMode.value === "editing" || state.editMode.value === "translating") && gl
|
|
27
|
-
);
|
|
25
|
+
const enabled = computed(() => !selection.editableActive.value && gl);
|
|
28
26
|
const shouldRender = ref(false);
|
|
29
27
|
const downX = ref(0);
|
|
30
28
|
const downY = ref(0);
|
|
@@ -113,7 +113,12 @@ const showLabel = computed(() => {
|
|
|
113
113
|
const label = computed(
|
|
114
114
|
() => $blokkliText(`blockOption_${props.property}_label`, props.option.label)
|
|
115
115
|
);
|
|
116
|
-
const description = computed(
|
|
116
|
+
const description = computed(
|
|
117
|
+
() => $blokkliText(
|
|
118
|
+
`blockOption_${props.property}_description`,
|
|
119
|
+
props.option.description
|
|
120
|
+
)
|
|
121
|
+
);
|
|
117
122
|
const checkboxOptions = computed(() => {
|
|
118
123
|
if (props.option.type !== "checkboxes") {
|
|
119
124
|
return [];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Banner
|
|
3
|
+
id="ownership"
|
|
4
|
+
icon="user"
|
|
5
|
+
:text
|
|
6
|
+
:button="$t('ownershipTakeOwnership', 'Assign to me')"
|
|
7
|
+
@click="$emit('submit')"
|
|
8
|
+
/>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup>
|
|
12
|
+
import { computed, useBlokkli, onMounted, onBeforeUnmount } from "#imports";
|
|
13
|
+
import { Banner } from "#blokkli/components";
|
|
14
|
+
defineEmits(["submit"]);
|
|
15
|
+
const { state, $t, ui } = useBlokkli();
|
|
16
|
+
const name = computed(() => {
|
|
17
|
+
const v = state.owner.value?.name;
|
|
18
|
+
if (v) {
|
|
19
|
+
return `<strong>${v}</strong>`;
|
|
20
|
+
}
|
|
21
|
+
return "";
|
|
22
|
+
});
|
|
23
|
+
const text = computed(() => {
|
|
24
|
+
return $t(
|
|
25
|
+
"ownershipNote",
|
|
26
|
+
"This page is currently being edited by @name. Changes can only be made by one person at a time."
|
|
27
|
+
).replace("@name", name.value);
|
|
28
|
+
});
|
|
29
|
+
onMounted(() => {
|
|
30
|
+
ui.setSelectionColor("ownership", "mono");
|
|
31
|
+
});
|
|
32
|
+
onBeforeUnmount(() => {
|
|
33
|
+
ui.removeSelectionColor("ownership");
|
|
34
|
+
});
|
|
35
|
+
</script>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
2
|
+
submit: () => any;
|
|
3
|
+
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
4
|
+
onSubmit?: (() => any) | undefined;
|
|
5
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
6
|
+
export default _default;
|
|
@@ -1,26 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Teleport to="
|
|
3
|
-
<
|
|
4
|
-
v-if="!state.owner.value?.currentUserIsOwner"
|
|
5
|
-
class="bk-owner-indicator"
|
|
6
|
-
>
|
|
7
|
-
<p
|
|
8
|
-
v-html="
|
|
9
|
-
$t(
|
|
10
|
-
'ownershipNote',
|
|
11
|
-
'This page is currently being edited by @name. Changes can only be made by one person at a time.'
|
|
12
|
-
).replace('@name', name)
|
|
13
|
-
"
|
|
14
|
-
/>
|
|
15
|
-
<button class="bk-button bk-is-danger" @click="takeOwnership">
|
|
16
|
-
{{ $t("ownershipTakeOwnership", "Assign to me") }}
|
|
17
|
-
</button>
|
|
18
|
-
</div>
|
|
2
|
+
<Teleport to="#bk-banner-list">
|
|
3
|
+
<Renderer v-if="shouldRender" @submit="takeOwnership" />
|
|
19
4
|
</Teleport>
|
|
20
5
|
</template>
|
|
21
6
|
|
|
22
7
|
<script setup>
|
|
23
|
-
import {
|
|
8
|
+
import { useBlokkli, defineBlokkliFeature, computed } from "#imports";
|
|
9
|
+
import Renderer from "./Renderer.vue";
|
|
24
10
|
const { adapter } = defineBlokkliFeature({
|
|
25
11
|
id: "ownership",
|
|
26
12
|
icon: "user",
|
|
@@ -29,18 +15,14 @@ const { adapter } = defineBlokkliFeature({
|
|
|
29
15
|
description: "Renders a large button to take ownership of the current edit state."
|
|
30
16
|
});
|
|
31
17
|
const { state, $t } = useBlokkli();
|
|
18
|
+
const shouldRender = computed(
|
|
19
|
+
() => !state.owner.value?.currentUserIsOwner && state.permissions.value.includes("edit")
|
|
20
|
+
);
|
|
32
21
|
const takeOwnership = () => state.mutateWithLoadingState(
|
|
33
22
|
() => adapter.takeOwnership(),
|
|
34
23
|
$t("ownershipError", "Error in assigning"),
|
|
35
24
|
$t("ownershipSuccess", "You are now the owner.")
|
|
36
25
|
);
|
|
37
|
-
const name = computed(() => {
|
|
38
|
-
const v = state.owner.value?.name;
|
|
39
|
-
if (v) {
|
|
40
|
-
return `<strong>${v}</strong>`;
|
|
41
|
-
}
|
|
42
|
-
return "";
|
|
43
|
-
});
|
|
44
26
|
</script>
|
|
45
27
|
|
|
46
28
|
<script>
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"
|
|
14
14
|
key-code="P"
|
|
15
15
|
icon="tree"
|
|
16
|
+
@update:model-value="onToggleProxyMode"
|
|
16
17
|
/>
|
|
17
18
|
</template>
|
|
18
19
|
|
|
@@ -26,7 +27,10 @@ defineBlokkliFeature({
|
|
|
26
27
|
description: "Displays the blocks as a structure in the preview.",
|
|
27
28
|
viewports: ["desktop"]
|
|
28
29
|
});
|
|
29
|
-
const { $t, ui } = useBlokkli();
|
|
30
|
+
const { $t, ui, eventBus } = useBlokkli();
|
|
31
|
+
function onToggleProxyMode() {
|
|
32
|
+
eventBus.emit("state:reloaded");
|
|
33
|
+
}
|
|
30
34
|
</script>
|
|
31
35
|
|
|
32
36
|
<script>
|
|
@@ -1,86 +1,57 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
:
|
|
6
|
-
:
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
<ArtboardTooltip
|
|
3
|
+
id="add-buttons"
|
|
4
|
+
:title="label"
|
|
5
|
+
:anchor-el
|
|
6
|
+
:anchor-coordinates
|
|
7
|
+
class="bk-selection-add-overlay"
|
|
8
|
+
@close="$emit('close')"
|
|
9
9
|
>
|
|
10
|
-
<div
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@wheel="onWheel"
|
|
10
|
+
<div
|
|
11
|
+
ref="listEl"
|
|
12
|
+
class="bk-selection-add-overlay-list bk-scrollbar-dark"
|
|
13
|
+
@wheel="onWheel"
|
|
14
|
+
>
|
|
15
|
+
<button
|
|
16
|
+
v-for="item in items"
|
|
17
|
+
:key="item.bundle"
|
|
18
|
+
tabindex="-1"
|
|
19
|
+
@click.prevent="$emit('select', item.bundle)"
|
|
21
20
|
>
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
tabindex="-1"
|
|
38
|
-
@click.prevent="$emit('action', action.id)"
|
|
39
|
-
>
|
|
40
|
-
<AddListItemIcon :icon="action.icon" :color="action.color" />
|
|
41
|
-
<span>{{ action.title }}</span>
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
21
|
+
<AddListItemIcon
|
|
22
|
+
:bundle="item.bundle"
|
|
23
|
+
:color="item.isFavorite ? 'yellow' : 'default'"
|
|
24
|
+
/>
|
|
25
|
+
<span>{{ item.label }}</span>
|
|
26
|
+
</button>
|
|
27
|
+
<button
|
|
28
|
+
v-for="action in actions"
|
|
29
|
+
:key="'action:' + action.id"
|
|
30
|
+
tabindex="-1"
|
|
31
|
+
@click.prevent="$emit('action', action.id)"
|
|
32
|
+
>
|
|
33
|
+
<AddListItemIcon :icon="action.icon" :color="action.color" />
|
|
34
|
+
<span>{{ action.title }}</span>
|
|
35
|
+
</button>
|
|
44
36
|
</div>
|
|
45
|
-
</
|
|
37
|
+
</ArtboardTooltip>
|
|
46
38
|
</template>
|
|
47
39
|
|
|
48
40
|
<script setup>
|
|
49
|
-
import
|
|
50
|
-
import {
|
|
51
|
-
useTemplateRef,
|
|
52
|
-
useBlokkli,
|
|
53
|
-
computed,
|
|
54
|
-
onMounted,
|
|
55
|
-
onBeforeUnmount
|
|
56
|
-
} from "#imports";
|
|
57
|
-
import { Icon, AddListItemIcon } from "#blokkli/components";
|
|
41
|
+
import { useTemplateRef, useBlokkli, computed } from "#imports";
|
|
42
|
+
import { AddListItemIcon, ArtboardTooltip } from "#blokkli/components";
|
|
58
43
|
import { isInternalBundle } from "#blokkli/helpers/bundles";
|
|
59
44
|
const props = defineProps({
|
|
60
45
|
bundles: { type: Array, required: true },
|
|
61
|
-
anchorEl: { type: null, required:
|
|
62
|
-
|
|
46
|
+
anchorEl: { type: null, required: false },
|
|
47
|
+
anchorCoordinates: { type: Object, required: false },
|
|
48
|
+
label: { type: String, required: true }
|
|
63
49
|
});
|
|
64
50
|
defineEmits(["select", "action", "close"]);
|
|
65
|
-
const el = useTemplateRef("el");
|
|
66
51
|
const listEl = useTemplateRef("listEl");
|
|
67
52
|
let hasScrollbar = null;
|
|
68
|
-
const { types,
|
|
53
|
+
const { types, plugins, storage } = useBlokkli();
|
|
69
54
|
const favorites = storage.use("blockFavorites", []);
|
|
70
|
-
const { placementY, caretX } = useStickyToolbar(el, {
|
|
71
|
-
getAnchorElement() {
|
|
72
|
-
return props.anchorEl;
|
|
73
|
-
},
|
|
74
|
-
getPlacementY() {
|
|
75
|
-
return "auto";
|
|
76
|
-
},
|
|
77
|
-
getPlacementX() {
|
|
78
|
-
return "center";
|
|
79
|
-
},
|
|
80
|
-
getCaretWidth() {
|
|
81
|
-
return 30;
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
55
|
const items = computed(() => {
|
|
85
56
|
return props.bundles.filter((bundle) => !isInternalBundle(bundle)).map((bundle) => {
|
|
86
57
|
return {
|
|
@@ -111,10 +82,4 @@ const onWheel = (e) => {
|
|
|
111
82
|
e.stopPropagation();
|
|
112
83
|
}
|
|
113
84
|
};
|
|
114
|
-
onMounted(() => {
|
|
115
|
-
ui.hasAddTooltipOpen.value = true;
|
|
116
|
-
});
|
|
117
|
-
onBeforeUnmount(() => {
|
|
118
|
-
ui.hasAddTooltipOpen.value = false;
|
|
119
|
-
});
|
|
120
85
|
</script>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { Coord } from '#blokkli/types';
|
|
1
2
|
type __VLS_Props = {
|
|
2
3
|
bundles: string[];
|
|
3
|
-
anchorEl
|
|
4
|
-
|
|
4
|
+
anchorEl?: HTMLElement;
|
|
5
|
+
anchorCoordinates?: Coord;
|
|
6
|
+
label: string;
|
|
5
7
|
};
|
|
6
8
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
7
9
|
select: (id: string) => void;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
precision highp float;
|
|
2
|
+
|
|
3
|
+
varying vec4 v_quad;
|
|
4
|
+
varying vec2 v_circle_center;
|
|
5
|
+
varying float v_visible;
|
|
6
|
+
varying float v_is_hovered;
|
|
7
|
+
varying float v_scale_fade;
|
|
8
|
+
varying float v_rect_id;
|
|
9
|
+
|
|
10
|
+
uniform float u_dpi;
|
|
11
|
+
uniform vec3 u_color;
|
|
12
|
+
uniform vec3 u_color_hover;
|
|
13
|
+
uniform vec3 u_color_field;
|
|
14
|
+
uniform vec3 u_color_field_hover;
|
|
15
|
+
|
|
16
|
+
void main() {
|
|
17
|
+
// Early exit if not visible or fully faded out
|
|
18
|
+
if (v_visible < 0.5 || v_scale_fade < 0.01) {
|
|
19
|
+
discard;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Calculate distance from pixel to circle center
|
|
23
|
+
vec2 pixelPos = gl_FragCoord.xy;
|
|
24
|
+
float dist = distance(pixelPos, v_circle_center);
|
|
25
|
+
|
|
26
|
+
// Circle radius (includes border)
|
|
27
|
+
float radius = v_quad.z / 2.0;
|
|
28
|
+
|
|
29
|
+
// Border width in pixels (must match vertex shader) - scaled by DPI
|
|
30
|
+
float borderWidth = 4.0 * u_dpi;
|
|
31
|
+
|
|
32
|
+
// Inner circle radius (without border)
|
|
33
|
+
float innerRadius = radius - borderWidth;
|
|
34
|
+
|
|
35
|
+
// Anti-aliased circle
|
|
36
|
+
float edgeSoftness = 1.0 * u_dpi;
|
|
37
|
+
float alpha = 1.0 - smoothstep(radius - edgeSoftness, radius, dist);
|
|
38
|
+
|
|
39
|
+
if (alpha < 0.01) {
|
|
40
|
+
discard;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Calculate position relative to circle center
|
|
44
|
+
vec2 offset = pixelPos - v_circle_center;
|
|
45
|
+
|
|
46
|
+
// Plus dimensions relative to inner circle radius
|
|
47
|
+
// Reduce thickness at low DPI (zoomed out)
|
|
48
|
+
float plusThicknessBase = u_dpi <= 0.5 ? 1.25 : 1.5;
|
|
49
|
+
float plusThickness = plusThicknessBase * u_dpi;
|
|
50
|
+
float plusLength = innerRadius * 0.5; // 50% of inner radius
|
|
51
|
+
float plusSoftness = 0.25 * u_dpi;
|
|
52
|
+
|
|
53
|
+
// Calculate soft plus factor (0 = not plus, 1 = fully plus)
|
|
54
|
+
float horizontalDist = max(abs(offset.y) - plusThickness, 0.0);
|
|
55
|
+
float verticalDist = max(abs(offset.x) - plusThickness, 0.0);
|
|
56
|
+
|
|
57
|
+
float horizontalBarFactor = 0.0;
|
|
58
|
+
if (abs(offset.x) < plusLength) {
|
|
59
|
+
horizontalBarFactor = 1.0 - smoothstep(0.0, plusSoftness, horizontalDist);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
float verticalBarFactor = 0.0;
|
|
63
|
+
if (abs(offset.y) < plusLength) {
|
|
64
|
+
verticalBarFactor = 1.0 - smoothstep(0.0, plusSoftness, verticalDist);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
float plusFactor = max(horizontalBarFactor, verticalBarFactor);
|
|
68
|
+
|
|
69
|
+
// Check if pixel is in the border area (outside the inner circle)
|
|
70
|
+
bool isBorder = dist >= innerRadius && dist <= radius;
|
|
71
|
+
|
|
72
|
+
// Determine base fill color
|
|
73
|
+
vec3 fillColor;
|
|
74
|
+
bool isFieldButton = v_rect_id >= 2.0;
|
|
75
|
+
if (isFieldButton) {
|
|
76
|
+
fillColor = v_is_hovered > 0.5 ? u_color_field_hover : u_color_field;
|
|
77
|
+
} else {
|
|
78
|
+
fillColor = v_is_hovered > 0.5 ? u_color_hover : u_color;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Determine final color
|
|
82
|
+
vec3 finalColor;
|
|
83
|
+
if (isBorder) {
|
|
84
|
+
// Soft border transition - blend from fill color to white over 0.5px
|
|
85
|
+
float transitionRange = 0.5 * u_dpi;
|
|
86
|
+
float borderStart = innerRadius;
|
|
87
|
+
float borderEnd = innerRadius + transitionRange;
|
|
88
|
+
|
|
89
|
+
// Calculate blend factor (0 = fill color, 1 = white)
|
|
90
|
+
float blendFactor = smoothstep(borderStart, borderEnd, dist);
|
|
91
|
+
|
|
92
|
+
// Blend between fill color and white
|
|
93
|
+
finalColor = mix(fillColor, vec3(1.0, 1.0, 1.0), blendFactor);
|
|
94
|
+
} else {
|
|
95
|
+
// Circle background
|
|
96
|
+
finalColor = fillColor;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Apply soft plus on top
|
|
100
|
+
if (plusFactor > 0.0) {
|
|
101
|
+
finalColor = mix(finalColor, vec3(1.0, 1.0, 1.0), plusFactor);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Apply scale fade to alpha
|
|
105
|
+
gl_FragColor = vec4(finalColor, alpha);
|
|
106
|
+
}
|