var v=Object.defineProperty;var N=(o)=>o;function F(o,r){this[o]=N.bind(null,r)}var L=(o,r)=>{for(var i in r)v(o,i,{get:r[i],enumerable:!0,configurable:!0,set:F.bind(r,i)})};var R=(o,r)=>()=>(o&&(r=o(o=0)),r);import S from"@contractspec/lib.ui-link";import{jsx as c,jsxs as z}from"react/jsx-runtime";function s({title:o="Need the operating layer on top of OSS ContractSpec?",body:r="ContractSpec Studio helps teams turn evidence into proposed spec changes, governed delivery loops, and execution-ready task packs while keeping the open contract system as the source of truth.",ctaLabel:i="See what Studio adds",href:h="https://www.contractspec.studio/docs"}){return z("div",{className:"card-subtle space-y-3 p-6",children:[c("h3",{className:"font-semibold text-lg",children:o}),c("p",{className:"text-muted-foreground text-sm",children:r}),c(S,{href:h,className:"btn-primary",children:i})]})}var f=`import {
  defineFormSpec,
  FormRegistry,
  responsiveFormColumns,
} from "@contractspec/lib.contracts-spec/forms";
import { fromZod } from "@contractspec/lib.schema";
import { z } from "zod";

const LeadCaptureModel = fromZod(
  z.object({
    fullName: z.string().min(1),
    email: z.string().email(),
    company: z.string().min(1),
    intent: z.enum(["demo", "pricing", "pilot"]),
    notes: z.string().max(1000).optional(),
    newsletter: z.boolean().optional(),
  }),
  { name: "LeadCaptureModel" },
);

export const LeadCaptureForm = defineFormSpec({
  meta: {
    key: "marketing.lead.form",
    version: "1.0.0",
    title: "Lead capture form",
    description: "Collect qualified OSS and Studio leads.",
    domain: "marketing",
    owners: ["@growth"],
    tags: ["forms", "leads"],
    stability: "experimental",
  },
  model: LeadCaptureModel,
  layout: {
    columns: responsiveFormColumns(2),
    gap: "md",
    flow: {
      kind: "sections",
      sections: [
        { key: "identity", titleI18n: "Who you are", fieldNames: ["fullName", "email", "company"] },
        { key: "request", titleI18n: "What you need", fieldNames: ["intent", "notes", "newsletter"] },
      ],
    },
  },
  fields: [
    { kind: "text", name: "fullName", labelI18n: "Full name", required: true, autoComplete: "name" },
    { kind: "email", name: "email", labelI18n: "Work email", required: true, autoComplete: "email" },
    { kind: "text", name: "company", labelI18n: "Company", required: true, autoComplete: "organization" },
    {
      kind: "select",
      name: "intent",
      labelI18n: "Primary goal",
      required: true,
      options: [
        { labelI18n: "Book a demo", value: "demo" },
        { labelI18n: "Understand pricing", value: "pricing" },
        { labelI18n: "Plan a pilot", value: "pilot" },
      ],
    },
    { kind: "textarea", name: "notes", labelI18n: "Context", rows: 4, layout: { colSpan: "full" } },
    { kind: "checkbox", name: "newsletter", labelI18n: "Send product updates" },
  ],
  actions: [{ key: "submit", labelI18n: "Send request", op: { name: "lead.create", version: "1.0.0" } }],
  policy: { flags: ["lead-capture"], pii: ["fullName", "email", "company", "notes"] },
  renderHints: { ui: "shadcn", form: "react-hook-form" },
});

export const formRegistry = new FormRegistry().register(LeadCaptureForm);`,y=`"use client";

import { formRenderer } from "@contractspec/lib.design-system/renderers/form-contract";
import { LeadCaptureForm } from "../contracts/forms/lead-capture.form";

export function LeadCapturePanel() {
  return formRenderer.render(LeadCaptureForm, {
    defaultValues: { newsletter: true },
    overrides: {
      onSubmitOverride: async (values, actionKey) => {
        await fetch("/api/leads", {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({ actionKey, values }),
        });
      },
    },
  });
}`,g=`bun add @contractspec/example.form-showcase

# Full form-only example docs
open https://www.contractspec.io/docs/examples/form-showcase

# Template catalog filtered to forms
open https://www.contractspec.io/templates?tag=forms

# Sandbox spec preview
open https://www.contractspec.io/sandbox?template=form-showcase`;import{CodeBlock as l}from"@contractspec/lib.design-system";import{HStack as C,VStack as a}from"@contractspec/lib.design-system/layout";import{List as I,ListItem as u}from"@contractspec/lib.design-system/list";import{Code as b,H1 as q,H2 as p,H3 as w,P as n,Text as m}from"@contractspec/lib.design-system/typography";import d from"@contractspec/lib.ui-link";import{ChevronRight as O}from"lucide-react";import{jsx as e,jsxs as t}from"react/jsx-runtime";function _(){return t(a,{className:"space-y-8",children:[t(a,{className:"space-y-3",children:[e(q,{className:"font-bold text-4xl",children:"Build a contract-driven form"}),e(n,{className:"text-lg text-muted-foreground",children:"Define form data, fields, layout, policy, and submit behavior once, then let your app render from the same ContractSpec surface."})]}),t(a,{className:"card-subtle space-y-4 p-6",children:[e(p,{className:"font-bold text-2xl",children:"What you'll build"}),t(I,{className:"space-y-2 text-muted-foreground text-sm",children:[e(u,{children:e(m,{children:"A schema-backed FormSpec for a lead capture form."})}),e(u,{children:e(m,{children:"A FormRegistry that exposes the latest version by stable key."})}),e(u,{children:e(m,{children:"A React renderer that keeps UI, validation, and policy aligned."})})]})]}),t(a,{className:"space-y-6",children:[t(a,{className:"space-y-3",children:[e(p,{className:"font-bold text-2xl",children:"1) Define the form spec"}),t(n,{className:"text-muted-foreground text-sm",children:["Create ",e(b,{children:"src/contracts/forms/lead-capture.form.ts"}),":"]}),e(l,{language:"typescript",filename:"src/contracts/forms/lead-capture.form.ts",code:f})]}),t(a,{className:"card-subtle space-y-3 p-6",children:[e(w,{className:"font-semibold text-lg",children:"Need every form field?"}),t(n,{className:"text-muted-foreground text-sm",children:["Start from the"," ",e(d,{href:"/docs/examples/form-showcase",children:"Form Showcase example"})," ","or the"," ",e(d,{href:"/templates?tag=forms",children:"form template catalog"}),". It is focused only on forms and covers field kinds, section layouts, step layouts, arrays, groups, conditionals, and validation hints."]}),e(l,{language:"bash",filename:"form-showcase-template",code:g})]}),t(a,{className:"space-y-3",children:[e(p,{className:"font-bold text-2xl",children:"2) Render from the contract"}),e(n,{className:"text-muted-foreground text-sm",children:"Use the shared renderer, or provide your own driver if your app uses a different component library."}),e(l,{language:"tsx",filename:"src/components/LeadCapturePanel.tsx",code:y})]}),t(a,{className:"space-y-3",children:[e(p,{className:"font-bold text-2xl",children:"3) Validate and evolve"}),e(l,{language:"bash",filename:"validate-form",code:"contractspec validate src/contracts/forms/lead-capture.form.ts"}),t(n,{className:"text-muted-foreground text-sm",children:["Expected output: ",e(b,{children:"Validation passed"}),". When the form becomes public contract surface, version changes deliberately instead of editing field meaning in place."]})]}),t(a,{className:"card-subtle space-y-3 p-6",children:[e(w,{className:"font-semibold text-lg",children:"Repo tutorial"}),e(n,{className:"text-muted-foreground text-sm",children:"The repository guide adds the longer implementation checklist, custom renderer notes, and rollout rules."}),e(l,{language:"bash",filename:"repo-guide",code:"open docs/tutorials/contract-driven-forms.md"})]}),e(s,{title:"Need governed form changes?",body:"Studio can connect form edits to customer evidence, approval packets, and rollout checks before teams regenerate public surfaces."})]}),t(C,{className:"flex items-center gap-4 pt-4",children:[t(d,{href:"/docs/guides/generate-docs-clients-schemas",className:"btn-primary",children:[e(m,{children:"Next: Generate docs + clients"}),e(O,{size:16})]}),e(d,{href:"/docs/guides",className:"btn-ghost",children:e(m,{children:"Back to guides"})})]})]})}export{_ as GuideContractDrivenFormsPage};
