{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"settings-list","title":"Settings List","description":"Sectioned settings surface with passive items and consumer-provided controls, tags and supporting content. Search terms: preferences, rows.","dependencies":[],"registryDependencies":["@siteplane/base","@siteplane/card","@siteplane/separator"],"files":[{"path":"packages/ui/src/components/settings-list/settings-list.tsx","content":"\"use client\";\n\nimport { useId, type ComponentPropsWithoutRef, type ReactNode } from \"react\";\n\nimport { Card } from \"../card\";\nimport { Separator } from \"../separator\";\n\nimport { cn } from \"../../system/utils/cn\";\nimport { slotClass } from \"../../system/utils/slot-class\";\n\nexport interface SettingsListProps extends Omit<\n  ComponentPropsWithoutRef<\"section\">,\n  \"title\"\n> {\n  description?: ReactNode;\n  title: ReactNode;\n  /**\n   * The heading level of the title, 1 to 6; `h2` by default, below the page's\n   * `h1`. A list inside a section of a settings page takes the next level. The\n   * look stays the same at every level.\n   */\n  titleLevel?: 1 | 2 | 3 | 4 | 5 | 6 | undefined;\n}\n\n/**\n * What `control` receives. Spread it on a switch, a select trigger or an input:\n * the title becomes their accessible name. An action button keeps its own text\n * as its name, so pass it `aria-describedby` only; with `aria-labelledby` too,\n * the title would replace the button's label for assistive technology.\n */\nexport interface SettingsListControlProps {\n  \"aria-describedby\"?: string | undefined;\n  \"aria-labelledby\": string;\n}\n\nexport interface SettingsListItemProps extends Omit<\n  ComponentPropsWithoutRef<\"div\">,\n  \"children\" | \"title\"\n> {\n  control: (props: SettingsListControlProps) => ReactNode;\n  description?: ReactNode;\n  layout?: \"inline\" | \"responsive\";\n  tag?: ReactNode;\n  title: ReactNode;\n}\n\n/**\n * The list is a size container: its rows, its card padding and its header\n * inset switch once the list itself is 36rem wide. A list in a page column\n * keeps the rows it had at the old viewport `md` switch; beside a sidebar or\n * in a narrow column it stays stacked. The gaps and the header inset are the\n * rules in design-rework.css.\n */\nexport function SettingsList({\n  children,\n  className,\n  description,\n  title,\n  titleLevel = 2,\n  ...props\n}: SettingsListProps): React.ReactElement {\n  const Title = `h${titleLevel}` as const;\n  return (\n    <section\n      className={cn(\n        slotClass(\"settings-list\", props),\n        \"@container/settings-list flex w-full flex-col\",\n        className,\n      )}\n      data-recipe=\"settings-list\"\n      data-slot=\"settings-list\"\n      {...props}\n    >\n      <header\n        className=\"sp-settings-list-header grid min-w-0\"\n        data-slot=\"settings-list-header\"\n      >\n        <Title\n          className=\"sp-settings-list-title\"\n          data-slot=\"settings-list-title\"\n        >\n          {title}\n        </Title>\n        {description ? (\n          <p\n            className=\"sp-settings-list-description\"\n            data-slot=\"settings-list-description\"\n          >\n            {description}\n          </p>\n        ) : null}\n      </header>\n      <div\n        className=\"sp-settings-list-surface min-w-0\"\n        data-slot=\"settings-list-surface\"\n      >\n        <Card className=\"grid min-w-0 px-4 py-5 @min-[36rem]/settings-list:px-6\">\n          {children}\n        </Card>\n      </div>\n    </section>\n  );\n}\n\nexport function SettingsListItem({\n  className,\n  control,\n  description,\n  layout = \"responsive\",\n  tag,\n  title,\n  ...props\n}: SettingsListItemProps): React.ReactElement {\n  const descriptionId = useId();\n  const titleId = useId();\n\n  return (\n    <div\n      className={cn(\n        slotClass(\"settings-list-item\", props),\n        \"group/settings-item flex\",\n        layout === \"inline\"\n          ? \"items-center justify-between\"\n          : \"flex-col @min-[36rem]/settings-list:flex-row @min-[36rem]/settings-list:items-center @min-[36rem]/settings-list:justify-between\",\n        className,\n      )}\n      data-layout={layout}\n      data-slot=\"settings-list-item\"\n      {...props}\n    >\n      {/* A drawn divider between rows: the list already separates them. */}\n      <Separator\n        className=\"absolute inset-x-0 bottom-0 group-last/settings-item:hidden\"\n        role=\"presentation\"\n      />\n      <div\n        className=\"sp-settings-list-item-copy flex min-w-0 flex-auto flex-col\"\n        data-slot=\"settings-list-item-copy\"\n      >\n        <div className=\"flex min-w-0 flex-wrap items-center gap-x-1.5\">\n          <span className=\"min-w-0 wrap-anywhere\" id={titleId}>\n            {title}\n          </span>\n          {tag}\n        </div>\n        {description ? (\n          <div\n            className=\"sp-settings-list-item-description min-w-0 wrap-anywhere\"\n            data-slot=\"settings-list-item-description\"\n            id={descriptionId}\n          >\n            {description}\n          </div>\n        ) : null}\n      </div>\n      <div\n        className={cn(\n          \"sp-settings-list-item-control\",\n          \"flex min-w-0 shrink-0 items-center @min-[36rem]/settings-list:justify-end @min-[36rem]/settings-list:text-right\",\n          layout === \"inline\"\n            ? \"justify-end text-right\"\n            : \"@max-[36rem]/settings-list:w-full\",\n        )}\n        data-slot=\"settings-list-item-control\"\n      >\n        {control({\n          \"aria-describedby\": description ? descriptionId : undefined,\n          \"aria-labelledby\": titleId,\n        })}\n      </div>\n    </div>\n  );\n}\n","type":"registry:ui","target":"~/src/siteplane/components/settings-list/settings-list.tsx"},{"path":"packages/ui/src/components/settings-list/index.ts","content":"export * from \"./settings-list\";\n","type":"registry:ui","target":"~/src/siteplane/components/settings-list/index.ts"}],"type":"registry:ui","docs":"https://ui.siteplane.io/docs-markdown/components/settings-list.md","categories":["Data display"],"meta":{"avoidWhen":["Avoid when the whole row, rather than its trailing control, should activate the setting."],"description":"Sectioned settings surface with passive items and consumer-provided controls, tags and supporting content.","knownLimitations":["The list is not a form and submits no values; the controls it renders own their state."],"providerNotes":[],"releaseStatus":"stable","searchTerms":["settings-list","settings","preferences","rows"],"useWhen":["Use when settings share one surfaced row anatomy but use different trailing controls."]}}