@prolibu-suite/cobalt-form-builder 0.2.0
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/CobaltFormBuilder.vue.d.ts +200 -0
- package/dist/CobaltFormBuilder.vue.d.ts.map +1 -0
- package/dist/cobalt-form-builder.cjs +2 -0
- package/dist/cobalt-form-builder.cjs.map +1 -0
- package/dist/cobalt-form-builder.css +1 -0
- package/dist/cobalt-form-builder.js +3446 -0
- package/dist/cobalt-form-builder.js.map +1 -0
- package/dist/components/DesignerTab.vue.d.ts +4 -0
- package/dist/components/DesignerTab.vue.d.ts.map +1 -0
- package/dist/components/EditableText.vue.d.ts +19 -0
- package/dist/components/EditableText.vue.d.ts.map +1 -0
- package/dist/components/FieldCanvas.vue.d.ts +4 -0
- package/dist/components/FieldCanvas.vue.d.ts.map +1 -0
- package/dist/components/FieldCard.vue.d.ts +9 -0
- package/dist/components/FieldCard.vue.d.ts.map +1 -0
- package/dist/components/FieldCardExpanded.vue.d.ts +8 -0
- package/dist/components/FieldCardExpanded.vue.d.ts.map +1 -0
- package/dist/components/FieldToolbox.vue.d.ts +4 -0
- package/dist/components/FieldToolbox.vue.d.ts.map +1 -0
- package/dist/components/JsonTab.vue.d.ts +4 -0
- package/dist/components/JsonTab.vue.d.ts.map +1 -0
- package/dist/components/PageCard.vue.d.ts +7 -0
- package/dist/components/PageCard.vue.d.ts.map +1 -0
- package/dist/components/PreviewTab.vue.d.ts +4 -0
- package/dist/components/PreviewTab.vue.d.ts.map +1 -0
- package/dist/components/PropertiesPanel.vue.d.ts +4 -0
- package/dist/components/PropertiesPanel.vue.d.ts.map +1 -0
- package/dist/fieldCatalog.d.ts +17 -0
- package/dist/fieldCatalog.d.ts.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/stores/schema.d.ts +193 -0
- package/dist/stores/schema.d.ts.map +1 -0
- package/examples/01-contact-form.json +36 -0
- package/examples/02-nps-survey.json +59 -0
- package/examples/03-quiz-vue3.json +59 -0
- package/examples/04-event-registration.json +100 -0
- package/examples/05-themed-dark-form.json +56 -0
- package/examples/06-culture-survey.json +99 -0
- package/examples/07-crm-quotation.json +70 -0
- package/examples/08-landing-page-embed.json +142 -0
- package/package.json +54 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=DesignerTab.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DesignerTab.vue.d.ts","sourceRoot":"","sources":["../../src/components/DesignerTab.vue"],"names":[],"mappings":"AAuGA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline-editable text. Click to focus, blur or Enter to commit.
|
|
3
|
+
*
|
|
4
|
+
* We use contenteditable on a span so layout doesn't shift between
|
|
5
|
+
* read/edit modes — switching to an <input> would jump the row height.
|
|
6
|
+
*/
|
|
7
|
+
type __VLS_Props = {
|
|
8
|
+
modelValue: string;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
multiline?: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
|
+
"update:modelValue": (value: string) => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
16
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
//# sourceMappingURL=EditableText.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditableText.vue.d.ts","sourceRoot":"","sources":["../../src/components/EditableText.vue"],"names":[],"mappings":"AA+GA;;;;;GAKG;AACH,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAuGF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=FieldCanvas.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldCanvas.vue.d.ts","sourceRoot":"","sources":["../../src/components/FieldCanvas.vue"],"names":[],"mappings":"AAydA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
pageIdx: number;
|
|
3
|
+
fieldIdx: number;
|
|
4
|
+
fieldName: string;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
+
declare const _default: typeof __VLS_export;
|
|
8
|
+
export default _default;
|
|
9
|
+
//# sourceMappingURL=FieldCard.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldCard.vue.d.ts","sourceRoot":"","sources":["../../src/components/FieldCard.vue"],"names":[],"mappings":"AA2PA,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA0OF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
pageIdx: number;
|
|
3
|
+
fieldName: string;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
8
|
+
//# sourceMappingURL=FieldCardExpanded.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldCardExpanded.vue.d.ts","sourceRoot":"","sources":["../../src/components/FieldCardExpanded.vue"],"names":[],"mappings":"AA85BA,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA8wCF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=FieldToolbox.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldToolbox.vue.d.ts","sourceRoot":"","sources":["../../src/components/FieldToolbox.vue"],"names":[],"mappings":"AAqfA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=JsonTab.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonTab.vue.d.ts","sourceRoot":"","sources":["../../src/components/JsonTab.vue"],"names":[],"mappings":"AA8NA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
pageIdx: number;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
declare const _default: typeof __VLS_export;
|
|
6
|
+
export default _default;
|
|
7
|
+
//# sourceMappingURL=PageCard.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageCard.vue.d.ts","sourceRoot":"","sources":["../../src/components/PageCard.vue"],"names":[],"mappings":"AAiUA,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAoUF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=PreviewTab.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreviewTab.vue.d.ts","sourceRoot":"","sources":["../../src/components/PreviewTab.vue"],"names":[],"mappings":"AAoTA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=PropertiesPanel.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertiesPanel.vue.d.ts","sourceRoot":"","sources":["../../src/components/PropertiesPanel.vue"],"names":[],"mappings":"AAmsEA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog of field types the builder can insert. Each entry pairs a Cobalt
|
|
3
|
+
* FieldKind (or composite `uiCom`) with a human label, group, search aliases,
|
|
4
|
+
* and a Phosphor icon name rendered by <co-icon>.
|
|
5
|
+
*/
|
|
6
|
+
export interface FieldCatalogEntry {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
group: 'inputs' | 'choices' | 'advanced' | 'layout';
|
|
10
|
+
/** Extra terms the search matches against. */
|
|
11
|
+
aliases?: string[];
|
|
12
|
+
/** Phosphor icon name (used by <co-icon name="..." />). */
|
|
13
|
+
icon: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const FIELD_CATALOG: FieldCatalogEntry[];
|
|
16
|
+
export declare const GROUP_LABELS: Record<FieldCatalogEntry['group'], string>;
|
|
17
|
+
//# sourceMappingURL=fieldCatalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldCatalog.d.ts","sourceRoot":"","sources":["../src/fieldCatalog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IACpD,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,aAAa,EAAE,iBAAiB,EAoB5C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,CAKnE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Library entry point for `@prolibu-suite/cobalt-form-builder`.
|
|
3
|
+
*
|
|
4
|
+
* Consumers (e.g. suite-v2) install the package and mount the builder
|
|
5
|
+
* inside their own Vue 3 app:
|
|
6
|
+
*
|
|
7
|
+
* ```vue
|
|
8
|
+
* <script setup>
|
|
9
|
+
* import { CobaltFormBuilder } from '@prolibu-suite/cobalt-form-builder';
|
|
10
|
+
* import '@prolibu-suite/cobalt-form-builder/style.css';
|
|
11
|
+
* // Required peer setup (tokens + custom elements registration):
|
|
12
|
+
* import '@prolibu-suite/cobalt-tokens/css';
|
|
13
|
+
* const schema = ref({});
|
|
14
|
+
* </script>
|
|
15
|
+
*
|
|
16
|
+
* <template>
|
|
17
|
+
* <CobaltFormBuilder v-model="schema" @save="save" />
|
|
18
|
+
* </template>
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* The component handles its own Pinia store internally. **V1 limitation**:
|
|
22
|
+
* the store is a singleton, so only one `<CobaltFormBuilder>` can be
|
|
23
|
+
* mounted on a page at a time (multi-instance support comes in Fase 2 via
|
|
24
|
+
* provide/inject scoping).
|
|
25
|
+
*/
|
|
26
|
+
import './style.css';
|
|
27
|
+
export { default as CobaltFormBuilder } from './CobaltFormBuilder.vue';
|
|
28
|
+
export type { PagedSchema, PageDefinition, ResolvedTheme, ThemeSpec, } from '@prolibu-suite/cobalt-form-core';
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAIvE,YAAY,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,GACV,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { type InjectionKey } from 'vue';
|
|
2
|
+
import { type ThemeSpec } from '@prolibu-suite/cobalt-form-core';
|
|
3
|
+
/**
|
|
4
|
+
* Internal model for the builder. We always work with the paged shape so
|
|
5
|
+
* the UI can render pages as containers à la SurveyJS, even when the user
|
|
6
|
+
* only has one page.
|
|
7
|
+
*/
|
|
8
|
+
interface BuilderPage {
|
|
9
|
+
name: string;
|
|
10
|
+
title?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
visibleIf?: string;
|
|
13
|
+
hideTitle?: boolean;
|
|
14
|
+
hideDescription?: boolean;
|
|
15
|
+
fields: Record<string, any>;
|
|
16
|
+
}
|
|
17
|
+
interface BuilderSchema {
|
|
18
|
+
title: string;
|
|
19
|
+
description: string;
|
|
20
|
+
mode: 'form' | 'quiz' | 'survey';
|
|
21
|
+
pages: BuilderPage[];
|
|
22
|
+
theme: ThemeSpec;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Selection has three scopes, each editing a different layer of the schema:
|
|
26
|
+
* - `form` → global form-level settings (theme, title, mode).
|
|
27
|
+
* - `page` → page-level (id, visibleIf, etc.). pageIdx points at it.
|
|
28
|
+
* - `field` → field inside the current page. fieldName is the key.
|
|
29
|
+
*/
|
|
30
|
+
export interface Selection {
|
|
31
|
+
kind: 'form' | 'page' | 'field';
|
|
32
|
+
pageIdx: number;
|
|
33
|
+
fieldName: string | null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Granular events the store emits on mutations. `CobaltFormBuilder` bridges
|
|
37
|
+
* them to Vue emits so host apps can react to specific actions (e.g. track
|
|
38
|
+
* analytics when a field is added).
|
|
39
|
+
*/
|
|
40
|
+
export type SchemaEvent = {
|
|
41
|
+
type: 'field-added';
|
|
42
|
+
pageIdx: number;
|
|
43
|
+
fieldName: string;
|
|
44
|
+
kind: string;
|
|
45
|
+
} | {
|
|
46
|
+
type: 'field-removed';
|
|
47
|
+
pageIdx: number;
|
|
48
|
+
fieldName: string;
|
|
49
|
+
} | {
|
|
50
|
+
type: 'field-renamed';
|
|
51
|
+
pageIdx: number;
|
|
52
|
+
oldName: string;
|
|
53
|
+
newName: string;
|
|
54
|
+
} | {
|
|
55
|
+
type: 'field-updated';
|
|
56
|
+
pageIdx: number;
|
|
57
|
+
fieldName: string;
|
|
58
|
+
patch: Record<string, any>;
|
|
59
|
+
} | {
|
|
60
|
+
type: 'field-duplicated';
|
|
61
|
+
pageIdx: number;
|
|
62
|
+
sourceName: string;
|
|
63
|
+
newName: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'field-reordered';
|
|
66
|
+
pageIdx: number;
|
|
67
|
+
order: string[];
|
|
68
|
+
} | {
|
|
69
|
+
type: 'page-added';
|
|
70
|
+
pageIdx: number;
|
|
71
|
+
} | {
|
|
72
|
+
type: 'page-removed';
|
|
73
|
+
pageIdx: number;
|
|
74
|
+
} | {
|
|
75
|
+
type: 'page-duplicated';
|
|
76
|
+
sourceIdx: number;
|
|
77
|
+
newIdx: number;
|
|
78
|
+
} | {
|
|
79
|
+
type: 'page-updated';
|
|
80
|
+
pageIdx: number;
|
|
81
|
+
patch: Record<string, any>;
|
|
82
|
+
} | {
|
|
83
|
+
type: 'theme-changed';
|
|
84
|
+
theme: ThemeSpec;
|
|
85
|
+
} | {
|
|
86
|
+
type: 'selection-changed';
|
|
87
|
+
selection: Selection;
|
|
88
|
+
} | {
|
|
89
|
+
type: 'schema-replaced';
|
|
90
|
+
} | {
|
|
91
|
+
type: 'undo';
|
|
92
|
+
} | {
|
|
93
|
+
type: 'redo';
|
|
94
|
+
};
|
|
95
|
+
export declare const FIELD_DEFAULTS: Record<string, () => Record<string, any>>;
|
|
96
|
+
export interface SchemaStoreOptions {
|
|
97
|
+
/** Schema to hydrate the builder with on creation. */
|
|
98
|
+
initialSchema?: Record<string, any>;
|
|
99
|
+
/** Bag of typed events the host can listen to (in addition to v-model). */
|
|
100
|
+
onEvent?: (event: SchemaEvent) => void;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create an independent schema-store instance. Each `<CobaltFormBuilder>`
|
|
104
|
+
* mounts its own store and provides it via `SCHEMA_STORE_KEY` so child
|
|
105
|
+
* components inject it without sharing state across instances.
|
|
106
|
+
*
|
|
107
|
+
* Returned shape matches the public composable API the components used
|
|
108
|
+
* before (data, selection, methods) — no Pinia involved.
|
|
109
|
+
*/
|
|
110
|
+
export declare function createSchemaStore(options?: SchemaStoreOptions): {
|
|
111
|
+
data: {
|
|
112
|
+
title: string;
|
|
113
|
+
description: string;
|
|
114
|
+
mode: "form" | "quiz" | "survey";
|
|
115
|
+
pages: {
|
|
116
|
+
name: string;
|
|
117
|
+
title?: string | undefined;
|
|
118
|
+
description?: string | undefined;
|
|
119
|
+
visibleIf?: string | undefined;
|
|
120
|
+
hideTitle?: boolean | undefined;
|
|
121
|
+
hideDescription?: boolean | undefined;
|
|
122
|
+
fields: Record<string, any>;
|
|
123
|
+
}[];
|
|
124
|
+
theme: {
|
|
125
|
+
colorScheme?: import("@prolibu-suite/cobalt-form-core").ColorScheme | undefined;
|
|
126
|
+
accent?: import("@prolibu-suite/cobalt-form-core").AccentPreset | undefined;
|
|
127
|
+
accentHex?: string | undefined;
|
|
128
|
+
questionAppearance?: import("@prolibu-suite/cobalt-form-core").QuestionAppearance | undefined;
|
|
129
|
+
density?: import("@prolibu-suite/cobalt-form-core").Density | undefined;
|
|
130
|
+
borderRadius?: import("@prolibu-suite/cobalt-form-core").BorderRadius | undefined;
|
|
131
|
+
background?: {
|
|
132
|
+
color?: string | null | undefined;
|
|
133
|
+
imageUrl?: string | null | undefined;
|
|
134
|
+
imageSize?: import("@prolibu-suite/cobalt-form-core").BackgroundSize | undefined;
|
|
135
|
+
imageAttachment?: import("@prolibu-suite/cobalt-form-core").BackgroundAttachment | undefined;
|
|
136
|
+
opacity?: number | undefined;
|
|
137
|
+
} | undefined;
|
|
138
|
+
header?: {
|
|
139
|
+
show?: boolean | undefined;
|
|
140
|
+
backgroundColor?: string | null | undefined;
|
|
141
|
+
height?: string | null | undefined;
|
|
142
|
+
} | undefined;
|
|
143
|
+
fontFamily?: string | undefined;
|
|
144
|
+
customCss?: string | undefined;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
selection: {
|
|
148
|
+
kind: "form" | "page" | "field";
|
|
149
|
+
pageIdx: number;
|
|
150
|
+
fieldName: string | null;
|
|
151
|
+
};
|
|
152
|
+
currentPage: BuilderPage | null;
|
|
153
|
+
selectedField: any;
|
|
154
|
+
canUndo: boolean;
|
|
155
|
+
canRedo: boolean;
|
|
156
|
+
exported: Record<string, any>;
|
|
157
|
+
resolvedTheme: import("@prolibu-suite/cobalt-form-core").ResolvedTheme;
|
|
158
|
+
selectField: (pageIdx: number, fieldName: string | null) => void;
|
|
159
|
+
selectPage: (pageIdx: number) => void;
|
|
160
|
+
selectForm: () => void;
|
|
161
|
+
undo: () => void;
|
|
162
|
+
redo: () => void;
|
|
163
|
+
setTitle: (title: string) => void;
|
|
164
|
+
setDescription: (description: string) => void;
|
|
165
|
+
setMode: (mode: BuilderSchema["mode"]) => void;
|
|
166
|
+
setTheme: (patch: Partial<ThemeSpec>) => void;
|
|
167
|
+
setThemeSection: (section: "background" | "header", patch: Record<string, any>) => void;
|
|
168
|
+
resetTheme: () => void;
|
|
169
|
+
addPage: () => void;
|
|
170
|
+
removePage: (idx: number) => void;
|
|
171
|
+
duplicatePage: (idx: number) => void;
|
|
172
|
+
updatePage: (idx: number, patch: Partial<BuilderPage>) => void;
|
|
173
|
+
addField: (kind: string, pageIdx?: number) => void;
|
|
174
|
+
insertFieldAfter: (pageIdx: number, refName: string, kind: string) => void;
|
|
175
|
+
removeField: (pageIdx: number, name: string) => void;
|
|
176
|
+
duplicateField: (pageIdx: number, name: string) => void;
|
|
177
|
+
updateField: (pageIdx: number, name: string, patch: Record<string, any>) => void;
|
|
178
|
+
replaceFieldDef: (pageIdx: number, name: string, newDef: Record<string, any>) => void;
|
|
179
|
+
renameField: (pageIdx: number, oldName: string, newName: string) => void;
|
|
180
|
+
moveField: (pageIdx: number, fromIdx: number, toIdx: number) => void;
|
|
181
|
+
reorderFieldsByNames: (pageIdx: number, names: string[]) => void;
|
|
182
|
+
replaceAll: (raw: any) => void;
|
|
183
|
+
};
|
|
184
|
+
export type SchemaStore = ReturnType<typeof createSchemaStore>;
|
|
185
|
+
export declare const SCHEMA_STORE_KEY: InjectionKey<SchemaStore>;
|
|
186
|
+
/**
|
|
187
|
+
* Inject the schema store provided by an ancestor `<CobaltFormBuilder>`.
|
|
188
|
+
* Throws if called outside one — that's almost always a bug worth surfacing
|
|
189
|
+
* loudly rather than silently returning an unrelated singleton.
|
|
190
|
+
*/
|
|
191
|
+
export declare function useSchemaStore(): SchemaStore;
|
|
192
|
+
export {};
|
|
193
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/stores/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": {
|
|
3
|
+
"type": "String",
|
|
4
|
+
"required": true,
|
|
5
|
+
"label": "Nombre completo",
|
|
6
|
+
"placeholder": "Ej. María González",
|
|
7
|
+
"full": true,
|
|
8
|
+
"minLength": 2
|
|
9
|
+
},
|
|
10
|
+
"email": {
|
|
11
|
+
"type": "String",
|
|
12
|
+
"required": true,
|
|
13
|
+
"format": "email",
|
|
14
|
+
"label": "Email",
|
|
15
|
+
"placeholder": "tu@ejemplo.com"
|
|
16
|
+
},
|
|
17
|
+
"phone": {
|
|
18
|
+
"type": "String",
|
|
19
|
+
"label": "Teléfono",
|
|
20
|
+
"placeholder": "+57 300 123 4567"
|
|
21
|
+
},
|
|
22
|
+
"message": {
|
|
23
|
+
"type": "String",
|
|
24
|
+
"uiCom": "TextArea",
|
|
25
|
+
"label": "Mensaje",
|
|
26
|
+
"placeholder": "Cuéntanos en qué podemos ayudarte",
|
|
27
|
+
"full": true,
|
|
28
|
+
"maxLength": 500
|
|
29
|
+
},
|
|
30
|
+
"newsletter": {
|
|
31
|
+
"type": "Boolean",
|
|
32
|
+
"label": "Suscribirme al newsletter",
|
|
33
|
+
"default": true,
|
|
34
|
+
"full": true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Encuesta de Satisfacción",
|
|
3
|
+
"description": "Tu opinión nos ayuda a mejorar",
|
|
4
|
+
"mode": "survey",
|
|
5
|
+
"pages": [
|
|
6
|
+
{
|
|
7
|
+
"name": "rating",
|
|
8
|
+
"title": "¿Cómo nos calificas?",
|
|
9
|
+
"fields": {
|
|
10
|
+
"nps_score": {
|
|
11
|
+
"type": "Number",
|
|
12
|
+
"uiCom": "Rating",
|
|
13
|
+
"max": 10,
|
|
14
|
+
"label": "¿Qué tan probable es que nos recomiendes? (0-10)",
|
|
15
|
+
"required": true,
|
|
16
|
+
"full": true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "detractor",
|
|
22
|
+
"title": "Cuéntanos más",
|
|
23
|
+
"visibleIf": "{nps_score} < 7",
|
|
24
|
+
"fields": {
|
|
25
|
+
"problem": {
|
|
26
|
+
"type": "String",
|
|
27
|
+
"uiCom": "TextArea",
|
|
28
|
+
"label": "¿Qué podríamos mejorar?",
|
|
29
|
+
"required": true,
|
|
30
|
+
"full": true,
|
|
31
|
+
"minLength": 10
|
|
32
|
+
},
|
|
33
|
+
"contact_back": {
|
|
34
|
+
"type": "Boolean",
|
|
35
|
+
"label": "Me gustaría que me contacten",
|
|
36
|
+
"full": true
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "promoter",
|
|
42
|
+
"title": "¡Gracias!",
|
|
43
|
+
"visibleIf": "{nps_score} >= 9",
|
|
44
|
+
"fields": {
|
|
45
|
+
"highlight": {
|
|
46
|
+
"type": "String",
|
|
47
|
+
"enum": ["Velocidad", "Diseño", "Soporte", "Precio", "Funcionalidades"],
|
|
48
|
+
"label": "¿Qué es lo que más te gusta?",
|
|
49
|
+
"full": true
|
|
50
|
+
},
|
|
51
|
+
"share": {
|
|
52
|
+
"type": "Boolean",
|
|
53
|
+
"label": "Compartir mi testimonio públicamente",
|
|
54
|
+
"full": true
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Quiz: Vue 3 Fundamentals",
|
|
3
|
+
"mode": "quiz",
|
|
4
|
+
"pages": [
|
|
5
|
+
{
|
|
6
|
+
"name": "p1",
|
|
7
|
+
"title": "Composition API",
|
|
8
|
+
"fields": {
|
|
9
|
+
"q1_reactive": {
|
|
10
|
+
"type": "String",
|
|
11
|
+
"enum": ["ref()", "reactive()", "computed()", "watch()"],
|
|
12
|
+
"label": "¿Cuál crea un proxy reactivo de un objeto?",
|
|
13
|
+
"required": true,
|
|
14
|
+
"full": true,
|
|
15
|
+
"quiz": { "correctAnswer": "reactive()", "points": 10 }
|
|
16
|
+
},
|
|
17
|
+
"q2_lifecycle": {
|
|
18
|
+
"type": "String",
|
|
19
|
+
"enum": ["onMounted", "onCreated", "onInit", "onBeforeRender"],
|
|
20
|
+
"label": "Hook que reemplaza a 'mounted' en Composition API",
|
|
21
|
+
"required": true,
|
|
22
|
+
"full": true,
|
|
23
|
+
"quiz": { "correctAnswer": "onMounted", "points": 10 }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "p2",
|
|
29
|
+
"title": "Reactividad",
|
|
30
|
+
"fields": {
|
|
31
|
+
"q3_unwrap": {
|
|
32
|
+
"type": "Boolean",
|
|
33
|
+
"label": "Los refs se auto-unwrappean en el template",
|
|
34
|
+
"required": true,
|
|
35
|
+
"full": true,
|
|
36
|
+
"quiz": { "correctAnswer": true, "points": 10 }
|
|
37
|
+
},
|
|
38
|
+
"q4_features": {
|
|
39
|
+
"type": "String",
|
|
40
|
+
"enum": ["computed", "watch", "watchEffect", "v-for"],
|
|
41
|
+
"multiple": true,
|
|
42
|
+
"label": "¿Cuáles son parte del sistema de reactividad? (varias)",
|
|
43
|
+
"required": true,
|
|
44
|
+
"full": true,
|
|
45
|
+
"quiz": { "correctAnswer": ["computed", "watch", "watchEffect"], "points": 20 }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"scoring": {
|
|
51
|
+
"showScore": true,
|
|
52
|
+
"passingScore": 70,
|
|
53
|
+
"feedbackRules": [
|
|
54
|
+
{ "expression": "{_score} == 100", "message": "🎉 Perfecto — manejas Vue 3 al 100%" },
|
|
55
|
+
{ "expression": "{_score} >= 70 && {_score} < 100", "message": "✅ Aprobado, pero hay espacio para repasar." },
|
|
56
|
+
{ "expression": "{_score} < 70", "message": "📚 Te recomendamos repasar la documentación oficial." }
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Registro: DevConf 2026",
|
|
3
|
+
"description": "Únete a la conferencia de devs más grande del año",
|
|
4
|
+
"pages": [
|
|
5
|
+
{
|
|
6
|
+
"name": "personal",
|
|
7
|
+
"title": "Datos personales",
|
|
8
|
+
"fields": {
|
|
9
|
+
"full_name": {
|
|
10
|
+
"type": "String",
|
|
11
|
+
"required": true,
|
|
12
|
+
"label": "Nombre completo",
|
|
13
|
+
"full": true
|
|
14
|
+
},
|
|
15
|
+
"email": {
|
|
16
|
+
"type": "String",
|
|
17
|
+
"required": true,
|
|
18
|
+
"format": "email",
|
|
19
|
+
"label": "Email corporativo"
|
|
20
|
+
},
|
|
21
|
+
"role": {
|
|
22
|
+
"type": "String",
|
|
23
|
+
"enum": ["Frontend", "Backend", "Full-stack", "DevOps", "Manager", "Otro"],
|
|
24
|
+
"required": true,
|
|
25
|
+
"label": "Rol"
|
|
26
|
+
},
|
|
27
|
+
"experience": {
|
|
28
|
+
"type": "Number",
|
|
29
|
+
"uiCom": "Slider",
|
|
30
|
+
"min": 0,
|
|
31
|
+
"max": 20,
|
|
32
|
+
"step": 1,
|
|
33
|
+
"label": "Años de experiencia",
|
|
34
|
+
"full": true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "preferences",
|
|
40
|
+
"title": "Preferencias",
|
|
41
|
+
"fields": {
|
|
42
|
+
"tracks": {
|
|
43
|
+
"type": "String",
|
|
44
|
+
"enum": ["AI/ML", "Frontend", "Backend", "Cloud", "Security", "Mobile"],
|
|
45
|
+
"multiple": true,
|
|
46
|
+
"label": "Tracks de interés (selecciona varios)",
|
|
47
|
+
"required": true,
|
|
48
|
+
"full": true
|
|
49
|
+
},
|
|
50
|
+
"satisfaction_last_year": {
|
|
51
|
+
"type": "Number",
|
|
52
|
+
"uiCom": "Rating",
|
|
53
|
+
"max": 5,
|
|
54
|
+
"label": "Si fuiste el año pasado, ¿cómo lo calificarías?",
|
|
55
|
+
"full": true
|
|
56
|
+
},
|
|
57
|
+
"dietary": {
|
|
58
|
+
"type": "String",
|
|
59
|
+
"uiCom": "TextArea",
|
|
60
|
+
"label": "Restricciones alimentarias",
|
|
61
|
+
"placeholder": "Vegetariano, gluten-free, alergias…",
|
|
62
|
+
"full": true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "extras",
|
|
68
|
+
"title": "Extras",
|
|
69
|
+
"fields": {
|
|
70
|
+
"wants_swag": {
|
|
71
|
+
"type": "Boolean",
|
|
72
|
+
"label": "Quiero el kit de bienvenida",
|
|
73
|
+
"default": true,
|
|
74
|
+
"full": true
|
|
75
|
+
},
|
|
76
|
+
"swag_size": {
|
|
77
|
+
"type": "String",
|
|
78
|
+
"enum": ["XS", "S", "M", "L", "XL", "XXL"],
|
|
79
|
+
"label": "Talla de camiseta",
|
|
80
|
+
"visibleIf": "{wants_swag} == true",
|
|
81
|
+
"requiredIf": "{wants_swag} == true",
|
|
82
|
+
"full": true
|
|
83
|
+
},
|
|
84
|
+
"accent_color": {
|
|
85
|
+
"type": "String",
|
|
86
|
+
"uiCom": "ColorPicker",
|
|
87
|
+
"label": "Color favorito (para tu badge)",
|
|
88
|
+
"default": "#2563EB",
|
|
89
|
+
"full": true
|
|
90
|
+
},
|
|
91
|
+
"photo": {
|
|
92
|
+
"type": "String",
|
|
93
|
+
"uiCom": "File",
|
|
94
|
+
"label": "Foto de perfil (opcional)",
|
|
95
|
+
"full": true
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|