@revenexx/editor 0.1.0 → 0.1.1

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.
Files changed (31) hide show
  1. package/README.md +117 -43
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +1 -1
  4. package/dist/modules/agent/runtime/app/types/index.d.ts +3 -3
  5. package/dist/runtime/editor/components/BlockPreviewItem/index.d.vue.ts +1 -1
  6. package/dist/runtime/editor/components/BlockPreviewItem/index.vue.d.ts +1 -1
  7. package/dist/runtime/editor/components/BlockPreviewRenderer/index.d.vue.ts +1 -1
  8. package/dist/runtime/editor/components/BlockPreviewRenderer/index.vue.d.ts +1 -1
  9. package/dist/runtime/editor/components/Dialog/index.d.vue.ts +2 -2
  10. package/dist/runtime/editor/components/Dialog/index.vue.d.ts +2 -2
  11. package/dist/runtime/editor/components/DiffApproval/Toolbar/index.d.vue.ts +2 -2
  12. package/dist/runtime/editor/components/DiffApproval/Toolbar/index.vue.d.ts +2 -2
  13. package/dist/runtime/editor/components/FlexTextarea/index.d.vue.ts +1 -1
  14. package/dist/runtime/editor/components/FlexTextarea/index.vue.d.ts +1 -1
  15. package/dist/runtime/editor/components/RichText/Editor/index.d.vue.ts +1 -1
  16. package/dist/runtime/editor/components/RichText/Editor/index.vue.d.ts +1 -1
  17. package/dist/runtime/editor/components/SearchOverlay/index.d.vue.ts +1 -1
  18. package/dist/runtime/editor/components/SearchOverlay/index.vue.d.ts +1 -1
  19. package/dist/runtime/editor/components/Tooltip/index.d.vue.ts +1 -1
  20. package/dist/runtime/editor/components/Tooltip/index.vue.d.ts +1 -1
  21. package/dist/runtime/editor/features/changelog/changelog.json +122 -0
  22. package/dist/runtime/editor/features/comments/CommentInput/index.d.vue.ts +1 -1
  23. package/dist/runtime/editor/features/comments/CommentInput/index.vue.d.ts +1 -1
  24. package/dist/runtime/editor/plugins/ItemAction/index.d.vue.ts +1 -1
  25. package/dist/runtime/editor/plugins/ItemAction/index.vue.d.ts +1 -1
  26. package/dist/runtime/editor/plugins/Sidebar/Detached/index.d.vue.ts +1 -1
  27. package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue.d.ts +1 -1
  28. package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +2 -2
  29. package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +2 -2
  30. package/package.json +1 -1
  31. package/dist/runtime/editor/css/output.css +0 -1
package/README.md CHANGED
@@ -1,58 +1,132 @@
1
- # blökkli page builder for Nuxt
1
+ # @revenexx/editor
2
2
 
3
- **[Live Demo](https://blokk.li)**
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
- blökkli is an interactive page editor that integrates with any backend and
6
- offers various features to edit content quick and easy.
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
- ![Screenshot of the blökkli editor](./playground/public/editor-screenshot.png)
15
+ ## Using it in a revenexx theme
9
16
 
10
- ## Features
17
+ ### 1. Install
11
18
 
12
- - Smooth drag and drop editing
13
- - True WYSIWYG
14
- - Dynamic options for block apperance
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
- ## Comparison to other editors
23
+ ### 2. Register the module
24
24
 
25
- The main difference to other WYSIWYG editors is that blökkli does not manage the
26
- data - it's just the editor. It provides a single interface (called adapter) to
27
- integrate any backend or data structure. Actually performing the mutations (like
28
- add, delete, move, setting options) is left to the adapter. In most cases an
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
- ## Integration with Nuxt
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
- One of the main goals of blökkli is to offer a seamless integration with your
36
- new or existing Nuxt app. Creating new block components is straightforward.
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
- During normal rendering of blocks (not in the editor), the provided blökkli
42
- components and composables have a minimal overhead, to not have a negative
43
- impact on performance.
44
+ ### 3. Write blocks
44
45
 
45
- ## Backends
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
- Currently blökkli ships with an adapter to integrate it with the paragraphs
48
- module of Drupal. The
49
- [Paragraphs blökkli](https://www.drupal.org/project/paragraphs_blokkli) module
50
- implements all features available in the editor. It provides a new edit state
51
- entity that stores the applied mutations and implements a GraphQL schema
52
- extension to integrate the adapter.
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 developed by [dulnan](https://github.com/dulnan) at
57
- [Liip](https://www.liip.ch/). The development was supported by the canton of
58
- Basel-Stadt in Switzerland as part of the relaunch project for WebBS.
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@revenexx/editor",
3
3
  "configKey": "blokkli",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "compatibility": {
6
6
  "nuxt": ">=3.15.0"
7
7
  },
package/dist/module.mjs CHANGED
@@ -19,7 +19,7 @@ import 'typescript';
19
19
  import 'oxc-walker';
20
20
 
21
21
  const name = "@revenexx/editor";
22
- const version = "0.1.0";
22
+ const version = "0.1.1";
23
23
 
24
24
  function validateOption(optionKey, option, icons) {
25
25
  const errors = [];
@@ -409,11 +409,11 @@ declare const toolConversationItemSchema: z.ZodObject<{
409
409
  * the components that render it.
410
410
  */
411
411
  export declare const serverToolNameSchema: z.ZodEnum<{
412
+ plan_completed: "plan_completed";
412
413
  load_skills: "load_skills";
413
414
  load_tools: "load_tools";
414
415
  create_plan: "create_plan";
415
416
  complete_plan_step: "complete_plan_step";
416
- plan_completed: "plan_completed";
417
417
  }>;
418
418
  export type ServerToolName = z.infer<typeof serverToolNameSchema>;
419
419
  /**
@@ -424,11 +424,11 @@ declare const serverToolConversationItemSchema: z.ZodObject<{
424
424
  timestamp: z.ZodNumber;
425
425
  type: z.ZodLiteral<"server_tool">;
426
426
  tool: z.ZodEnum<{
427
+ plan_completed: "plan_completed";
427
428
  load_skills: "load_skills";
428
429
  load_tools: "load_tools";
429
430
  create_plan: "create_plan";
430
431
  complete_plan_step: "complete_plan_step";
431
- plan_completed: "plan_completed";
432
432
  }>;
433
433
  label: z.ZodString;
434
434
  }, z.core.$strip>;
@@ -503,11 +503,11 @@ export declare const conversationItemSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
503
503
  timestamp: z.ZodNumber;
504
504
  type: z.ZodLiteral<"server_tool">;
505
505
  tool: z.ZodEnum<{
506
+ plan_completed: "plan_completed";
506
507
  load_skills: "load_skills";
507
508
  load_tools: "load_tools";
508
509
  create_plan: "create_plan";
509
510
  complete_plan_step: "complete_plan_step";
510
- plan_completed: "plan_completed";
511
511
  }>;
512
512
  label: z.ZodString;
513
513
  }, z.core.$strip>, z.ZodObject<{
@@ -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;
@@ -4,8 +4,8 @@ type __VLS_Props = {
4
4
  maxHeight?: number;
5
5
  };
6
6
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
7
- maxHeight: number;
8
7
  backgroundClass: string;
8
+ maxHeight: number;
9
9
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
10
  declare const _default: typeof __VLS_export;
11
11
  export default _default;
@@ -4,8 +4,8 @@ type __VLS_Props = {
4
4
  maxHeight?: number;
5
5
  };
6
6
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
7
- maxHeight: number;
8
7
  backgroundClass: string;
8
+ maxHeight: number;
9
9
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
10
  declare const _default: typeof __VLS_export;
11
11
  export default _default;
@@ -41,9 +41,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
41
41
  zIndex: "default" | "high";
42
42
  icon: BlokkliIcon;
43
43
  width: number | string;
44
- lead: string;
45
- submitLabel: string;
46
44
  canSubmit: boolean;
45
+ submitLabel: string;
46
+ lead: string;
47
47
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
48
48
  tabs?: (props: {}) => any;
49
49
  } & {
@@ -41,9 +41,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
41
41
  zIndex: "default" | "high";
42
42
  icon: BlokkliIcon;
43
43
  width: number | string;
44
- lead: string;
45
- submitLabel: string;
46
44
  canSubmit: boolean;
45
+ submitLabel: string;
46
+ lead: string;
47
47
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
48
48
  tabs?: (props: {}) => any;
49
49
  } & {
@@ -34,10 +34,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
34
34
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
35
35
  onCancel?: (() => any) | undefined;
36
36
  onApply?: (() => any) | undefined;
37
- "onUpdate:selected"?: ((key: string, value: boolean) => any) | undefined;
38
- "onUpdate:reasons"?: ((key: string, value: string) => any) | undefined;
39
37
  onPrev?: (() => any) | undefined;
40
38
  onNext?: (() => any) | undefined;
39
+ "onUpdate:selected"?: ((key: string, value: boolean) => any) | undefined;
40
+ "onUpdate:reasons"?: ((key: string, value: string) => any) | undefined;
41
41
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
42
42
  declare const _default: typeof __VLS_export;
43
43
  export default _default;
@@ -34,10 +34,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
34
34
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
35
35
  onCancel?: (() => any) | undefined;
36
36
  onApply?: (() => any) | undefined;
37
- "onUpdate:selected"?: ((key: string, value: boolean) => any) | undefined;
38
- "onUpdate:reasons"?: ((key: string, value: string) => any) | undefined;
39
37
  onPrev?: (() => any) | undefined;
40
38
  onNext?: (() => any) | undefined;
39
+ "onUpdate:selected"?: ((key: string, value: boolean) => any) | undefined;
40
+ "onUpdate:reasons"?: ((key: string, value: string) => any) | undefined;
41
41
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
42
42
  declare const _default: typeof __VLS_export;
43
43
  export default _default;
@@ -28,8 +28,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
28
28
  onSubmit?: (() => any) | undefined;
29
29
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
30
30
  }>, {
31
- maxHeight: number;
32
31
  minHeight: number;
32
+ maxHeight: number;
33
33
  onBeforePaste: (data: ClipboardData) => boolean;
34
34
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
35
  declare const _default: typeof __VLS_export;
@@ -28,8 +28,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
28
28
  onSubmit?: (() => any) | undefined;
29
29
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
30
30
  }>, {
31
- maxHeight: number;
32
31
  minHeight: number;
32
+ maxHeight: number;
33
33
  onBeforePaste: (data: ClipboardData) => boolean;
34
34
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
35
  declare const _default: typeof __VLS_export;
@@ -25,7 +25,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
25
25
  isEmpty: boolean;
26
26
  }) => any) | undefined;
27
27
  }>, {
28
- autofocus: boolean;
29
28
  initialValue: string;
29
+ autofocus: boolean;
30
30
  getUsers: () => Promise<MentionItem[]>;
31
31
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -25,7 +25,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
25
25
  isEmpty: boolean;
26
26
  }) => any) | undefined;
27
27
  }>, {
28
- autofocus: boolean;
29
28
  initialValue: string;
29
+ autofocus: boolean;
30
30
  getUsers: () => Promise<MentionItem[]>;
31
31
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -30,8 +30,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
30
30
  "onUpdate:text"?: ((value: string) => any) | undefined;
31
31
  }>, {
32
32
  placeholder: string;
33
- itemHeight: number;
34
33
  visibleItems: number;
34
+ itemHeight: number;
35
35
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
36
36
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
37
37
  declare const _default: typeof __VLS_export;
@@ -30,8 +30,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
30
30
  "onUpdate:text"?: ((value: string) => any) | undefined;
31
31
  }>, {
32
32
  placeholder: string;
33
- itemHeight: number;
34
33
  visibleItems: number;
34
+ itemHeight: number;
35
35
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
36
36
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
37
37
  declare const _default: typeof __VLS_export;
@@ -14,8 +14,8 @@ type __VLS_Slots = {} & {
14
14
  };
15
15
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
16
16
  description: string | null;
17
- placement: Placement | "inline";
18
17
  margin: boolean;
18
+ placement: Placement | "inline";
19
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
20
20
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
21
21
  declare const _default: typeof __VLS_export;
@@ -14,8 +14,8 @@ type __VLS_Slots = {} & {
14
14
  };
15
15
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
16
16
  description: string | null;
17
- placement: Placement | "inline";
18
17
  margin: boolean;
18
+ placement: Placement | "inline";
19
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
20
20
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
21
21
  declare const _default: typeof __VLS_export;