@toaster-builder/site-runtime 0.1.1 → 0.1.2
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/README.md
CHANGED
|
@@ -70,3 +70,23 @@ const placementId = inject(blockPlacementIdKey, ref(''))
|
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
Для модального Block атрибут ставится на само окно, а не на backdrop.
|
|
73
|
+
|
|
74
|
+
## Действия блока в Builder
|
|
75
|
+
|
|
76
|
+
По умолчанию Builder показывает полный набор действий. Block может ограничить
|
|
77
|
+
его атрибутом `data-toaster-editor-actions` на том же элементе, который отмечен
|
|
78
|
+
как `data-toaster-editor-root`:
|
|
79
|
+
|
|
80
|
+
```vue
|
|
81
|
+
<div
|
|
82
|
+
data-toaster-editor-root
|
|
83
|
+
data-toaster-editor-actions="version settings assistant add add-ai"
|
|
84
|
+
:data-toaster-placement-id="placementId"
|
|
85
|
+
>
|
|
86
|
+
<!-- Содержимое блока -->
|
|
87
|
+
</div>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Доступные значения: `version`, `move`, `copy`, `settings`, `assistant`,
|
|
91
|
+
`visibility`, `delete`, `add`, `add-ai`. Если атрибут отсутствует, доступны все
|
|
92
|
+
действия. Пустой атрибут скрывает все элементы управления.
|
package/dist/module.json
CHANGED
|
@@ -19,6 +19,10 @@ import moveBlockUpIcon from "../assets/editor/move-block-up.svg";
|
|
|
19
19
|
import showBlockIcon from "../assets/editor/show-block.svg";
|
|
20
20
|
import BlockPlacementProvider from "#toaster-site-runtime/components/BlockPlacementProvider.vue";
|
|
21
21
|
import { useBuilderEventService } from "#toaster-site-runtime/composables/useBuilderEventService";
|
|
22
|
+
import {
|
|
23
|
+
blockEditorActions,
|
|
24
|
+
parseBlockEditorActions
|
|
25
|
+
} from "#toaster-site-runtime/utils/block-editor-actions";
|
|
22
26
|
const props = defineProps({
|
|
23
27
|
blockComponent: { type: null, required: true },
|
|
24
28
|
blockId: { type: String, required: true },
|
|
@@ -38,6 +42,9 @@ const overlayHovered = ref(false);
|
|
|
38
42
|
const overlayFocused = ref(false);
|
|
39
43
|
const overlayStyle = ref({});
|
|
40
44
|
const overlayVisible = ref(false);
|
|
45
|
+
const enabledEditorActions = shallowRef(
|
|
46
|
+
new Set(blockEditorActions)
|
|
47
|
+
);
|
|
41
48
|
const targetHovered = ref(false);
|
|
42
49
|
const targetFocused = ref(false);
|
|
43
50
|
const overlayActive = computed(() => overlayHovered.value || overlayFocused.value || targetHovered.value || targetFocused.value);
|
|
@@ -104,6 +111,9 @@ function unbindEditorTarget() {
|
|
|
104
111
|
targetFocused.value = false;
|
|
105
112
|
}
|
|
106
113
|
function bindEditorTarget(target) {
|
|
114
|
+
enabledEditorActions.value = parseBlockEditorActions(
|
|
115
|
+
target?.dataset.toasterEditorActions
|
|
116
|
+
);
|
|
107
117
|
if (editorTarget.value === target) {
|
|
108
118
|
scheduleOverlayBoundsUpdate();
|
|
109
119
|
return;
|
|
@@ -122,6 +132,9 @@ function bindEditorTarget(target) {
|
|
|
122
132
|
resizeObserver.observe(target);
|
|
123
133
|
scheduleOverlayBoundsUpdate();
|
|
124
134
|
}
|
|
135
|
+
function hasEditorAction(action) {
|
|
136
|
+
return enabledEditorActions.value.has(action);
|
|
137
|
+
}
|
|
125
138
|
function findPlacementTargets(root) {
|
|
126
139
|
return Array.from(root.querySelectorAll("[data-toaster-editor-root]")).filter((element) => element.dataset.toasterPlacementId === props.placementId);
|
|
127
140
|
}
|
|
@@ -144,7 +157,16 @@ onMounted(() => {
|
|
|
144
157
|
document.addEventListener("scroll", scheduleOverlayBoundsUpdate, true);
|
|
145
158
|
window.addEventListener("resize", scheduleOverlayBoundsUpdate);
|
|
146
159
|
mutationObserver = new MutationObserver(resolveEditorTarget);
|
|
147
|
-
mutationObserver.observe(document.body, {
|
|
160
|
+
mutationObserver.observe(document.body, {
|
|
161
|
+
attributes: true,
|
|
162
|
+
attributeFilter: [
|
|
163
|
+
"data-toaster-editor-actions",
|
|
164
|
+
"data-toaster-editor-root",
|
|
165
|
+
"data-toaster-placement-id"
|
|
166
|
+
],
|
|
167
|
+
childList: true,
|
|
168
|
+
subtree: true
|
|
169
|
+
});
|
|
148
170
|
void nextTick(resolveEditorTarget);
|
|
149
171
|
});
|
|
150
172
|
onBeforeUnmount(() => {
|
|
@@ -192,6 +214,7 @@ onBeforeUnmount(() => {
|
|
|
192
214
|
class="block-editor-frame__overlay"
|
|
193
215
|
:class="{ 'block-editor-frame__overlay--active': overlayActive }"
|
|
194
216
|
data-toaster-editor-overlay
|
|
217
|
+
:data-toaster-editor-actions="[...enabledEditorActions].join(' ')"
|
|
195
218
|
:data-toaster-placement-id="placementId"
|
|
196
219
|
:style="overlayStyle"
|
|
197
220
|
@pointerenter="overlayHovered = true"
|
|
@@ -201,6 +224,7 @@ onBeforeUnmount(() => {
|
|
|
201
224
|
>
|
|
202
225
|
<div class="block-editor-frame__toolbar">
|
|
203
226
|
<button
|
|
227
|
+
v-if="hasEditorAction('version')"
|
|
204
228
|
class="block-editor-frame__control block-editor-frame__version"
|
|
205
229
|
type="button"
|
|
206
230
|
:aria-label="`\u0421\u043C\u0435\u043D\u0438\u0442\u044C \u0432\u0435\u0440\u0441\u0438\u044E \u0431\u043B\u043E\u043A\u0430 ${blockVersionLabel}`"
|
|
@@ -211,6 +235,7 @@ onBeforeUnmount(() => {
|
|
|
211
235
|
</button>
|
|
212
236
|
|
|
213
237
|
<button
|
|
238
|
+
v-if="hasEditorAction('move')"
|
|
214
239
|
class="block-editor-frame__control block-editor-frame__icon-button"
|
|
215
240
|
type="button"
|
|
216
241
|
:aria-label="`\u041F\u0435\u0440\u0435\u043D\u0435\u0441\u0442\u0438 \u0432\u0432\u0435\u0440\u0445 \u0431\u043B\u043E\u043A ${blockVersionLabel}`"
|
|
@@ -226,6 +251,7 @@ onBeforeUnmount(() => {
|
|
|
226
251
|
</button>
|
|
227
252
|
|
|
228
253
|
<button
|
|
254
|
+
v-if="hasEditorAction('move')"
|
|
229
255
|
class="block-editor-frame__control block-editor-frame__icon-button"
|
|
230
256
|
type="button"
|
|
231
257
|
:aria-label="`\u041F\u0435\u0440\u0435\u043D\u0435\u0441\u0442\u0438 \u0432\u043D\u0438\u0437 \u0431\u043B\u043E\u043A ${blockVersionLabel}`"
|
|
@@ -241,6 +267,7 @@ onBeforeUnmount(() => {
|
|
|
241
267
|
</button>
|
|
242
268
|
|
|
243
269
|
<button
|
|
270
|
+
v-if="hasEditorAction('copy')"
|
|
244
271
|
class="block-editor-frame__control block-editor-frame__icon-button"
|
|
245
272
|
type="button"
|
|
246
273
|
:aria-label="`\u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0431\u043B\u043E\u043A ${blockVersionLabel}`"
|
|
@@ -255,6 +282,7 @@ onBeforeUnmount(() => {
|
|
|
255
282
|
</button>
|
|
256
283
|
|
|
257
284
|
<button
|
|
285
|
+
v-if="hasEditorAction('settings')"
|
|
258
286
|
class="block-editor-frame__control block-editor-frame__icon-button"
|
|
259
287
|
type="button"
|
|
260
288
|
:aria-label="`\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0431\u043B\u043E\u043A\u0430 ${blockVersionLabel}`"
|
|
@@ -279,6 +307,7 @@ onBeforeUnmount(() => {
|
|
|
279
307
|
</button>
|
|
280
308
|
|
|
281
309
|
<button
|
|
310
|
+
v-if="hasEditorAction('assistant')"
|
|
282
311
|
class="block-editor-frame__control block-editor-frame__icon-button"
|
|
283
312
|
type="button"
|
|
284
313
|
:aria-label="`\u041E\u0442\u043A\u0440\u044B\u0442\u044C AI-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442\u0430 \u0434\u043B\u044F \u0431\u043B\u043E\u043A\u0430 ${blockVersionLabel}`"
|
|
@@ -293,6 +322,7 @@ onBeforeUnmount(() => {
|
|
|
293
322
|
</button>
|
|
294
323
|
|
|
295
324
|
<button
|
|
325
|
+
v-if="hasEditorAction('visibility')"
|
|
296
326
|
class="block-editor-frame__control block-editor-frame__icon-button"
|
|
297
327
|
type="button"
|
|
298
328
|
:aria-label="enabled ? `\u0412\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u0441\u043A\u0440\u044B\u0442\u044C \u0431\u043B\u043E\u043A ${blockVersionLabel}` : `\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0431\u043B\u043E\u043A ${blockVersionLabel}`"
|
|
@@ -307,6 +337,7 @@ onBeforeUnmount(() => {
|
|
|
307
337
|
</button>
|
|
308
338
|
|
|
309
339
|
<button
|
|
340
|
+
v-if="hasEditorAction('delete')"
|
|
310
341
|
class="block-editor-frame__control block-editor-frame__icon-button"
|
|
311
342
|
type="button"
|
|
312
343
|
:aria-label="`\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0431\u043B\u043E\u043A ${blockVersionLabel}`"
|
|
@@ -322,6 +353,7 @@ onBeforeUnmount(() => {
|
|
|
322
353
|
</div>
|
|
323
354
|
|
|
324
355
|
<button
|
|
356
|
+
v-if="hasEditorAction('add')"
|
|
325
357
|
class="block-editor-frame__control block-editor-frame__add block-editor-frame__add--after"
|
|
326
358
|
type="button"
|
|
327
359
|
aria-label="Добавить блок снизу"
|
|
@@ -336,6 +368,7 @@ onBeforeUnmount(() => {
|
|
|
336
368
|
</button>
|
|
337
369
|
|
|
338
370
|
<button
|
|
371
|
+
v-if="hasEditorAction('add-ai')"
|
|
339
372
|
class="block-editor-frame__control block-editor-frame__add-ai"
|
|
340
373
|
type="button"
|
|
341
374
|
:aria-label="`\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0431\u043B\u043E\u043A \u0447\u0435\u0440\u0435\u0437 AI \u043F\u043E\u0441\u043B\u0435 \u0431\u043B\u043E\u043A\u0430 ${blockVersionLabel}`"
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const blockEditorActions: readonly ["version", "move", "copy", "settings", "assistant", "visibility", "delete", "add", "add-ai"];
|
|
2
|
+
export type BlockEditorAction = (typeof blockEditorActions)[number];
|
|
3
|
+
export declare function parseBlockEditorActions(value: string | undefined): ReadonlySet<BlockEditorAction>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const blockEditorActions = [
|
|
2
|
+
"version",
|
|
3
|
+
"move",
|
|
4
|
+
"copy",
|
|
5
|
+
"settings",
|
|
6
|
+
"assistant",
|
|
7
|
+
"visibility",
|
|
8
|
+
"delete",
|
|
9
|
+
"add",
|
|
10
|
+
"add-ai"
|
|
11
|
+
];
|
|
12
|
+
const knownActions = new Set(blockEditorActions);
|
|
13
|
+
export function parseBlockEditorActions(value) {
|
|
14
|
+
if (value === void 0) return new Set(blockEditorActions);
|
|
15
|
+
return new Set(
|
|
16
|
+
value.split(/\s+/).filter((action) => knownActions.has(action))
|
|
17
|
+
);
|
|
18
|
+
}
|