{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"c-signature-pad-10","type":"registry:block","title":"Initials per clause","description":"Compact initial pads for each contract clause with a completion count.","dependencies":[],"registryDependencies":["@reui/badge","button","item","@reui/signature-pad"],"files":[{"path":"c-signature-pad-10.tsx","type":"registry:block","content":"\"use client\"\n\nimport { useState } from \"react\"\nimport { Badge } from \"@/components/reui/badge\"\nimport {\n  SignaturePad,\n  SignaturePadArea,\n  SignaturePadClear,\n  SignaturePadControls,\n  SignaturePadPlaceholder,\n} from \"@/components/reui/signature-pad\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Item,\n  ItemActions,\n  ItemContent,\n  ItemDescription,\n  ItemGroup,\n  ItemMedia,\n  ItemTitle,\n} from \"@/components/ui/item\"\nimport { IconPlaceholder } from \"@/app/(create)/components/icon-placeholder\"\n\nconst CLAUSES = [\n  {\n    id: \"scope\",\n    number: 2,\n    title: \"Scope of work\",\n    description: \"Design and build of the marketing site, 6 templates.\",\n  },\n  {\n    id: \"payment\",\n    number: 3,\n    title: \"Payment terms\",\n    description: \"Invoiced monthly in arrears, due within 30 days.\",\n  },\n  {\n    id: \"ownership\",\n    number: 4,\n    title: \"Ownership\",\n    description: \"Source files transfer to the client on final payment.\",\n  },\n  {\n    id: \"termination\",\n    number: 5,\n    title: \"Termination\",\n    description: \"Either party, with 30 days written notice.\",\n  },\n]\n\nexport function Pattern() {\n  const [initialed, setInitialed] = useState<Record<string, boolean>>({})\n  const [submitted, setSubmitted] = useState(false)\n  const count = CLAUSES.filter((clause) => initialed[clause.id]).length\n  const complete = count === CLAUSES.length\n\n  return (\n    <div className=\"mx-auto flex w-full max-w-lg flex-col gap-3\">\n      <div className=\"flex items-start justify-between gap-4\">\n        <div className=\"flex flex-col gap-0.5\">\n          <p className=\"text-sm font-medium\">Initial each clause</p>\n          <p className=\"text-muted-foreground text-xs\">\n            Your initials confirm you have read the section.\n          </p>\n        </div>\n        <Badge variant={complete ? \"success-light\" : \"secondary\"}>\n          {count} of {CLAUSES.length} initialed\n        </Badge>\n      </div>\n      <ItemGroup>\n        {CLAUSES.map((clause) => {\n          const done = initialed[clause.id] === true\n          return (\n            <Item key={clause.id} variant=\"outline\" size=\"sm\">\n              <ItemMedia variant=\"icon\" aria-hidden=\"true\">\n                {done ? (\n                  <IconPlaceholder\n                    lucide=\"CircleCheckIcon\"\n                    tabler=\"IconCircleCheck\"\n                    hugeicons=\"CheckmarkCircle02Icon\"\n                    phosphor=\"CheckCircleIcon\"\n                    remixicon=\"RiCheckboxCircleLine\"\n                    className=\"text-success\"\n                  />\n                ) : (\n                  <IconPlaceholder\n                    lucide=\"CircleDashedIcon\"\n                    tabler=\"IconCircleDashed\"\n                    hugeicons=\"CircleDashedIcon\"\n                    phosphor=\"CircleDashedIcon\"\n                    remixicon=\"RiProgress1Line\"\n                    className=\"text-muted-foreground\"\n                  />\n                )}\n              </ItemMedia>\n              <ItemContent>\n                <ItemTitle>\n                  {clause.number}. {clause.title}\n                  {done && <span className=\"sr-only\">, initialed</span>}\n                </ItemTitle>\n                <ItemDescription>{clause.description}</ItemDescription>\n              </ItemContent>\n              <ItemActions>\n                {/* Initials are small, so the line range is narrower too. */}\n                <SignaturePad\n                  minWidth={0.6}\n                  maxWidth={2.4}\n                  readOnly={submitted}\n                  className=\"w-28\"\n                  onValueChange={(strokes) =>\n                    setInitialed((current) => ({\n                      ...current,\n                      [clause.id]: strokes.length > 0,\n                    }))\n                  }\n                >\n                  <SignaturePadArea\n                    variant=\"muted\"\n                    aria-label={`Initials for ${clause.title}`}\n                    className=\"h-14\"\n                  >\n                    <SignaturePadPlaceholder>Initials</SignaturePadPlaceholder>\n                    {done && !submitted && (\n                      <SignaturePadControls className=\"end-1 top-1\">\n                        <SignaturePadClear variant=\"ghost\" size=\"icon-xs\" />\n                      </SignaturePadControls>\n                    )}\n                  </SignaturePadArea>\n                </SignaturePad>\n              </ItemActions>\n            </Item>\n          )\n        })}\n      </ItemGroup>\n      {submitted ? (\n        <p\n          ref={(node) => node?.focus()}\n          tabIndex={-1}\n          role=\"status\"\n          className=\"self-end text-sm font-medium outline-none\"\n        >\n          Initials submitted\n        </p>\n      ) : (\n        <Button\n          disabled={!complete}\n          onClick={() => setSubmitted(true)}\n          className=\"self-end\"\n        >\n          Submit initials\n        </Button>\n      )}\n    </div>\n  )\n}","target":"components/examples/c-signature-pad-10.tsx"}],"meta":{"order":10,"label":"Clause Initials"}}