diff --git a/docs/framework/custom-components.mdx b/docs/framework/custom-components.mdx
index 5ce899008..28874ad32 100644
--- a/docs/framework/custom-components.mdx
+++ b/docs/framework/custom-components.mdx
@@ -135,9 +135,9 @@ The code above will make Bubble Message available in the Builder.
You can also have a look at the built-in component templates, since their
- syntax is equivalent. They can be found in the `ui/src/components/` folder.
+ syntax is equivalent. They can be found in the `ui/src/components/core` folder.
-Go to `ui/src/custom_components/` and open the Vue single-file components, i.e. the
+Go to `ui/src/components/custom` and open the Vue single-file components, i.e. the
`.vue` files. These files contain comments that will help you get started. Try editing
the provided templates, you should see changes reflected.
@@ -145,7 +145,7 @@ You can get started by duplicating one of these examples. Make sure you add the
### Define entrypoint
-For custom component templates to be taken into account, they need to be accessible from the entrypoint. Edit `ui/src/custom_components/index.ts` to define which templates you wish to export and under which identifiers.
+For custom component templates to be taken into account, they need to be accessible from the entrypoint. Edit `ui/src/components/custom/index.ts` to define which templates you wish to export and under which identifiers.
```ts
// Import the templates
diff --git a/src/ui/src/custom_components/BubbleMessage.vue b/src/ui/src/components/custom/BubbleMessage.vue
similarity index 100%
rename from src/ui/src/custom_components/BubbleMessage.vue
rename to src/ui/src/components/custom/BubbleMessage.vue
diff --git a/src/ui/src/custom_components/BubbleMessageAdvanced.vue b/src/ui/src/components/custom/BubbleMessageAdvanced.vue
similarity index 100%
rename from src/ui/src/custom_components/BubbleMessageAdvanced.vue
rename to src/ui/src/components/custom/BubbleMessageAdvanced.vue
diff --git a/src/ui/src/custom_components/index.ts b/src/ui/src/components/custom/index.ts
similarity index 69%
rename from src/ui/src/custom_components/index.ts
rename to src/ui/src/components/custom/index.ts
index 436ffd20a..f148e7dd3 100644
--- a/src/ui/src/custom_components/index.ts
+++ b/src/ui/src/components/custom/index.ts
@@ -1,11 +1,14 @@
// Import the templates
+import type { TemplateMap } from "@/writerTypes";
import BubbleMessage from "./BubbleMessage.vue";
import BubbleMessageAdvanced from "./BubbleMessageAdvanced.vue";
// Export an object with the ids and the templates as default
-export default {
+const CUSTOM_COMPONENTS: TemplateMap = {
bubblemessage: BubbleMessage,
bubblemessageadvanced: BubbleMessageAdvanced,
};
+
+export default CUSTOM_COMPONENTS;
diff --git a/src/ui/src/core/templateMap.ts b/src/ui/src/core/templateMap.ts
index b05dd014a..cd3d2f966 100644
--- a/src/ui/src/core/templateMap.ts
+++ b/src/ui/src/core/templateMap.ts
@@ -1,3 +1,4 @@
+import type { Component as VueComponent } from "vue";
// Maps Writer Framework component types to renderable Vue components
// content
import CoreDataframe from "../components/core/content/CoreDataframe.vue";
@@ -69,10 +70,14 @@ import WorkflowsWorkflow from "../components/workflows/WorkflowsWorkflow.vue";
import WorkflowsNode from "../components/workflows/abstract/WorkflowsNode.vue";
import WorkflowsRoot from "@/components/workflows/WorkflowsRoot.vue";
-import { AbstractTemplate, WriterComponentDefinition } from "@/writerTypes";
+import type {
+ AbstractTemplate,
+ TemplateMap,
+ WriterComponentDefinition,
+} from "@/writerTypes";
import { h } from "vue";
-const templateMap = {
+const templateMap: TemplateMap = {
root: CoreRoot,
page: CorePage,
sidebar: CoreSidebar,
@@ -135,14 +140,14 @@ const templateMap = {
const abstractTemplateMap: Record = {};
+// eslint-disable-next-line no-undef
if (WRITER_LIVE_CCT === "yes") {
/*
- Assigns the components in custom_components to the template map,
+ Assigns the components in `components/custom` to the template map,
allowing for live updates when developing custom component templates.
*/
- const liveCCT: Record = (await import("../custom_components"))
- .default;
+ const liveCCT = (await import("../components/custom")).default;
Object.entries(liveCCT).forEach(([componentType, template]) => {
templateMap[`custom_${componentType}`] = template;
});
@@ -157,7 +162,7 @@ function fallbackTemplate(type: string) {
description: message,
category: "Fallback",
},
- setup(props, { slots }) {
+ setup(_props: never, { slots }) {
return () => {
return h(
"div",
@@ -212,7 +217,10 @@ export function getSupportedComponentTypes() {
return [...Object.keys(templateMap), ...Object.keys(abstractTemplateMap)];
}
-export function registerComponentTemplate(type: string, vueComponent: any) {
+export function registerComponentTemplate(
+ type: string,
+ vueComponent: VueComponent,
+) {
templateMap[type] = vueComponent;
}
diff --git a/src/ui/src/writerTypes.ts b/src/ui/src/writerTypes.ts
index bbe92a36f..4eb9d554a 100644
--- a/src/ui/src/writerTypes.ts
+++ b/src/ui/src/writerTypes.ts
@@ -1,3 +1,4 @@
+import type { Component as VueComponent } from "vue";
import { generateCore } from "./core";
import { generateBuilderManager } from "./builder/builderManager";
@@ -101,8 +102,15 @@ export type WriterComponentDefinition = {
>;
previewField?: string; // Which field to use for previewing in the Component Tree
positionless?: boolean; // Whether this type of component is positionless (like Sidebar)
- outs?:
- Record;
+ outs?: Record<
+ string,
+ {
+ name: string;
+ description: string;
+ style: string;
+ field?: keyof WriterComponentDefinition["fields"];
+ }
+ >;
};
export type BuilderManager = ReturnType;
@@ -154,3 +162,5 @@ export type AbstractTemplate = {
baseType: string;
writer: WriterComponentDefinition;
};
+
+export type TemplateMap = Record;
diff --git a/src/ui/tools/custom_check.mjs b/src/ui/tools/custom_check.mjs
index 49b26aa70..6ae37749c 100644
--- a/src/ui/tools/custom_check.mjs
+++ b/src/ui/tools/custom_check.mjs
@@ -2,7 +2,7 @@ import { importVue } from "./core.mjs";
async function checkDeclarationKey() {
let hasFailed = false;
- const module = await importVue("../src/custom_components/index.ts");
+ const module = await importVue("../src/components/custom/index.ts");
const { checkComponentKey } = await importVue(
"../src/core/loadExtensions.ts",
);
@@ -17,7 +17,7 @@ async function checkDeclarationKey() {
if (invalidCustomComponentKeys.length !== 0) {
// eslint-disable-next-line no-console
console.error(
- `ERROR: Invalid component declaration: ${invalidCustomComponentKeys} into 'src/custom_components/index.ts'. Their key must be declared using only lowercase and alphanumeric characters.`,
+ `ERROR: Invalid component declaration: ${invalidCustomComponentKeys} into 'src/components/custom/index.ts'. Their key must be declared using only lowercase and alphanumeric characters.`,
);
}
return hasFailed;
diff --git a/src/ui/vite.config.custom.ts b/src/ui/vite.config.custom.ts
index 2534e3385..6b092c704 100644
--- a/src/ui/vite.config.custom.ts
+++ b/src/ui/vite.config.custom.ts
@@ -14,7 +14,7 @@ export default defineConfig({
publicDir: false,
build: {
lib: {
- entry: ["./src/custom_components"],
+ entry: ["./src/components/custom"],
formats: ["umd"],
name: "WriterCustomComponentTemplates",
fileName: (format, entryalias: string): string => {