{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"fieldset","title":"Fieldset","description":"Base UI fieldset and legend primitives for semantic control groups, with a description the fieldset names in aria-describedby.","dependencies":["@base-ui/react@1.7.0"],"registryDependencies":["@siteplane/base"],"files":[{"path":"packages/ui/src/components/fieldset/fieldset.tsx","content":"\"use client\";\n\nimport { Fieldset as FieldsetPrimitive } from \"@base-ui/react/fieldset\";\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport * as React from \"react\";\n\nimport { cn, type WithStringClassName } from \"../../system/utils/cn\";\nimport { slotClass } from \"../../system/utils/slot-class\";\n\n/** Registers a description's id with the Fieldset it describes. */\ntype FieldsetDescriptionRegistry = (id: string) => () => void;\n\nconst FieldsetDescriptionContext =\n  React.createContext<FieldsetDescriptionRegistry | null>(null);\n\n/**\n * A group of related fields. Its FieldsetDescription parts describe it: their\n * ids join the fieldset's `aria-describedby`, after one the application gives.\n * Its rows stay packed at the top: a Fieldset that a grid or flex row\n * stretches to a taller neighbour's height leaves the extra height below its\n * last row instead of opening gaps between its legend, description and\n * fields (`content-start`).\n */\nexport function Fieldset({\n  \"aria-describedby\": describedBy,\n  className,\n  ...props\n}: WithStringClassName<FieldsetPrimitive.Root.Props>): React.ReactElement {\n  const [descriptionIds, setDescriptionIds] = React.useState<readonly string[]>(\n    [],\n  );\n  const register = React.useCallback<FieldsetDescriptionRegistry>((id) => {\n    setDescriptionIds((ids) => [...ids, id]);\n    return () =>\n      setDescriptionIds((ids) => ids.filter((entry) => entry !== id));\n  }, []);\n  const ariaDescribedBy =\n    [describedBy, ...descriptionIds].filter(Boolean).join(\" \") || undefined;\n\n  return (\n    <FieldsetDescriptionContext.Provider value={register}>\n      <FieldsetPrimitive.Root\n        aria-describedby={ariaDescribedBy}\n        className={cn(\n          slotClass(\"fieldset\", props),\n          \"grid content-start gap-3\",\n          className,\n        )}\n        data-slot=\"fieldset\"\n        {...props}\n      />\n    </FieldsetDescriptionContext.Provider>\n  );\n}\n\nexport function FieldsetLegend({\n  className,\n  ...props\n}: WithStringClassName<FieldsetPrimitive.Legend.Props>): React.ReactElement {\n  return (\n    <FieldsetPrimitive.Legend\n      className={cn(\n        slotClass(\"fieldset-legend\", props),\n        \"font-(--sp-rw-font-weight-strong) text-foreground\",\n        className,\n      )}\n      data-slot=\"fieldset-legend\"\n      {...props}\n    />\n  );\n}\n\nexport type FieldsetDescriptionProps = useRender.ComponentProps<\"p\">;\n\n/**\n * Text that explains the group, for the hint a group of fields shares. It\n * reads like the descriptions of other groups, such as a Card's, and the\n * Fieldset names it in its `aria-describedby`, so a screen reader reads it\n * when focus enters the group. Renders a `<p>`.\n */\nexport function FieldsetDescription({\n  className,\n  id,\n  render,\n  ...props\n}: FieldsetDescriptionProps): React.ReactElement {\n  const generatedId = React.useId();\n  const descriptionId = id ?? generatedId;\n  const register = React.useContext(FieldsetDescriptionContext);\n  React.useLayoutEffect(\n    () => register?.(descriptionId),\n    [descriptionId, register],\n  );\n  const defaultProps = {\n    className: cn(\n      slotClass(\"fieldset-description\", props, render),\n      \"wrap-anywhere\",\n      className,\n    ),\n    \"data-slot\": \"fieldset-description\",\n    id: descriptionId,\n  };\n\n  return useRender({\n    defaultTagName: \"p\",\n    props: mergeProps<\"p\">(defaultProps, props),\n    render,\n  });\n}\n\nexport { FieldsetPrimitive };\n","type":"registry:ui","target":"~/src/siteplane/components/fieldset/fieldset.tsx"},{"path":"packages/ui/src/components/fieldset/index.ts","content":"export * from \"./fieldset\";\n","type":"registry:ui","target":"~/src/siteplane/components/fieldset/index.ts"}],"type":"registry:ui","docs":"https://ui.siteplane.io/docs-markdown/components/fieldset.md","categories":["Forms & selection"],"meta":{"avoidWhen":["Avoid for visual grouping only; use Card or Frame.","Avoid expecting it to submit, validate or save: compose it within Form."],"description":"Base UI fieldset and legend primitives for semantic control groups, with a description the fieldset names in aria-describedby.","knownLimitations":[],"providerNotes":[],"releaseStatus":"stable","searchTerms":["fieldset"],"useWhen":["Use to group related fields under a shared legend, such as an address or a set of notification options."]}}