@revenexx/editor 0.1.0 → 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 +117 -43
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/modules/agent/runtime/shared/types.d.ts +3 -3
- package/dist/runtime/editor/components/BlockPreviewItem/index.d.vue.ts +1 -1
- package/dist/runtime/editor/components/BlockPreviewItem/index.vue.d.ts +1 -1
- package/dist/runtime/editor/css/output.css +1 -1
- package/dist/runtime/editor/features/changelog/changelog.json +122 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,58 +1,132 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @revenexx/editor
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
The visual page editor for **revenexx Revenue Cloud themes** — a hard fork of
|
|
4
|
+
[blökkli](https://github.com/blokkli/editor) ([live demo](https://blokk.li)),
|
|
5
|
+
adapted to the revenexx UI and platform. How the fork is maintained, synced with
|
|
6
|
+
upstream and released is documented in [FORK.md](./FORK.md).
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
The editor gives buyers of a theme true WYSIWYG page building: drag & drop
|
|
9
|
+
blocks, inline text editing, undo/redo history, comments, a reusable-block
|
|
10
|
+
library, templates, multi-language content and a publish workflow. The editor
|
|
11
|
+
**does not store data** — every mutation goes through an _adapter_ to a backend.
|
|
12
|
+
In the Revenue Cloud that backend is the **pages platform app** (`apps/pages`),
|
|
13
|
+
and the reference integration is **`@revenexx/cover-theme`**.
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
## Using it in a revenexx theme
|
|
9
16
|
|
|
10
|
-
|
|
17
|
+
### 1. Install
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- Inline text editing (plain or rich text)
|
|
16
|
-
- Multilanguage (both UI and content)
|
|
17
|
-
- Nested blocks (for sections, grids, accordions, etc.)
|
|
18
|
-
- Restrictions (allowed block types, cardinality, max instances)
|
|
19
|
-
- Clipboard integration (paste text, images, links or copy blocks)
|
|
20
|
-
- Comments
|
|
21
|
-
- and many more
|
|
19
|
+
```bash
|
|
20
|
+
npm install @revenexx/editor
|
|
21
|
+
```
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
### 2. Register the module
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
adapter method performs API calls, but it could as well all be done in the
|
|
30
|
-
browser. In fact, the demo page / playground implements a reference adapter that
|
|
31
|
-
stores mutations in local storage and keeps data in JSON files.
|
|
25
|
+
```ts
|
|
26
|
+
// nuxt.config.ts
|
|
27
|
+
export default defineNuxtConfig({
|
|
28
|
+
modules: ['@revenexx/editor'],
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
blokkli: {
|
|
31
|
+
itemEntityType: 'block',
|
|
32
|
+
defaultLanguage: 'de',
|
|
33
|
+
// Where your block components live:
|
|
34
|
+
pattern: ['app/components/blokkli/**/*.vue'],
|
|
35
|
+
// Your edit adapter (see step 4):
|
|
36
|
+
editAdapterPath: 'app/blokkli.editAdapter.ts',
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
```
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Options to change the appearance of a block are directly defined in the
|
|
38
|
-
component, so is configuration that defines the behaviour of the block when
|
|
39
|
-
rendered in the editor.
|
|
41
|
+
> The config key stays `blokkli` and all in-app imports go through the generated
|
|
42
|
+
> `#blokkli/*` aliases — only the package name is revenexx-specific.
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
components and composables have a minimal overhead, to not have a negative
|
|
43
|
-
impact on performance.
|
|
44
|
+
### 3. Write blocks
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
A block is a Vue component using the `defineBlokkli()` macro. Props are the
|
|
47
|
+
editable fields; options control appearance and show up in the editor toolbar.
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
```vue
|
|
50
|
+
<!-- app/components/blokkli/hero/index.vue -->
|
|
51
|
+
<script setup lang="ts">
|
|
52
|
+
const props = defineProps<{
|
|
53
|
+
headline: string
|
|
54
|
+
subheadline?: string
|
|
55
|
+
}>()
|
|
56
|
+
|
|
57
|
+
const { options } = defineBlokkli({
|
|
58
|
+
bundle: 'hero',
|
|
59
|
+
options: {
|
|
60
|
+
alignment: {
|
|
61
|
+
type: 'radios',
|
|
62
|
+
label: 'Alignment',
|
|
63
|
+
default: 'left',
|
|
64
|
+
options: { left: 'Left', center: 'Center' },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
editor: {
|
|
68
|
+
// Props a freshly added block starts with:
|
|
69
|
+
mockProps: () => ({ headline: 'Headline' }),
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<template>
|
|
75
|
+
<section :class="options.alignment === 'center' && 'text-center'">
|
|
76
|
+
<!-- v-blokkli-editable enables inline editing for this field -->
|
|
77
|
+
<h1 v-blokkli-editable:headline>{{ headline }}</h1>
|
|
78
|
+
<p v-if="subheadline" v-blokkli-editable:subheadline>{{ subheadline }}</p>
|
|
79
|
+
</section>
|
|
80
|
+
</template>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Nested blocks (sections, grids, accordions) render their children with
|
|
84
|
+
`<BlokkliField name="items" :list="..." />`.
|
|
85
|
+
|
|
86
|
+
### 4. The edit adapter
|
|
87
|
+
|
|
88
|
+
The adapter translates editor actions (add, move, delete, options, publish,
|
|
89
|
+
comments, …) into backend calls. **Don't write one from scratch** — copy the
|
|
90
|
+
reference implementation:
|
|
91
|
+
|
|
92
|
+
- **Adapter:** `cover/packages/cover-theme/app/blokkli.editAdapter.ts` — full
|
|
93
|
+
feature surface against the pages app
|
|
94
|
+
- **Backend contract:** `apps/pages/README.md` has the complete adapter-method →
|
|
95
|
+
endpoint mapping (mutation log with undo/redo, ownership, revisions, comments,
|
|
96
|
+
library, templates, translations, notifications)
|
|
97
|
+
- **BFF proxy:** the browser never calls the pages app directly; a Nitro route
|
|
98
|
+
(`/api/blokkli/app/[...path]`) forwards calls with tenant context
|
|
99
|
+
|
|
100
|
+
### 5. The `/admin/` pattern
|
|
101
|
+
|
|
102
|
+
Live storefront routes never ship editor code. The editor mounts on a dedicated
|
|
103
|
+
route the cockpit embeds in an iframe:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
/admin/edit?page={id}&langcode={lang} ← editor surface (BlokkliProvider)
|
|
107
|
+
/preview/{token} ← read-only share preview
|
|
108
|
+
/{slug} ← live rendering, zero editor weight
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The cockpit hands a short-lived, user-scoped token to the iframe via
|
|
112
|
+
`postMessage` (`{ type: 'blokkli:edit-token', token }`) or the `#token=`
|
|
113
|
+
fragment; the theme attaches it to every adapter call. See
|
|
114
|
+
`cover-theme/app/pages/admin/edit.vue` + `useEditToken.ts`.
|
|
115
|
+
|
|
116
|
+
## Development (this repo)
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm install
|
|
120
|
+
npm run dev:prepare # generate the .nuxt alias environment (required once)
|
|
121
|
+
npm run dev -- --port 3001 # playground with the revenexx theme
|
|
122
|
+
npm test # vitest
|
|
123
|
+
npm run typecheck # see /typecheck for targeted commands
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Releasing & upstream syncs: see [FORK.md](./FORK.md).
|
|
53
127
|
|
|
54
128
|
## Acknowledgments
|
|
55
129
|
|
|
56
|
-
blökkli was
|
|
57
|
-
[Liip](https://www.liip.ch/).
|
|
58
|
-
|
|
130
|
+
blökkli was created by [dulnan](https://github.com/dulnan) at
|
|
131
|
+
[Liip](https://www.liip.ch/) (MIT). This fork tracks upstream closely — we pull
|
|
132
|
+
new releases regularly and replay the revenexx customizations on top.
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -207,6 +207,7 @@ export type PageContext = {
|
|
|
207
207
|
* Both Anthropic and OpenAI SDKs map to these via HTTP status codes.
|
|
208
208
|
*/
|
|
209
209
|
export declare const agentErrorTypeSchema: z.ZodEnum<{
|
|
210
|
+
unknown: "unknown";
|
|
210
211
|
authentication: "authentication";
|
|
211
212
|
rate_limit: "rate_limit";
|
|
212
213
|
overloaded: "overloaded";
|
|
@@ -214,7 +215,6 @@ export declare const agentErrorTypeSchema: z.ZodEnum<{
|
|
|
214
215
|
bad_request: "bad_request";
|
|
215
216
|
connection: "connection";
|
|
216
217
|
unauthorized: "unauthorized";
|
|
217
|
-
unknown: "unknown";
|
|
218
218
|
}>;
|
|
219
219
|
export type AgentErrorType = z.infer<typeof agentErrorTypeSchema>;
|
|
220
220
|
/**
|
|
@@ -355,8 +355,8 @@ export declare const clientMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
355
355
|
name: z.ZodString;
|
|
356
356
|
label: z.ZodString;
|
|
357
357
|
type: z.ZodEnum<{
|
|
358
|
-
reference: "reference";
|
|
359
358
|
link: "link";
|
|
359
|
+
reference: "reference";
|
|
360
360
|
}>;
|
|
361
361
|
allowed: z.ZodArray<z.ZodObject<{
|
|
362
362
|
type: z.ZodString;
|
|
@@ -395,8 +395,8 @@ export declare const clientMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
395
395
|
name: z.ZodString;
|
|
396
396
|
label: z.ZodString;
|
|
397
397
|
type: z.ZodEnum<{
|
|
398
|
-
reference: "reference";
|
|
399
398
|
link: "link";
|
|
399
|
+
reference: "reference";
|
|
400
400
|
}>;
|
|
401
401
|
allowed: z.ZodArray<z.ZodObject<{
|
|
402
402
|
type: z.ZodString;
|
|
@@ -11,8 +11,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
11
11
|
bundle: string;
|
|
12
12
|
description: string;
|
|
13
13
|
noPreview: boolean;
|
|
14
|
-
maxHeight: number;
|
|
15
14
|
items: FieldListItem[] | FieldListItem;
|
|
15
|
+
maxHeight: number;
|
|
16
16
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
17
|
declare const _default: typeof __VLS_export;
|
|
18
18
|
export default _default;
|
|
@@ -11,8 +11,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
11
11
|
bundle: string;
|
|
12
12
|
description: string;
|
|
13
13
|
noPreview: boolean;
|
|
14
|
-
maxHeight: number;
|
|
15
14
|
items: FieldListItem[] | FieldListItem;
|
|
15
|
+
maxHeight: number;
|
|
16
16
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
17
|
declare const _default: typeof __VLS_export;
|
|
18
18
|
export default _default;
|