@duffcloudservices/site-forms 0.1.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.
Files changed (51) hide show
  1. package/README.md +213 -0
  2. package/dist/DcsForm.vue.d.ts +67 -0
  3. package/dist/composables/useDcsForm.d.ts +36 -0
  4. package/dist/composables/useFormSubmission.d.ts +18 -0
  5. package/dist/composables/useFormValidation.d.ts +19 -0
  6. package/dist/fields/DcsFormCheckbox.vue.d.ts +12 -0
  7. package/dist/fields/DcsFormCheckboxGroup.vue.d.ts +12 -0
  8. package/dist/fields/DcsFormDate.vue.d.ts +14 -0
  9. package/dist/fields/DcsFormFieldWrapper.vue.d.ts +27 -0
  10. package/dist/fields/DcsFormFile.vue.d.ts +12 -0
  11. package/dist/fields/DcsFormHidden.vue.d.ts +7 -0
  12. package/dist/fields/DcsFormHtmlBlock.vue.d.ts +6 -0
  13. package/dist/fields/DcsFormRadio.vue.d.ts +12 -0
  14. package/dist/fields/DcsFormSection.vue.d.ts +21 -0
  15. package/dist/fields/DcsFormSelect.vue.d.ts +35 -0
  16. package/dist/fields/DcsFormText.vue.d.ts +34 -0
  17. package/dist/fields/DcsFormTextarea.vue.d.ts +34 -0
  18. package/dist/index.d.ts +22 -0
  19. package/dist/index.js +918 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/loaders/yaml.d.ts +12 -0
  22. package/dist/schema/validate.d.ts +9 -0
  23. package/dist/types.d.ts +106 -0
  24. package/package.json +73 -0
  25. package/src/DcsForm.vue +299 -0
  26. package/src/__tests__/fields.test.ts +82 -0
  27. package/src/__tests__/multi-step.test.ts +46 -0
  28. package/src/__tests__/schema.test.ts +42 -0
  29. package/src/__tests__/submission.test.ts +77 -0
  30. package/src/__tests__/visible-if.test.ts +111 -0
  31. package/src/composables/useDcsForm.ts +201 -0
  32. package/src/composables/useFormSubmission.ts +113 -0
  33. package/src/composables/useFormValidation.ts +127 -0
  34. package/src/fields/DcsFormCheckbox.vue +35 -0
  35. package/src/fields/DcsFormCheckboxGroup.vue +52 -0
  36. package/src/fields/DcsFormDate.vue +34 -0
  37. package/src/fields/DcsFormFieldWrapper.vue +39 -0
  38. package/src/fields/DcsFormFile.vue +38 -0
  39. package/src/fields/DcsFormHidden.vue +17 -0
  40. package/src/fields/DcsFormHtmlBlock.vue +19 -0
  41. package/src/fields/DcsFormRadio.vue +45 -0
  42. package/src/fields/DcsFormSection.vue +19 -0
  43. package/src/fields/DcsFormSelect.vue +62 -0
  44. package/src/fields/DcsFormText.vue +54 -0
  45. package/src/fields/DcsFormTextarea.vue +43 -0
  46. package/src/index.ts +51 -0
  47. package/src/loaders/yaml.ts +51 -0
  48. package/src/schema/form-definition.schema.json +633 -0
  49. package/src/schema/validate.ts +58 -0
  50. package/src/shims.d.ts +10 -0
  51. package/src/types.ts +140 -0
package/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # @duffcloudservices/site-forms
2
+
3
+ Shared `<DcsForm/>` runtime for DCS customer sites. Renders a managed
4
+ form definition (created in the portal Form Manager) from a build-time
5
+ `.dcs/forms/<formId>.yaml` snapshot, validates user input, and posts
6
+ submissions to the public site-forms API.
7
+
8
+ This is the single import surface for managed-form runtime code on
9
+ customer sites — do not redefine field components per site.
10
+
11
+ > **Inside the `dcs-again` workspace** the package is also reachable
12
+ > as `@duffcloudservices/site-forms` via `workspace:*` (the workspace
13
+ > name and the published name are the same).
14
+ > **In sibling customer-site repos** install the published package
15
+ > from public npm — see [`PUBLISHING.md`](./PUBLISHING.md) for the
16
+ > consumption story and registry setup.
17
+
18
+ ## Install
19
+
20
+ ### In a workspace app (inside `dcs-again`)
21
+
22
+ ```jsonc
23
+ // portal/package.json
24
+ {
25
+ "dependencies": {
26
+ "@duffcloudservices/site-forms": "workspace:*"
27
+ }
28
+ }
29
+ ```
30
+
31
+ Then `pnpm install` from the repo root.
32
+
33
+ ### In a sibling customer-site repo (e.g. `ktbraunlaw`, `kept`)
34
+
35
+ ```powershell
36
+ pnpm add @duffcloudservices/site-forms
37
+ ```
38
+
39
+ See [`PUBLISHING.md`](./PUBLISHING.md) for the registry, version, and
40
+ release-workflow details.
41
+
42
+ ## Vite setup
43
+
44
+ Two pieces are required in the consuming site:
45
+
46
+ 1. **`vite-plugin-yaml`** so `import.meta.glob('/.dcs/forms/*.yaml', { eager: true, import: 'default' })` returns parsed objects:
47
+
48
+ ```ts
49
+ // vite.config.ts
50
+ import yaml from '@modyfi/vite-plugin-yaml'
51
+
52
+ export default defineConfig({
53
+ plugins: [vue(), yaml()],
54
+ })
55
+ ```
56
+
57
+ Without it, the loader falls back to parsing raw strings via
58
+ `js-yaml`, which works but pays the parse cost at boot.
59
+
60
+ 2. **Env vars** the runtime reads:
61
+
62
+ | Variable | Purpose |
63
+ | ----------------------- | ---------------------------------------------------- |
64
+ | `VITE_DCS_PUBLIC_API` | Base URL of the DCS public API (no trailing slash). |
65
+ | `VITE_DCS_SITE_SLUG` | Default site slug used when the prop is omitted. |
66
+
67
+ ## Usage
68
+
69
+ Place a YAML file at `<site>/.dcs/forms/contact.yaml`:
70
+
71
+ ```yaml
72
+ formId: contact
73
+ title: Contact Us
74
+ submission:
75
+ kind: lead
76
+ fields:
77
+ - id: name
78
+ type: text
79
+ label: Name
80
+ required: true
81
+ - id: email
82
+ type: email
83
+ label: Email
84
+ required: true
85
+ - id: message
86
+ type: textarea
87
+ label: Message
88
+ required: true
89
+ ```
90
+
91
+ Then in any page component:
92
+
93
+ ```vue
94
+ <script setup lang="ts">
95
+ import { DcsForm } from '@duffcloudservices/site-forms'
96
+ </script>
97
+
98
+ <template>
99
+ <DcsForm
100
+ form-id="contact"
101
+ @submit-success="onSuccess"
102
+ @submit-error="onError"
103
+ />
104
+ </template>
105
+ ```
106
+
107
+ ## Props
108
+
109
+ | Prop | Type | Default | Notes |
110
+ | -------------------- | --------------------------------- | -------------------------------------- | ----------------------------------------------------------- |
111
+ | `formId` | `string` (required) | — | Matches `.dcs/forms/<formId>.yaml`. |
112
+ | `siteSlug` | `string` | `import.meta.env.VITE_DCS_SITE_SLUG` | Path segment in the submission URL. |
113
+ | `definitionOverride` | `PortalFormDefinition` | — | Used by the portal preview iframe to show in-flight edits. |
114
+ | `apiBase` | `string` | `import.meta.env.VITE_DCS_PUBLIC_API` | Override for tests / non-prod environments. |
115
+ | `captchaToken` | `string` | — | Attached to the submission payload when set. |
116
+ | `formsModules` | `Record<string, unknown>` | `import.meta.glob(...)` | Test-only override for the YAML modules map. |
117
+
118
+ ## Emits
119
+
120
+ | Event | Payload | When |
121
+ | ------------------ | ---------------------- | ------------------------------------------- |
122
+ | `submit-success` | `DcsFormSubmitSuccess` | API responded `2xx`. |
123
+ | `submit-error` | `DcsFormSubmitError` | Network or non-2xx response after retries. |
124
+ | `validation-error` | `FormErrors` | Submit attempted with invalid required/regex/etc. fields. |
125
+
126
+ ## Slots
127
+
128
+ Every slot exposes scoped data so consumers (KT Braun, Kept) can swap
129
+ shadcn primitives in without forking field components.
130
+
131
+ | Slot | Scope | Default |
132
+ | ---------- | ------------------------------------------------------------------ | ---------------------------------------------------- |
133
+ | `header` | `{ definition }` | `<h2>` + description |
134
+ | `progress` | `{ current, total, step }` | `Step N of M — Title` (multi-step only) |
135
+ | `actions` | `{ isFirstStep, isLastStep, submitting, prev, next }` | Plain `<button>` elements |
136
+ | `success` | `{ definition }` | `definition.successMessage` |
137
+ | `missing` | `{ formId }` | Friendly fallback when the YAML can't be found |
138
+
139
+ Per-field components (`DcsFormText` etc.) expose `#input` slots so a
140
+ shadcn site can replace the underlying primitive while keeping the
141
+ wrapper, label, help, and error-message structure.
142
+
143
+ ## Composables
144
+
145
+ For sites that want a fully custom layout, drop `<DcsForm/>` and use
146
+ the underlying composables directly:
147
+
148
+ ```ts
149
+ import {
150
+ useDcsForm,
151
+ validateForm,
152
+ submitFormValues,
153
+ parseFormYaml,
154
+ } from '@duffcloudservices/site-forms'
155
+ ```
156
+
157
+ - `useDcsForm({ definition })` — reactive `values`, `errors`, `steps`,
158
+ `next`, `prev`, `validateAll`, `collectSubmissionValues`, etc.
159
+ - `validateForm(def, values, fieldIds?)` — pure validator usable in
160
+ any setting (server-side, tests, custom adapters).
161
+ - `submitFormValues({ apiBase, siteSlug, payload })` — one-shot POST
162
+ with a single retry on 5xx and `multipart/form-data` when files are
163
+ present.
164
+
165
+ ## Visual editor integration
166
+
167
+ The form root carries `data-form-key="<formId>"` and every field
168
+ wrapper carries `data-form-field-key="<fieldId>"`. The portal preview
169
+ iframe bridge uses these to highlight and select form regions. Do not
170
+ strip them in custom layouts.
171
+
172
+ ## Schema validation
173
+
174
+ In dev (`import.meta.env.DEV === true`) the runtime validates each
175
+ loaded definition against the JSON Schema bundled in
176
+ `src/schema/form-definition.schema.json` (snapshot of
177
+ `contracts/dist/form-definition.schema.json`) and logs failures via
178
+ `console.warn`. Production builds skip the warning to avoid noisy
179
+ end-user consoles.
180
+
181
+ When the contracts schema is regenerated (`pnpm --filter @dcs/contracts
182
+ generate`), refresh the snapshot:
183
+
184
+ ```powershell
185
+ Copy-Item ../../contracts/dist/form-definition.schema.json ./src/schema/form-definition.schema.json -Force
186
+ pnpm --filter @duffcloudservices/site-forms test --run
187
+ ```
188
+
189
+ ## Scripts
190
+
191
+ ```powershell
192
+ pnpm --filter @duffcloudservices/site-forms build # vite library build (esm + dts)
193
+ pnpm --filter @duffcloudservices/site-forms test # vitest --run
194
+ pnpm --filter @duffcloudservices/site-forms type-check # vue-tsc --noEmit
195
+ ```
196
+
197
+ ## Related docs
198
+
199
+ - **Authoring guide** — [`.docs/forms/AUTHORING.md`](../../.docs/forms/AUTHORING.md)
200
+ covers the YAML schema, worked examples, validation flow, HIPAA
201
+ guardrails, and the hand-coded → `<DcsForm/>` migration recipe.
202
+ - **Publishing** — [`PUBLISHING.md`](./PUBLISHING.md) covers the
203
+ registry, OIDC trusted publishing, version bump policy, and the
204
+ exact dep line sibling customer-site repos should add.
205
+ - **Validation CLI** — [`cli/forms/README.md`](../../cli/forms/README.md)
206
+ documents `dcs forms validate` and `dcs forms doctor`, which lint
207
+ the `.dcs/forms/*.yaml` files in a customer-site repo.
208
+
209
+ ## Ownership
210
+
211
+ Per `packages/README.md`: external/consumer-facing docs live here, not
212
+ in repo-root docs. Cross-cutting details (e.g. the public submissions
213
+ API contract) belong in `contracts/README.md`.
@@ -0,0 +1,67 @@
1
+ import { DcsFormSubmitError, DcsFormSubmitSuccess, PortalFormDefinition } from './types';
2
+ interface Props {
3
+ /** Kebab-case form id; matches `.dcs/forms/<formId>.yaml`. */
4
+ formId: string;
5
+ /** Site slug used for the submission endpoint path. */
6
+ siteSlug?: string;
7
+ /** Override the loaded definition (used by the portal preview iframe). */
8
+ definitionOverride?: PortalFormDefinition;
9
+ /** Override the API base URL; defaults to `VITE_DCS_PUBLIC_API`. */
10
+ apiBase?: string;
11
+ /** Optional captcha token, attached to the submission payload. */
12
+ captchaToken?: string;
13
+ /**
14
+ * Optional override for the YAML modules map. Mostly for tests; in
15
+ * real apps the build-time `import.meta.glob` call below is used.
16
+ */
17
+ formsModules?: Record<string, unknown>;
18
+ }
19
+ declare function __VLS_template(): {
20
+ attrs: Partial<{}>;
21
+ slots: {
22
+ missing?(_: {
23
+ formId: string;
24
+ }): any;
25
+ success?(_: {
26
+ definition: PortalFormDefinition;
27
+ }): any;
28
+ header?(_: {
29
+ definition: PortalFormDefinition;
30
+ }): any;
31
+ progress?(_: {
32
+ current: number;
33
+ total: number;
34
+ step: import('./types').PortalFormStep | null;
35
+ }): any;
36
+ actions?(_: {
37
+ isFirstStep: boolean;
38
+ isLastStep: boolean;
39
+ submitting: boolean;
40
+ prev: () => void;
41
+ next: () => boolean;
42
+ }): any;
43
+ };
44
+ refs: {
45
+ formEl: HTMLFormElement;
46
+ };
47
+ rootEl: any;
48
+ };
49
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
50
+ declare const __VLS_component: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
51
+ "submit-success": (event: DcsFormSubmitSuccess) => any;
52
+ "submit-error": (event: DcsFormSubmitError) => any;
53
+ "validation-error": (errors: Record<string, string | undefined>) => any;
54
+ }, string, import('vue').PublicProps, Readonly<Props> & Readonly<{
55
+ "onSubmit-success"?: ((event: DcsFormSubmitSuccess) => any) | undefined;
56
+ "onSubmit-error"?: ((event: DcsFormSubmitError) => any) | undefined;
57
+ "onValidation-error"?: ((errors: Record<string, string | undefined>) => any) | undefined;
58
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
59
+ formEl: HTMLFormElement;
60
+ }, any>;
61
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
62
+ export default _default;
63
+ type __VLS_WithTemplateSlots<T, S> = T & {
64
+ new (): {
65
+ $slots: S;
66
+ };
67
+ };
@@ -0,0 +1,36 @@
1
+ import { ComputedRef, Ref } from 'vue';
2
+ import { PortalFormDefinition, PortalFormField, PortalFormStep, FormErrors, FormValues } from '../types';
3
+ export interface UseDcsFormOptions {
4
+ definition: PortalFormDefinition;
5
+ }
6
+ export interface UseDcsFormReturn {
7
+ values: FormValues;
8
+ errors: Ref<FormErrors>;
9
+ touched: Ref<Record<string, boolean>>;
10
+ submitting: Ref<boolean>;
11
+ submitted: Ref<boolean>;
12
+ submitError: Ref<string | null>;
13
+ /** All fields, with layout-only types preserved. */
14
+ fields: ComputedRef<PortalFormField[]>;
15
+ /** Steps if multi-step, else null. */
16
+ steps: ComputedRef<PortalFormStep[] | null>;
17
+ currentStepIndex: Ref<number>;
18
+ currentStep: ComputedRef<PortalFormStep | null>;
19
+ currentStepFields: ComputedRef<PortalFormField[]>;
20
+ isFirstStep: ComputedRef<boolean>;
21
+ isLastStep: ComputedRef<boolean>;
22
+ visibleFields: ComputedRef<PortalFormField[]>;
23
+ /** Sets a field value and clears that field's error. */
24
+ setValue: (id: string, value: unknown) => void;
25
+ /** Marks a field as touched + revalidates only that field's row. */
26
+ touch: (id: string) => void;
27
+ /** Validates the current step (multi-step) or the entire form. */
28
+ validateCurrentScope: () => boolean;
29
+ validateAll: () => boolean;
30
+ next: () => boolean;
31
+ prev: () => void;
32
+ reset: () => void;
33
+ /** Returns the values that should actually be submitted (visible only). */
34
+ collectSubmissionValues: () => FormValues;
35
+ }
36
+ export declare function useDcsForm(opts: UseDcsFormOptions): UseDcsFormReturn;
@@ -0,0 +1,18 @@
1
+ import { DcsFormSubmitPayload, DcsFormSubmitSuccess } from '../types';
2
+ export interface SubmitOptions {
3
+ apiBase: string;
4
+ siteSlug: string;
5
+ payload: DcsFormSubmitPayload;
6
+ /** Number of retries on 5xx / network errors. Default 1. */
7
+ retries?: number;
8
+ /** Optional fetch implementation override (tests). */
9
+ fetchImpl?: typeof fetch;
10
+ }
11
+ /**
12
+ * POSTs a form submission to
13
+ * `${apiBase}/public/sites/{siteSlug}/form-submissions`.
14
+ *
15
+ * Uses JSON for plain values and `multipart/form-data` when any
16
+ * value is a `File` (file-upload fields).
17
+ */
18
+ export declare function submitFormValues(opts: SubmitOptions): Promise<DcsFormSubmitSuccess>;
@@ -0,0 +1,19 @@
1
+ import { PortalFormDefinition, PortalFormField, FormErrors, FormValues } from '../types';
2
+ /**
3
+ * Returns true iff `field` is currently visible given the form's
4
+ * other values. Hidden fields are never validated and never sent.
5
+ */
6
+ export declare function isFieldVisible(field: PortalFormField, values: FormValues): boolean;
7
+ /**
8
+ * Validates a single field's value. Returns an error string or
9
+ * `undefined` if valid. Layout-only field types (section-heading,
10
+ * html-block) and hidden fields never produce errors.
11
+ */
12
+ export declare function validateField(field: PortalFormField, value: unknown): string | undefined;
13
+ /**
14
+ * Validates an entire form. Skips fields that are not visible.
15
+ * If `fieldIds` is supplied, only those fields are validated
16
+ * (used for per-step validation in multi-step forms).
17
+ */
18
+ export declare function validateForm(def: PortalFormDefinition, values: FormValues, fieldIds?: string[]): FormErrors;
19
+ export declare function hasErrors(errors: FormErrors): boolean;
@@ -0,0 +1,12 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: boolean | undefined;
5
+ error?: string;
6
+ };
7
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
8
+ "update:modelValue": (value: boolean) => any;
9
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
12
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: string[] | undefined;
5
+ error?: string;
6
+ };
7
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
8
+ "update:modelValue": (value: string[]) => any;
9
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ "onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
12
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: string | undefined;
5
+ error?: string;
6
+ };
7
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
8
+ "update:modelValue": (value: string) => any;
9
+ blur: () => any;
10
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
12
+ onBlur?: (() => any) | undefined;
13
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
14
+ export default _default;
@@ -0,0 +1,27 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ error?: string;
5
+ /** Optional id to use for the input — wrappers use it for label `for=`. */
6
+ inputId?: string;
7
+ };
8
+ declare function __VLS_template(): {
9
+ attrs: Partial<{}>;
10
+ slots: {
11
+ label?(_: {}): any;
12
+ default?(_: {}): any;
13
+ help?(_: {}): any;
14
+ error?(_: {}): any;
15
+ };
16
+ refs: {};
17
+ rootEl: HTMLDivElement;
18
+ };
19
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
20
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
21
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
22
+ export default _default;
23
+ type __VLS_WithTemplateSlots<T, S> = T & {
24
+ new (): {
25
+ $slots: S;
26
+ };
27
+ };
@@ -0,0 +1,12 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: File | undefined;
5
+ error?: string;
6
+ };
7
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
8
+ "update:modelValue": (value: File | undefined) => any;
9
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ "onUpdate:modelValue"?: ((value: File | undefined) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
12
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: string | number | undefined;
5
+ };
6
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLInputElement>;
7
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ };
5
+ declare const _default: 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
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: string | undefined;
5
+ error?: string;
6
+ };
7
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
8
+ "update:modelValue": (value: string) => any;
9
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
12
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ };
5
+ declare function __VLS_template(): {
6
+ attrs: Partial<{}>;
7
+ slots: {
8
+ default?(_: {}): any;
9
+ };
10
+ refs: {};
11
+ rootEl: HTMLDivElement;
12
+ };
13
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
14
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
15
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
16
+ export default _default;
17
+ type __VLS_WithTemplateSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,35 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: string | string[] | undefined;
5
+ error?: string;
6
+ };
7
+ declare function onChange(e: Event): void;
8
+ declare function __VLS_template(): {
9
+ attrs: Partial<{}>;
10
+ slots: {
11
+ input?(_: {
12
+ id: string;
13
+ value: string | string[] | undefined;
14
+ options: import('..').PortalFormFieldOption[];
15
+ onChange: typeof onChange;
16
+ }): any;
17
+ };
18
+ refs: {};
19
+ rootEl: HTMLDivElement;
20
+ };
21
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
22
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
23
+ "update:modelValue": (value: string | string[]) => any;
24
+ blur: () => any;
25
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
26
+ "onUpdate:modelValue"?: ((value: string | string[]) => any) | undefined;
27
+ onBlur?: (() => any) | undefined;
28
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
29
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
30
+ export default _default;
31
+ type __VLS_WithTemplateSlots<T, S> = T & {
32
+ new (): {
33
+ $slots: S;
34
+ };
35
+ };
@@ -0,0 +1,34 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: string | number | undefined;
5
+ error?: string;
6
+ };
7
+ declare function __VLS_template(): {
8
+ attrs: Partial<{}>;
9
+ slots: {
10
+ input?(_: {
11
+ id: string;
12
+ value: string | number | undefined;
13
+ onInput: (e: Event) => void;
14
+ onBlur: () => void;
15
+ }): any;
16
+ };
17
+ refs: {};
18
+ rootEl: HTMLDivElement;
19
+ };
20
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
21
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
22
+ "update:modelValue": (value: string) => any;
23
+ blur: () => any;
24
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
25
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
26
+ onBlur?: (() => any) | undefined;
27
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
28
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
29
+ export default _default;
30
+ type __VLS_WithTemplateSlots<T, S> = T & {
31
+ new (): {
32
+ $slots: S;
33
+ };
34
+ };
@@ -0,0 +1,34 @@
1
+ import { PortalFormField } from '../types';
2
+ type __VLS_Props = {
3
+ field: PortalFormField;
4
+ modelValue: string | undefined;
5
+ error?: string;
6
+ };
7
+ declare function __VLS_template(): {
8
+ attrs: Partial<{}>;
9
+ slots: {
10
+ input?(_: {
11
+ id: string;
12
+ value: string | undefined;
13
+ onInput: (e: Event) => void;
14
+ onBlur: () => void;
15
+ }): any;
16
+ };
17
+ refs: {};
18
+ rootEl: HTMLDivElement;
19
+ };
20
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
21
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
22
+ "update:modelValue": (value: string) => any;
23
+ blur: () => any;
24
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
25
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
26
+ onBlur?: (() => any) | undefined;
27
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
28
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
29
+ export default _default;
30
+ type __VLS_WithTemplateSlots<T, S> = T & {
31
+ new (): {
32
+ $slots: S;
33
+ };
34
+ };
@@ -0,0 +1,22 @@
1
+ export { default as DcsForm } from './DcsForm.vue';
2
+ export { default as DcsFormText } from './fields/DcsFormText.vue';
3
+ export { default as DcsFormTextarea } from './fields/DcsFormTextarea.vue';
4
+ export { default as DcsFormSelect } from './fields/DcsFormSelect.vue';
5
+ export { default as DcsFormRadio } from './fields/DcsFormRadio.vue';
6
+ export { default as DcsFormCheckboxGroup } from './fields/DcsFormCheckboxGroup.vue';
7
+ export { default as DcsFormCheckbox } from './fields/DcsFormCheckbox.vue';
8
+ export { default as DcsFormDate } from './fields/DcsFormDate.vue';
9
+ export { default as DcsFormFile } from './fields/DcsFormFile.vue';
10
+ export { default as DcsFormHidden } from './fields/DcsFormHidden.vue';
11
+ export { default as DcsFormSection } from './fields/DcsFormSection.vue';
12
+ export { default as DcsFormHtmlBlock } from './fields/DcsFormHtmlBlock.vue';
13
+ export { default as DcsFormFieldWrapper } from './fields/DcsFormFieldWrapper.vue';
14
+ export { useDcsForm } from './composables/useDcsForm';
15
+ export type { UseDcsFormOptions, UseDcsFormReturn } from './composables/useDcsForm';
16
+ export { validateField, validateForm, isFieldVisible, hasErrors, } from './composables/useFormValidation';
17
+ export { submitFormValues } from './composables/useFormSubmission';
18
+ export type { SubmitOptions } from './composables/useFormSubmission';
19
+ export { loadFormDefinitions, parseFormYaml } from './loaders/yaml';
20
+ export { validateFormDefinition, warnIfInvalid, } from './schema/validate';
21
+ export type { SchemaValidationResult } from './schema/validate';
22
+ export type { DcsFormSubmitPayload, DcsFormSubmitSuccess, DcsFormSubmitError, FormErrors, FormValues, PortalFormDefinition, PortalFormField, PortalFormFieldType, PortalFormFieldOption, PortalFormFieldValidation, PortalFormFieldVisibleIf, PortalFormFieldWidth, PortalFormStep, PortalFormSubmissionConfig, PortalFormSubmissionLeadConfig, PortalFormSubmissionEmailConfig, PortalFormSubmissionWebhookConfig, } from './types';