@duffcloudservices/site-forms 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 CHANGED
@@ -1,213 +1,260 @@
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`.
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
+ Three pieces are required in the consuming site:
45
+
46
+ 1. **`vite-plugin-yaml`** so YAML modules return 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. **A `formsModules` loader** in your site that does the
61
+ `import.meta.glob` from a path Vite can resolve (see below).
62
+
63
+ 3. **Env vars** the runtime reads:
64
+
65
+ | Variable | Purpose |
66
+ | ----------------------- | ---------------------------------------------------- |
67
+ | `VITE_DCS_PUBLIC_API` | Base URL of the DCS public API (no trailing slash). |
68
+ | `VITE_DCS_SITE_SLUG` | Default site slug used when the prop is omitted. |
69
+
70
+ ### Why the `formsModules` prop is required in real sites
71
+
72
+ `<DcsForm/>` ships with an internal `import.meta.glob('/.dcs/forms/*.yaml')`
73
+ fallback, but Vite resolves the leading `/` against the **consumer's
74
+ Vite project root** (the directory containing `vite.config.ts`).
75
+ On every customer-site repo today, the `.dcs/forms/` directory lives
76
+ at the **repo root**, one or more levels above the Vite root
77
+ (typically `site/` or `docs/`). The internal glob therefore matches
78
+ nothing and you get:
79
+
80
+ ```
81
+ [@duffcloudservices/site-forms] No form definition found for "contact".
82
+ Expected a YAML at /.dcs/forms/contact.yaml.
83
+ ```
84
+
85
+ The fix is a one-file loader the rest of your site imports from.
86
+
87
+ #### Vue SPA (`vite.config.ts` in `site/`)
88
+
89
+ ```ts
90
+ // site/src/dcs-forms.ts
91
+ const modules = import.meta.glob('../../.dcs/forms/*.yaml', {
92
+ eager: true,
93
+ import: 'default',
94
+ })
95
+ export const dcsFormsModules: Record<string, unknown> = modules
96
+ ```
97
+
98
+ #### VitePress (`vite` block in `docs/.vitepress/config.ts`)
99
+
100
+ ```ts
101
+ // docs/.vitepress/dcs-forms-loader.ts
102
+ const modules = import.meta.glob('../../.dcs/forms/*.yaml', {
103
+ eager: true,
104
+ import: 'default',
105
+ })
106
+ export const dcsFormsModules: Record<string, unknown> = modules
107
+ ```
108
+
109
+ The relative depth (`../../`) depends on where the loader file lives
110
+ relative to the repo root. Adjust as needed.
111
+
112
+ ## Usage
113
+
114
+ Place a YAML file at `<site>/.dcs/forms/contact.yaml`:
115
+
116
+ ```yaml
117
+ formId: contact
118
+ title: Contact Us
119
+ submission:
120
+ kind: lead
121
+ fields:
122
+ - id: name
123
+ type: text
124
+ label: Name
125
+ required: true
126
+ - id: email
127
+ type: email
128
+ label: Email
129
+ required: true
130
+ - id: message
131
+ type: textarea
132
+ label: Message
133
+ required: true
134
+ ```
135
+
136
+ Then in any page component:
137
+
138
+ ```vue
139
+ <script setup lang="ts">
140
+ import { DcsForm } from '@duffcloudservices/site-forms'
141
+ import { dcsFormsModules } from '@/dcs-forms'
142
+ </script>
143
+
144
+ <template>
145
+ <DcsForm
146
+ form-id="contact"
147
+ :forms-modules="dcsFormsModules"
148
+ @submit-success="onSuccess"
149
+ @submit-error="onError"
150
+ />
151
+ </template>
152
+ ```
153
+
154
+ ## Props
155
+
156
+ | Prop | Type | Default | Notes |
157
+ | -------------------- | --------------------------------- | -------------------------------------- | ----------------------------------------------------------- |
158
+ | `formId` | `string` (required) | — | Matches `.dcs/forms/<formId>.yaml`. |
159
+ | `siteSlug` | `string` | `import.meta.env.VITE_DCS_SITE_SLUG` | Path segment in the submission URL. |
160
+ | `definitionOverride` | `PortalFormDefinition` | — | Used by the portal preview iframe to show in-flight edits. |
161
+ | `apiBase` | `string` | `import.meta.env.VITE_DCS_PUBLIC_API` | Override for tests / non-prod environments. |
162
+ | `captchaToken` | `string` | — | Attached to the submission payload when set. |
163
+ | `formsModules` | `Record<string, unknown>` | internal fallback glob (rarely matches) | **Required in real sites.** Pass a `Record<string, unknown>` from your own `import.meta.glob('../../.dcs/forms/*.yaml', { eager: true, import: 'default' })` — see Vite setup section. |
164
+
165
+ ## Emits
166
+
167
+ | Event | Payload | When |
168
+ | ------------------ | ---------------------- | ------------------------------------------- |
169
+ | `submit-success` | `DcsFormSubmitSuccess` | API responded `2xx`. |
170
+ | `submit-error` | `DcsFormSubmitError` | Network or non-2xx response after retries. |
171
+ | `validation-error` | `FormErrors` | Submit attempted with invalid required/regex/etc. fields. |
172
+
173
+ ## Slots
174
+
175
+ Every slot exposes scoped data so consumers (KT Braun, Kept) can swap
176
+ shadcn primitives in without forking field components.
177
+
178
+ | Slot | Scope | Default |
179
+ | ---------- | ------------------------------------------------------------------ | ---------------------------------------------------- |
180
+ | `header` | `{ definition }` | `<h2>` + description |
181
+ | `progress` | `{ current, total, step }` | `Step N of M — Title` (multi-step only) |
182
+ | `actions` | `{ isFirstStep, isLastStep, submitting, prev, next }` | Plain `<button>` elements |
183
+ | `success` | `{ definition }` | `definition.successMessage` |
184
+ | `missing` | `{ formId }` | Friendly fallback when the YAML can't be found |
185
+
186
+ Per-field components (`DcsFormText` etc.) expose `#input` slots so a
187
+ shadcn site can replace the underlying primitive while keeping the
188
+ wrapper, label, help, and error-message structure.
189
+
190
+ ## Composables
191
+
192
+ For sites that want a fully custom layout, drop `<DcsForm/>` and use
193
+ the underlying composables directly:
194
+
195
+ ```ts
196
+ import {
197
+ useDcsForm,
198
+ validateForm,
199
+ submitFormValues,
200
+ parseFormYaml,
201
+ } from '@duffcloudservices/site-forms'
202
+ ```
203
+
204
+ - `useDcsForm({ definition })` reactive `values`, `errors`, `steps`,
205
+ `next`, `prev`, `validateAll`, `collectSubmissionValues`, etc.
206
+ - `validateForm(def, values, fieldIds?)` pure validator usable in
207
+ any setting (server-side, tests, custom adapters).
208
+ - `submitFormValues({ apiBase, siteSlug, payload })` — one-shot POST
209
+ with a single retry on 5xx and `multipart/form-data` when files are
210
+ present.
211
+
212
+ ## Visual editor integration
213
+
214
+ The form root carries `data-form-key="<formId>"` and every field
215
+ wrapper carries `data-form-field-key="<fieldId>"`. The portal preview
216
+ iframe bridge uses these to highlight and select form regions. Do not
217
+ strip them in custom layouts.
218
+
219
+ ## Schema validation
220
+
221
+ In dev (`import.meta.env.DEV === true`) the runtime validates each
222
+ loaded definition against the JSON Schema bundled in
223
+ `src/schema/form-definition.schema.json` (snapshot of
224
+ `contracts/dist/form-definition.schema.json`) and logs failures via
225
+ `console.warn`. Production builds skip the warning to avoid noisy
226
+ end-user consoles.
227
+
228
+ When the contracts schema is regenerated (`pnpm --filter @dcs/contracts
229
+ generate`), refresh the snapshot:
230
+
231
+ ```powershell
232
+ Copy-Item ../../contracts/dist/form-definition.schema.json ./src/schema/form-definition.schema.json -Force
233
+ pnpm --filter @duffcloudservices/site-forms test --run
234
+ ```
235
+
236
+ ## Scripts
237
+
238
+ ```powershell
239
+ pnpm --filter @duffcloudservices/site-forms build # vite library build (esm + dts)
240
+ pnpm --filter @duffcloudservices/site-forms test # vitest --run
241
+ pnpm --filter @duffcloudservices/site-forms type-check # vue-tsc --noEmit
242
+ ```
243
+
244
+ ## Related docs
245
+
246
+ - **Authoring guide** — [`.docs/forms/AUTHORING.md`](../../.docs/forms/AUTHORING.md)
247
+ covers the YAML schema, worked examples, validation flow, HIPAA
248
+ guardrails, and the hand-coded → `<DcsForm/>` migration recipe.
249
+ - **Publishing** — [`PUBLISHING.md`](./PUBLISHING.md) covers the
250
+ registry, OIDC trusted publishing, version bump policy, and the
251
+ exact dep line sibling customer-site repos should add.
252
+ - **Validation CLI** — [`cli/forms/README.md`](../../cli/forms/README.md)
253
+ documents `dcs forms validate` and `dcs forms doctor`, which lint
254
+ the `.dcs/forms/*.yaml` files in a customer-site repo.
255
+
256
+ ## Ownership
257
+
258
+ Per `packages/README.md`: external/consumer-facing docs live here, not
259
+ in repo-root docs. Cross-cutting details (e.g. the public submissions
260
+ API contract) belong in `contracts/README.md`.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { reactive as X, ref as D, computed as p, defineComponent as I, createElementBlock as f, openBlock as l, normalizeClass as Z, renderSlot as S, createCommentVNode as k, createTextVNode as A, toDisplayString as b, createBlock as w, withCtx as V, createElementVNode as v, Fragment as T, renderList as B, watch as H, onMounted as ee, unref as u, resolveDynamicComponent as te } from "vue";
1
+ import { reactive as X, ref as C, computed as p, defineComponent as I, createElementBlock as f, openBlock as l, normalizeClass as Z, renderSlot as S, createCommentVNode as k, createTextVNode as A, toDisplayString as b, createBlock as w, withCtx as V, createElementVNode as v, Fragment as T, renderList as B, watch as H, onMounted as ee, unref as u, resolveDynamicComponent as te } from "vue";
2
2
  import ie from "ajv";
3
3
  import re from "ajv-formats";
4
4
  import K from "js-yaml";
@@ -60,7 +60,7 @@ function _(e) {
60
60
  return t;
61
61
  }
62
62
  function ae(e) {
63
- const { definition: t } = e, r = X(_(t)), i = D({}), o = D({}), d = D(!1), s = D(!1), c = D(null), a = D(0), n = p(() => t.fields), m = p(
63
+ const { definition: t } = e, r = X(_(t)), i = C({}), o = C({}), d = C(!1), s = C(!1), c = C(null), a = C(0), n = p(() => t.fields), m = p(
64
64
  () => t.steps && t.steps.length > 0 ? t.steps : null
65
65
  ), g = p(() => {
66
66
  const h = m.value;
@@ -79,7 +79,7 @@ function ae(e) {
79
79
  function y(h, F) {
80
80
  r[h] = F, i.value[h] && (i.value = { ...i.value, [h]: void 0 });
81
81
  }
82
- function C(h) {
82
+ function D(h) {
83
83
  o.value = { ...o.value, [h]: !0 };
84
84
  }
85
85
  function $(h) {
@@ -134,7 +134,7 @@ function ae(e) {
134
134
  isLastStep: O,
135
135
  visibleFields: z,
136
136
  setValue: y,
137
- touch: C,
137
+ touch: D,
138
138
  validateCurrentScope: L,
139
139
  validateAll: j,
140
140
  next: J,
@@ -270,7 +270,7 @@ const Ve = ["data-form-field-key"], we = ["for"], qe = {
270
270
  }, Pe = {
271
271
  key: 0,
272
272
  class: "dcs-form-field__help"
273
- }, Ce = {
273
+ }, De = {
274
274
  key: 0,
275
275
  class: "dcs-form-field__error",
276
276
  role: "alert"
@@ -301,11 +301,11 @@ const Ve = ["data-form-field-key"], we = ["for"], qe = {
301
301
  e.field.helpText ? (l(), f("p", Pe, b(e.field.helpText), 1)) : k("", !0)
302
302
  ]),
303
303
  S(t.$slots, "error", {}, () => [
304
- e.error ? (l(), f("p", Ce, b(e.error), 1)) : k("", !0)
304
+ e.error ? (l(), f("p", De, b(e.error), 1)) : k("", !0)
305
305
  ])
306
306
  ], 10, Ve));
307
307
  }
308
- }), De = ["id", "type", "name", "value", "placeholder", "required", "aria-invalid", "aria-describedby"], N = /* @__PURE__ */ I({
308
+ }), Ce = ["id", "type", "name", "value", "placeholder", "required", "aria-invalid", "aria-describedby"], N = /* @__PURE__ */ I({
309
309
  __name: "DcsFormText",
310
310
  props: {
311
311
  field: {},
@@ -348,7 +348,7 @@ const Ve = ["data-form-field-key"], we = ["for"], qe = {
348
348
  "aria-describedby": e.error ? `${o.value}-error` : void 0,
349
349
  onInput: c[0] || (c[0] = (a) => i("update:modelValue", a.target.value)),
350
350
  onBlur: c[1] || (c[1] = (a) => i("blur"))
351
- }, null, 40, De)
351
+ }, null, 40, Ce)
352
352
  ])
353
353
  ]),
354
354
  _: 3
@@ -772,7 +772,7 @@ const Ve = ["data-form-field-key"], we = ["for"], qe = {
772
772
  return N;
773
773
  }
774
774
  }
775
- const O = D(null);
775
+ const O = C(null);
776
776
  async function z(y) {
777
777
  if (y.preventDefault(), !s.value) return;
778
778
  if (!n.validateAll()) {
@@ -801,9 +801,9 @@ const Ve = ["data-form-field-key"], we = ["for"], qe = {
801
801
  }
802
802
  return ee(() => {
803
803
  s.value || console.warn(
804
- `[@duffcloudservices/site-forms] No form definition found for "${r.formId}". Expected a YAML at /.dcs/forms/${r.formId}.yaml.`
804
+ `[@duffcloudservices/site-forms] No form definition found for "${r.formId}". Expected a YAML at .dcs/forms/${r.formId}.yaml. In customer-site repos the YAML lives above the Vite root, so the internal auto-glob will not find it — pass formsModules explicitly: <DcsForm form-id="${r.formId}" :forms-modules="dcsFormsModules" />. See @duffcloudservices/site-forms README "Vite setup" section.`
805
805
  );
806
- }), (y, C) => s.value ? u(n).submitted.value ? (l(), f("div", {
806
+ }), (y, D) => s.value ? u(n).submitted.value ? (l(), f("div", {
807
807
  key: 1,
808
808
  class: "dcs-form dcs-form--success",
809
809
  "data-form-key": e.formId
@@ -863,13 +863,13 @@ const Ve = ["data-form-field-key"], we = ["for"], qe = {
863
863
  key: 0,
864
864
  type: "button",
865
865
  class: "dcs-form__btn dcs-form__btn--prev",
866
- onClick: C[0] || (C[0] = ($) => u(n).prev())
866
+ onClick: D[0] || (D[0] = ($) => u(n).prev())
867
867
  }, " Previous ")) : k("", !0),
868
868
  u(n).steps.value && !u(n).isLastStep.value ? (l(), f("button", {
869
869
  key: 1,
870
870
  type: "button",
871
871
  class: "dcs-form__btn dcs-form__btn--next",
872
- onClick: C[1] || (C[1] = ($) => u(n).next())
872
+ onClick: D[1] || (D[1] = ($) => u(n).next())
873
873
  }, " Next ")) : k("", !0),
874
874
  !u(n).steps.value || u(n).isLastStep.value ? (l(), f("button", {
875
875
  key: 2,