{
  "name": "Checkbox",
  "category": "Forms",
  "subcategory": "Specialized",
  "description": "Binary input with indeterminate state and accessible label.",
  "thumbnail": "/preview-cards/checkbox.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/Checkbox/Checkbox.razor"
  ],
  "dependencies": [],
  "packageDependencies": [],
  "cssVars": [
    "--color-background",
    "--color-destructive",
    "--color-muted",
    "--color-muted-foreground",
    "--color-primary",
    "--color-primary-foreground",
    "--color-ring",
    "--radius"
  ],
  "api": {
    "name": "Checkbox",
    "category": "Forms",
    "subcategory": "Specialized",
    "description": "Binary input with indeterminate state and accessible label.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/Checkbox/Checkbox.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "FormField",
        "type": "FormField.FormFieldContext?",
        "default": null,
        "description": null,
        "isCascading": true,
        "captureUnmatched": false
      },
      {
        "name": "Checked",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "CheckedChanged",
        "type": "EventCallback<bool>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsIndeterminate",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsIndeterminateChanged",
        "type": "EventCallback<bool>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Disabled",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Label",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Description",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Id",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "AriaLabel",
        "type": "string?",
        "default": null,
        "description": "Accessible name used when Label is not set (the checkbox renders without a visible label). Required for WCAG compliance when the checkbox sits alone in a cell or alongside text that isn't linked to it via for / htmlFor.",
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Animated",
        "type": "bool",
        "default": null,
        "description": "When true, the checkmark draws itself in via stroke-dasharray and the box plays a subtle 200ms scale bounce on check. Default is false.",
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "HapticFeedback",
        "type": "bool",
        "default": null,
        "description": "When true, triggers a short haptic vibration via navigator.vibrate() each time the checkbox state changes. Silently no-ops on browsers without the Vibration API (e.g. iOS Safari). Default is false.",
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Required",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Invalid",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "ErrorText",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "HelperText",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Name",
        "type": "string?",
        "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": "CheckedChanged",
        "type": "EventCallback<bool>",
        "description": null
      },
      {
        "name": "IsIndeterminateChanged",
        "type": "EventCallback<bool>",
        "description": null
      }
    ],
    "enums": [],
    "records": [],
    "cssVars": [
      "--color-background",
      "--color-destructive",
      "--color-muted",
      "--color-muted-foreground",
      "--color-primary",
      "--color-primary-foreground",
      "--color-ring",
      "--radius"
    ],
    "examples": [
      {
        "title": "Default",
        "code": "<Flex Gap=\"2\" Align=\"center\">\n    <Checkbox @bind-Checked=\"_checked\" />\n    <Label>Accept terms and conditions</Label>\n</Flex>"
      },
      {
        "title": "With Binding",
        "code": "<Flex Gap=\"2\" Align=\"center\">\n    <Checkbox @bind-Checked=\"_checked\" />\n    <Label>Enable notifications</Label>\n</Flex>\n<Lumeo.Text Size=\"sm\" Color=\"muted\">Checked: @_checked</Lumeo.Text>\n\n@code {\n    private bool _checked = true;\n}"
      },
      {
        "title": "Disabled",
        "code": "<Checkbox Checked=\"false\" Disabled=\"true\" />\n<Checkbox Checked=\"true\" Disabled=\"true\" />"
      },
      {
        "title": "Multiple Options",
        "code": "<Checkbox @bind-Checked=\"_optionA\" />\n<Checkbox @bind-Checked=\"_optionB\" />\n<Checkbox @bind-Checked=\"_optionC\" />"
      }
    ],
    "subComponents": {},
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "checkbox",
  "docsUrl": "https://lumeo.nativ.sh/components/checkbox",
  "sourceUrl": [
    {
      "file": "UI/Checkbox/Checkbox.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Checkbox/Checkbox.razor"
    }
  ],
  "source": [
    {
      "path": "UI/Checkbox/Checkbox.razor",
      "content": "@namespace Lumeo\n\n@* Inline SVGs sized to the checkbox's 12-unit viewBox. Stroke-width ~2.75 gives a crisper check\n   than Lucide's default 2 at this size, and `stroke-linecap/join=\"round\"` kills the pixel-corner\n   sharpness the user was seeing. *@\n\n@if (Label is not null)\n{\n    <div class=\"flex items-start gap-2.5\">\n        <button type=\"button\" id=\"@_id\" role=\"checkbox\" aria-checked=\"@AriaChecked\"\n                aria-required=\"@Required.ToString().ToLowerInvariant()\"\n                aria-invalid=\"@EffectiveInvalid.ToString().ToLowerInvariant()\"\n                class=\"@CssClass\" @onclick=\"Toggle\" disabled=\"@Disabled\" @attributes=\"AdditionalAttributes\">\n            @RenderIcon()\n        </button>\n        <div class=\"grid gap-1 leading-none pt-[1px]\">\n            <label for=\"@_id\" class=\"text-sm font-medium leading-none cursor-pointer peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n                @Label\n                @if (Required)\n                {\n                    <span class=\"text-destructive ml-0.5\">*</span>\n                }\n            </label>\n            @if (!string.IsNullOrEmpty(Description))\n            {\n                <p class=\"text-xs text-muted-foreground\">@Description</p>\n            }\n        </div>\n    </div>\n}\nelse\n{\n    <button type=\"button\" id=\"@_id\" role=\"checkbox\" aria-checked=\"@AriaChecked\" aria-label=\"@AriaLabel\"\n            aria-required=\"@Required.ToString().ToLowerInvariant()\"\n            aria-invalid=\"@EffectiveInvalid.ToString().ToLowerInvariant()\"\n            class=\"@CssClass\" @onclick=\"Toggle\" disabled=\"@Disabled\" @attributes=\"AdditionalAttributes\">\n        @RenderIcon()\n    </button>\n}\n\n@if (!InsideFormField)\n{\n    @if (EffectiveInvalid && !string.IsNullOrEmpty(ErrorText))\n    {\n        <p class=\"mt-1 text-xs text-destructive\">@ErrorText</p>\n    }\n    else if (!string.IsNullOrEmpty(HelperText))\n    {\n        <p class=\"mt-1 text-xs text-muted-foreground\">@HelperText</p>\n    }\n}\n\n@code {\n    private RenderFragment RenderIcon() => __builder =>\n    {\n        if (IsIndeterminate)\n        {\n            <svg class=\"pointer-events-none h-2.5 w-2.5\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.75\" stroke-linecap=\"round\">\n                <line x1=\"3\" y1=\"6\" x2=\"9\" y2=\"6\" />\n            </svg>\n        }\n        else if (Checked)\n        {\n            <svg class=\"pointer-events-none h-2.5 w-2.5\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <polyline points=\"2.5,6.5 5,8.5 9.5,3.5\" />\n            </svg>\n        }\n    };\n}\n\n@code {\n    [CascadingParameter] private FormField.FormFieldContext? FormField { get; set; }\n\n    [Parameter] public bool Checked { get; set; }\n    [Parameter] public EventCallback<bool> CheckedChanged { get; set; }\n    [Parameter] public bool IsIndeterminate { get; set; }\n    [Parameter] public EventCallback<bool> IsIndeterminateChanged { get; set; }\n    [Parameter] public bool Disabled { get; set; }\n    [Parameter] public string? Label { get; set; }\n    [Parameter] public string? Description { get; set; }\n    [Parameter] public string? Id { get; set; }\n    /// <summary>\n    /// Accessible name used when <see cref=\"Label\"/> is not set (the checkbox\n    /// renders without a visible label). Required for WCAG compliance when\n    /// the checkbox sits alone in a cell or alongside text that isn't linked\n    /// to it via <c>for</c> / <c>htmlFor</c>.\n    /// </summary>\n    [Parameter] public string? AriaLabel { get; set; }\n\n    /// <summary>\n    /// When true, the checkmark draws itself in via stroke-dasharray and the\n    /// box plays a subtle 200ms scale bounce on check. Default is <c>false</c>.\n    /// </summary>\n    [Parameter] public bool Animated { get; set; }\n\n    /// <summary>\n    /// When true, triggers a short haptic vibration via <c>navigator.vibrate()</c>\n    /// each time the checkbox state changes. Silently no-ops on browsers without the\n    /// Vibration API (e.g. iOS Safari). Default is <c>false</c>.\n    /// </summary>\n    [Parameter] public bool HapticFeedback { get; set; }\n\n    [Inject] private HapticsService Haptics { get; set; } = default!;\n\n    [Parameter] public bool Required { get; set; }\n    [Parameter] public bool Invalid { get; set; }\n    [Parameter] public string? ErrorText { get; set; }\n    [Parameter] public string? HelperText { get; set; }\n    [Parameter] public string? Name { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private bool EffectiveInvalid => Invalid || FormField?.HasError == true;\n    private bool InsideFormField => FormField is not null;\n\n    private string _id = default!;\n\n    protected override void OnInitialized()\n    {\n        _id = Id ?? $\"checkbox-{Guid.NewGuid():N}\";\n    }\n\n    private string AriaChecked => IsIndeterminate ? \"mixed\" : Checked.ToString().ToLower();\n\n    private string CssClass => string.Join(\" \", new[]\n    {\n        \"peer inline-flex items-center justify-center h-4 w-4 shrink-0 cursor-pointer rounded transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n        EffectiveInvalid\n            ? (Checked || IsIndeterminate ? \"bg-destructive border border-destructive text-primary-foreground focus-visible:ring-destructive/50\" : \"border border-destructive focus-visible:ring-destructive/50\")\n            : (Checked || IsIndeterminate ? \"bg-primary border border-primary text-primary-foreground focus-visible:ring-ring\" : \"border border-primary/60 bg-background hover:border-primary focus-visible:ring-ring\"),\n        Animated && Checked ? \"lumeo-checkbox-animated\" : null,\n        Class\n    }.Where(s => !string.IsNullOrWhiteSpace(s)));\n\n    private async Task Toggle()\n    {\n        if (!Disabled)\n        {\n            if (IsIndeterminate)\n            {\n                IsIndeterminate = false;\n                await IsIndeterminateChanged.InvokeAsync(false);\n                Checked = true;\n                await CheckedChanged.InvokeAsync(true);\n            }\n            else\n            {\n                Checked = !Checked;\n                await CheckedChanged.InvokeAsync(Checked);\n            }\n            if (HapticFeedback) await Haptics.Light();\n        }\n    }\n}\n"
    }
  ],
  "slots": [],
  "serviceDependencies": [],
  "cascadingDependencies": [
    {
      "name": "FormField",
      "type": "FormField.FormFieldContext?",
      "required": false
    }
  ],
  "relatedComponents": [],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests/Components/Checkbox/CheckboxAnimatedTests.cs",
    "tests/Lumeo.Tests/Components/Checkbox/CheckboxHapticFeedbackTests.cs",
    "tests/Lumeo.Tests/Components/Checkbox/CheckboxTests.cs",
    "tests/Lumeo.Tests/Components/DataGrid/DataGridTests.cs",
    "tests/Lumeo.Tests/Components/Switch/SwitchCursorTests.cs"
  ],
  "mdSummary": "# Checkbox\n\nBinary input with indeterminate state and accessible label.\n\n**Package:** `Lumeo` · **Category:** Forms/Specialized\n**Docs:** https://lumeo.nativ.sh/components/checkbox\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Checkbox | FormField | `FormField.FormFieldContext?` | `` |  |\n| Checkbox | Checked | `bool` | `` |  |\n| Checkbox | CheckedChanged | `EventCallback<bool>` | `` |  |\n| Checkbox | IsIndeterminate | `bool` | `` |  |\n| Checkbox | IsIndeterminateChanged | `EventCallback<bool>` | `` |  |\n| Checkbox | Disabled | `bool` | `` |  |\n| Checkbox | Label | `string?` | `` |  |\n| Checkbox | Description | `string?` | `` |  |\n| Checkbox | Id | `string?` | `` |  |\n| Checkbox | AriaLabel | `string?` | `` | Accessible name used when Label is not set (the checkbox renders without a visible label). Required for WCAG compliance when the checkbox sits alone in a cell or alongside text that isn't linked to it via for / htmlFor. |\n| Checkbox | Animated | `bool` | `` | When true, the checkmark draws itself in via stroke-dasharray and the box plays a subtle 200ms scale bounce on check. Default is false. |\n| Checkbox | HapticFeedback | `bool` | `` | When true, triggers a short haptic vibration via navigator.vibrate() each time the checkbox state changes. Silently no-ops on browsers without the Vibration API (e.g. iOS Safari). Default is false. |\n| Checkbox | Required | `bool` | `` |  |\n| Checkbox | Invalid | `bool` | `` |  |\n| Checkbox | ErrorText | `string?` | `` |  |\n| Checkbox | HelperText | `string?` | `` |  |\n| Checkbox | Name | `string?` | `` |  |\n| Checkbox | Class | `string?` | `` |  |\n| Checkbox | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- (none)\n\n## Events\n- `CheckedChanged` (`EventCallback<bool>`)\n- `IsIndeterminateChanged` (`EventCallback<bool>`)\n\n## Sub-components\n- (none)\n\n## Cascading values it expects\n- `FormField` (`FormField.FormFieldContext?`)\n\n## Services it injects\n- (none)\n\n## Keyboard\n—\n\n## Example\n```razor\n<Checkbox />\n```\n\n## CSS variables\n`--color-background`, `--color-destructive`, `--color-muted`, `--color-muted-foreground`, `--color-primary`, `--color-primary-foreground`, `--color-ring`, `--radius`\n\n## Files\n- `UI/Checkbox/Checkbox.razor`\n"
}