{
  "name": "Form",
  "category": "Forms",
  "subcategory": "Form Composition",
  "description": "EditForm wrapper with styled validation, field groups, and submit state.",
  "thumbnail": "/preview-cards/form.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/Form/DataAnnotationsFormValidator.cs",
    "UI/Form/Form.razor",
    "UI/Form/FormContext.cs",
    "UI/Form/FormDescription.razor",
    "UI/Form/FormField.razor",
    "UI/Form/FormItem.razor",
    "UI/Form/FormLabel.razor",
    "UI/Form/FormMessage.razor",
    "UI/Form/IFormValidator.cs"
  ],
  "dependencies": [
    "label"
  ],
  "packageDependencies": [],
  "cssVars": [
    "--color-destructive",
    "--color-muted",
    "--color-muted-foreground"
  ],
  "api": {
    "name": "Form",
    "category": "Forms",
    "subcategory": "Form Composition",
    "description": "EditForm wrapper with styled validation, field groups, and submit state.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/Form/DataAnnotationsFormValidator.cs",
      "UI/Form/Form.razor",
      "UI/Form/FormContext.cs",
      "UI/Form/FormDescription.razor",
      "UI/Form/FormField.razor",
      "UI/Form/FormItem.razor",
      "UI/Form/FormLabel.razor",
      "UI/Form/FormMessage.razor",
      "UI/Form/IFormValidator.cs"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "Model",
        "type": "TModel?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "ChildContent",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OnValidSubmit",
        "type": "EventCallback<TModel>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OnInvalidSubmit",
        "type": "EventCallback<TModel>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Validator",
        "type": "IFormValidator?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Class",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "AdditionalAttributes",
        "type": "Dictionary<string, object>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": true
      }
    ],
    "events": [
      {
        "name": "OnValidSubmit",
        "type": "EventCallback<TModel>",
        "description": null
      },
      {
        "name": "OnInvalidSubmit",
        "type": "EventCallback<TModel>",
        "description": null
      }
    ],
    "enums": [],
    "records": [],
    "cssVars": [
      "--color-destructive",
      "--color-muted",
      "--color-muted-foreground"
    ],
    "examples": [
      {
        "title": "Input with Validation",
        "code": "<FormField Name=\"email\" Label=\"Email\" Required=\"true\" Error=\"@_emailError\" HelpText=\"We will never share your email.\">\n    <Input Type=\"email\" Placeholder=\"you@example.com\" @bind-Value=\"_emailValue\" />\n</FormField>\n<Button OnClick=\"ValidateEmail\">Validate</Button>\n\n@code {\n    private string? _emailValue;\n    private string? _emailError;\n\n    private void ValidateEmail()\n    {\n        if (string.IsNullOrWhiteSpace(_emailValue) || !_emailValue.Contains('@'))\n            _emailError = \"Please enter a valid email address.\";\n        else\n            _emailError = null;\n    }\n}"
      },
      {
        "title": "Select with Validation",
        "code": "<FormField Name=\"role\" Label=\"Role\" Required=\"true\" Error=\"@_roleError\">\n    <Select @bind-Value=\"_roleValue\">\n        <SelectTrigger>\n            <Text As=\"span\" Class=\"@(_roleValue == null ? \\\"text-muted-foreground\\\" : \"\")\">\n                @(_roleValue ?? \"Select a role\")\n            </Text>\n        </SelectTrigger>\n        <SelectContent>\n            <SelectItem Value=\"admin\">Admin</SelectItem>\n            <SelectItem Value=\"editor\">Editor</SelectItem>\n            <SelectItem Value=\"viewer\">Viewer</SelectItem>\n        </SelectContent>\n    </Select>\n</FormField>\n<Button OnClick=\"ValidateRole\">Validate</Button>\n\n@code {\n    private string? _roleValue;\n    private string? _roleError;\n\n    private void ValidateRole()\n    {\n        if (string.IsNullOrEmpty(_roleValue))\n            _roleError = \"Please select a role.\";\n        else\n            _roleError = null;\n    }\n}"
      },
      {
        "title": "Checkbox and Switch with Validation",
        "code": "<FormField Name=\"terms\" Error=\"@_termsError\">\n    <Flex Gap=\"2\" Align=\"center\">\n        <Checkbox @bind-Checked=\"_termsChecked\" />\n        <Label>I accept the terms and conditions</Label>\n    </Flex>\n</FormField>\n<FormField Name=\"notifications\" Label=\"Email Notifications\" HelpText=\"Receive updates about your account.\">\n    <Switch @bind-Checked=\"_notifChecked\" />\n</FormField>\n<Button OnClick=\"ValidateTerms\">Submit</Button>\n\n@code {\n    private bool _termsChecked;\n    private bool _notifChecked = true;\n    private string? _termsError;\n\n    private void ValidateTerms()\n    {\n        _termsError = _termsChecked ? null : \"You must accept the terms to continue.\";\n    }\n}"
      },
      {
        "title": "Default",
        "code": "<FormField Name=\"username\">\n    <FormItem>\n        <FormLabel>Username</FormLabel>\n        <Input Placeholder=\"Enter your username\" />\n        <FormDescription>This is your public display name.</FormDescription>\n    </FormItem>\n</FormField>"
      }
    ],
    "subComponents": {
      "FormDescription": {
        "componentName": "FormDescription",
        "fileName": "FormDescription.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "FormField": {
        "componentName": "FormField",
        "fileName": "FormField.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Label",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "HelpText",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Error",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Required",
            "type": "bool",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Orientation",
            "type": "FormFieldOrientation",
            "default": "FormFieldOrientation.Vertical",
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "LabelWidth",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Name",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          },
          {
            "name": "ParentFormContext",
            "type": "FormContext?",
            "default": null,
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          }
        ],
        "events": [],
        "enums": [
          {
            "name": "FormFieldOrientation",
            "values": [
              "Vertical",
              "Horizontal"
            ],
            "description": null
          }
        ],
        "records": [
          {
            "name": "FormFieldContext",
            "signature": "FormFieldContext(string? Name, string? Error)",
            "description": null
          }
        ],
        "parseFailed": false,
        "parseError": null
      },
      "FormItem": {
        "componentName": "FormItem",
        "fileName": "FormItem.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "FormLabel": {
        "componentName": "FormLabel",
        "fileName": "FormLabel.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "FieldContext",
            "type": "FormField.FormFieldContext?",
            "default": null,
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "FormMessage": {
        "componentName": "FormMessage",
        "fileName": "FormMessage.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "FieldContext",
            "type": "FormField.FormFieldContext?",
            "default": null,
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      }
    },
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "form",
  "docsUrl": "https://lumeo.nativ.sh/components/form",
  "sourceUrl": [
    {
      "file": "UI/Form/DataAnnotationsFormValidator.cs",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/DataAnnotationsFormValidator.cs"
    },
    {
      "file": "UI/Form/Form.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/Form.razor"
    },
    {
      "file": "UI/Form/FormContext.cs",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/FormContext.cs"
    },
    {
      "file": "UI/Form/FormDescription.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/FormDescription.razor"
    },
    {
      "file": "UI/Form/FormField.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/FormField.razor"
    },
    {
      "file": "UI/Form/FormItem.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/FormItem.razor"
    },
    {
      "file": "UI/Form/FormLabel.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/FormLabel.razor"
    },
    {
      "file": "UI/Form/FormMessage.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/FormMessage.razor"
    },
    {
      "file": "UI/Form/IFormValidator.cs",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Form/IFormValidator.cs"
    }
  ],
  "source": [
    {
      "path": "UI/Form/DataAnnotationsFormValidator.cs",
      "content": "using System.ComponentModel.DataAnnotations;\n\nnamespace Lumeo;\n\npublic class DataAnnotationsFormValidator : IFormValidator\n{\n    public Dictionary<string, List<string>> Validate(object model)\n    {\n        var results = new List<ValidationResult>();\n        var context = new ValidationContext(model);\n        Validator.TryValidateObject(model, context, results, true);\n\n        var errors = new Dictionary<string, List<string>>();\n        foreach (var result in results)\n        {\n            foreach (var memberName in result.MemberNames)\n            {\n                if (!errors.ContainsKey(memberName))\n                    errors[memberName] = new List<string>();\n                if (result.ErrorMessage is not null)\n                    errors[memberName].Add(result.ErrorMessage);\n            }\n        }\n        return errors;\n    }\n\n    public List<string> ValidateField(object model, string fieldName)\n    {\n        var results = new List<ValidationResult>();\n        var context = new ValidationContext(model) { MemberName = fieldName };\n        var prop = model.GetType().GetProperty(fieldName);\n        if (prop is null) return new();\n        Validator.TryValidateProperty(prop.GetValue(model), context, results);\n        return results.Where(r => r.ErrorMessage is not null).Select(r => r.ErrorMessage!).ToList();\n    }\n}\n"
    },
    {
      "path": "UI/Form/Form.razor",
      "content": "@namespace Lumeo\n@typeparam TModel\n\n<CascadingValue Value=\"_context\" IsFixed=\"false\">\n    <form @onsubmit=\"HandleSubmit\" class=\"@($\"space-y-4 {Class}\".Trim())\" @attributes=\"AdditionalAttributes\">\n        @ChildContent\n    </form>\n</CascadingValue>\n\n@code {\n    [Parameter] public TModel? Model { get; set; }\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public EventCallback<TModel> OnValidSubmit { get; set; }\n    [Parameter] public EventCallback<TModel> OnInvalidSubmit { get; set; }\n    [Parameter] public IFormValidator? Validator { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private FormContext _context = new();\n\n    private async Task HandleSubmit()\n    {\n        if (Model is null) return;\n\n        _context.IsSubmitting = true;\n        StateHasChanged();\n\n        try\n        {\n            if (Validator is not null)\n            {\n                _context.Errors = Validator.Validate(Model);\n            }\n\n            if (_context.IsValid)\n            {\n                await OnValidSubmit.InvokeAsync(Model);\n            }\n            else\n            {\n                await OnInvalidSubmit.InvokeAsync(Model);\n            }\n        }\n        finally\n        {\n            _context.IsSubmitting = false;\n            StateHasChanged();\n        }\n    }\n\n    public void ValidateField(string fieldName)\n    {\n        if (Model is null || Validator is null) return;\n        var errors = Validator.ValidateField(Model, fieldName);\n        if (errors.Count > 0)\n            _context.Errors[fieldName] = errors;\n        else\n            _context.Errors.Remove(fieldName);\n        StateHasChanged();\n    }\n\n    public void Reset()\n    {\n        _context.Reset();\n        StateHasChanged();\n    }\n}\n"
    },
    {
      "path": "UI/Form/FormContext.cs",
      "content": "namespace Lumeo;\n\npublic class FormContext\n{\n    public Dictionary<string, List<string>> Errors { get; set; } = new();\n    public HashSet<string> DirtyFields { get; set; } = new();\n    public bool IsSubmitting { get; set; }\n    public bool IsValid => Errors.Count == 0 || Errors.All(e => e.Value.Count == 0);\n\n    public List<string> GetFieldErrors(string fieldName) =>\n        Errors.TryGetValue(fieldName, out var errors) ? errors : new();\n\n    public bool HasError(string fieldName) => GetFieldErrors(fieldName).Count > 0;\n    public bool IsDirty(string fieldName) => DirtyFields.Contains(fieldName);\n\n    public void MarkDirty(string fieldName) => DirtyFields.Add(fieldName);\n\n    public void ClearErrors() => Errors.Clear();\n    public void ClearFieldErrors(string fieldName) => Errors.Remove(fieldName);\n\n    public void Reset()\n    {\n        Errors.Clear();\n        DirtyFields.Clear();\n        IsSubmitting = false;\n    }\n}\n"
    },
    {
      "path": "UI/Form/FormDescription.razor",
      "content": "@namespace Lumeo\n\n<p class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</p>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"text-[0.8rem] text-muted-foreground {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/Form/FormField.razor",
      "content": "@namespace Lumeo\n\n@{\n    var context = new FormFieldContext(Name, EffectiveError);\n}\n\n<CascadingValue Value=\"context\" IsFixed=\"false\">\n    <div class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n        @if (Orientation == FormFieldOrientation.Vertical)\n        {\n            @if (Label is not null)\n            {\n                <Label>\n                    @Label\n                    @if (Required)\n                    {\n                        <span class=\"text-destructive ml-0.5\">*</span>\n                    }\n                </Label>\n            }\n            @ChildContent\n            @if (HelpText is not null && EffectiveError is null)\n            {\n                <p class=\"text-xs text-muted-foreground\">@HelpText</p>\n            }\n            @if (EffectiveError is not null)\n            {\n                <p class=\"text-xs text-destructive\">@EffectiveError</p>\n            }\n        }\n        else\n        {\n            <div class=\"grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-1\">\n                @if (Label is not null)\n                {\n                    <Label Class=\"@(string.Join(\" \", new[] { \"text-right\", LabelWidth is not null ? $\"w-[{LabelWidth}]\" : null }.Where(s => !string.IsNullOrWhiteSpace(s))))\">\n                        @Label\n                        @if (Required)\n                        {\n                            <span class=\"text-destructive ml-0.5\">*</span>\n                        }\n                    </Label>\n                }\n                <div>\n                    @ChildContent\n                    @if (HelpText is not null && EffectiveError is null)\n                    {\n                        <p class=\"text-xs text-muted-foreground mt-1\">@HelpText</p>\n                    }\n                    @if (EffectiveError is not null)\n                    {\n                        <p class=\"text-xs text-destructive mt-1\">@EffectiveError</p>\n                    }\n                </div>\n            </div>\n        }\n    </div>\n</CascadingValue>\n\n@code {\n    [Parameter] public string? Label { get; set; }\n    [Parameter] public string? HelpText { get; set; }\n    [Parameter] public string? Error { get; set; }\n    [Parameter] public bool Required { get; set; }\n    [Parameter] public FormFieldOrientation Orientation { get; set; } = FormFieldOrientation.Vertical;\n    [Parameter] public string? LabelWidth { get; set; }\n    [Parameter] public string? Name { get; set; }\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    // Bug D fix: receive the parent Form's context so Reset() clears cascade to child fields.\n    [CascadingParameter] private FormContext? ParentFormContext { get; set; }\n\n    // Use live errors from FormContext when available; fall back to the manually-set Error param.\n    private string? EffectiveError =>\n        ParentFormContext is { } pc && !string.IsNullOrEmpty(Name)\n            ? pc.GetFieldErrors(Name).FirstOrDefault() ?? Error\n            : Error;\n\n    private string CssClass => Orientation == FormFieldOrientation.Vertical\n        ? $\"space-y-2 {Class}\".Trim()\n        : $\"{Class}\".Trim();\n\n    public enum FormFieldOrientation\n    {\n        Vertical,\n        Horizontal\n    }\n\n    public record FormFieldContext(string? Name, string? Error)\n    {\n        public bool HasError => !string.IsNullOrEmpty(Error);\n    }\n}\n"
    },
    {
      "path": "UI/Form/FormItem.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"space-y-1 {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/Form/FormLabel.razor",
      "content": "@namespace Lumeo\n\n<label class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</label>\n\n@code {\n    [CascadingParameter] public FormField.FormFieldContext? FieldContext { get; set; }\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => string.Join(\" \", new[] { \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\", FieldContext?.HasError == true ? \"text-destructive\" : null, Class }.Where(s => !string.IsNullOrWhiteSpace(s)));\n}\n"
    },
    {
      "path": "UI/Form/FormMessage.razor",
      "content": "@namespace Lumeo\n\n@if (FieldContext?.HasError == true)\n{\n    <p class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n        @FieldContext.Error\n    </p>\n}\n\n@code {\n    [CascadingParameter] public FormField.FormFieldContext? FieldContext { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"text-[0.8rem] font-medium text-destructive {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/Form/IFormValidator.cs",
      "content": "namespace Lumeo;\n\npublic interface IFormValidator\n{\n    Dictionary<string, List<string>> Validate(object model);\n    List<string> ValidateField(object model, string fieldName);\n}\n"
    }
  ],
  "slots": [
    {
      "name": "ChildContent",
      "owner": "Form",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "FormDescription",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "FormField",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "FormItem",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "FormLabel",
      "type": "RenderFragment?",
      "description": null
    }
  ],
  "serviceDependencies": [],
  "cascadingDependencies": [
    {
      "name": "ParentFormContext",
      "type": "FormContext?",
      "required": false
    },
    {
      "name": "FieldContext",
      "type": "FormField.FormFieldContext?",
      "required": false
    }
  ],
  "relatedComponents": [
    {
      "name": "FormDescription",
      "reason": "sub-component"
    },
    {
      "name": "FormField",
      "reason": "sub-component"
    },
    {
      "name": "FormItem",
      "reason": "sub-component"
    },
    {
      "name": "FormLabel",
      "reason": "sub-component"
    },
    {
      "name": "FormMessage",
      "reason": "sub-component"
    },
    {
      "name": "Label",
      "reason": "used internally"
    }
  ],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Docs.Tests/Layout/NavMenuTests.cs",
    "tests/Lumeo.Docs.Tests/Services/NavConfigServiceTests.cs",
    "tests/Lumeo.Tests/Components/Form/FormTests.cs",
    "tests/Lumeo.Tests/Contract/ComponentContractTests.cs"
  ],
  "mdSummary": "# Form\n\nEditForm wrapper with styled validation, field groups, and submit state.\n\n**Package:** `Lumeo` · **Category:** Forms/Form Composition\n**Docs:** https://lumeo.nativ.sh/components/form\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Form | Model | `TModel?` | `` |  |\n| Form | ChildContent | `RenderFragment?` | `` |  |\n| Form | OnValidSubmit | `EventCallback<TModel>` | `` |  |\n| Form | OnInvalidSubmit | `EventCallback<TModel>` | `` |  |\n| Form | Validator | `IFormValidator?` | `` |  |\n| Form | Class | `string?` | `` |  |\n| Form | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| FormDescription | ChildContent | `RenderFragment?` | `` |  |\n| FormDescription | Class | `string?` | `` |  |\n| FormDescription | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| FormField | Label | `string?` | `` |  |\n| FormField | HelpText | `string?` | `` |  |\n| FormField | Error | `string?` | `` |  |\n| FormField | Required | `bool` | `` |  |\n| FormField | Orientation | `FormFieldOrientation` | `FormFieldOrientation.Vertical` |  |\n| FormField | LabelWidth | `string?` | `` |  |\n| FormField | Name | `string?` | `` |  |\n| FormField | ChildContent | `RenderFragment?` | `` |  |\n| FormField | Class | `string?` | `` |  |\n| FormField | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| FormField | ParentFormContext | `FormContext?` | `` |  |\n| FormItem | ChildContent | `RenderFragment?` | `` |  |\n| FormItem | Class | `string?` | `` |  |\n| FormItem | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| FormLabel | FieldContext | `FormField.FormFieldContext?` | `` |  |\n| FormLabel | ChildContent | `RenderFragment?` | `` |  |\n| FormLabel | Class | `string?` | `` |  |\n| FormLabel | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| FormMessage | FieldContext | `FormField.FormFieldContext?` | `` |  |\n| FormMessage | Class | `string?` | `` |  |\n| FormMessage | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `ChildContent` (Form) — RenderFragment slot\n- `ChildContent` (FormDescription) — RenderFragment slot\n- `ChildContent` (FormField) — RenderFragment slot\n- `ChildContent` (FormItem) — RenderFragment slot\n- `ChildContent` (FormLabel) — RenderFragment slot\n\n## Events\n- `OnValidSubmit` (`EventCallback<TModel>`)\n- `OnInvalidSubmit` (`EventCallback<TModel>`)\n\n## Sub-components\n- `FormDescription`, `FormField`, `FormItem`, `FormLabel`, `FormMessage`\n\n## Cascading values it expects\n- `ParentFormContext` (`FormContext?`)\n- `FieldContext` (`FormField.FormFieldContext?`)\n\n## Services it injects\n- (none)\n\n## Keyboard\n—\n\n## Example\n```razor\n<Form />\n```\n\n## CSS variables\n`--color-destructive`, `--color-muted`, `--color-muted-foreground`\n\n## Files\n- `UI/Form/DataAnnotationsFormValidator.cs`\n- `UI/Form/Form.razor`\n- `UI/Form/FormContext.cs`\n- `UI/Form/FormDescription.razor`\n- `UI/Form/FormField.razor`\n- `UI/Form/FormItem.razor`\n- `UI/Form/FormLabel.razor`\n- `UI/Form/FormMessage.razor`\n- `UI/Form/IFormValidator.cs`\n"
}