{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "layout",
  "type": "registry:ui",
  "title": "Layout",
  "description": "Stack, Inline, Grid and Container. Use them for all spacing between elements.",
  "dependencies": [
    "radix-ui@^1.6.7"
  ],
  "registryDependencies": [
    "https://blank.vageshwar.dev/r/theme.json",
    "https://blank.vageshwar.dev/r/utils.json"
  ],
  "files": [
    {
      "path": "ui/layout.tsx",
      "type": "registry:ui",
      "content": "// BlankUI: layout. Managed by BlankUI. Read layout.md before editing. Extend with props, not class overrides.\nimport type { ComponentProps } from \"react\"\nimport { Slot } from \"radix-ui\"\nimport { cn } from \"@/lib/utils\"\n\n/** Spacing steps. Same as Tailwind spacing: 4 = 1rem. */\nexport type Space = 1 | 2 | 3 | 4 | 6 | 8 | 12\n\nconst gapClass: Record<Space, string> = {\n  1: \"gap-1\",\n  2: \"gap-2\",\n  3: \"gap-3\",\n  4: \"gap-4\",\n  6: \"gap-6\",\n  8: \"gap-8\",\n  12: \"gap-12\",\n}\n\nconst alignClass = {\n  start: \"items-start\",\n  center: \"items-center\",\n  end: \"items-end\",\n  stretch: \"items-stretch\",\n  baseline: \"items-baseline\",\n} as const\n\nconst justifyClass = {\n  start: \"justify-start\",\n  center: \"justify-center\",\n  end: \"justify-end\",\n  between: \"justify-between\",\n} as const\n\ntype Align = keyof typeof alignClass\ntype Justify = keyof typeof justifyClass\n\ninterface LayoutBaseProps extends ComponentProps<\"div\"> {\n  /** Space between children. Uses the spacing scale: 1, 2, 3, 4, 6, 8 or 12. */\n  gap?: Space\n  /** Render the single child element instead of a `div`, for example a `section` or `ul`. */\n  asChild?: boolean\n}\n\nexport interface StackProps extends LayoutBaseProps {\n  /** Cross-axis (horizontal) alignment of children. Defaults to `stretch`. */\n  align?: Align\n  /** Main-axis (vertical) distribution of children. Defaults to `start`. */\n  justify?: Justify\n}\n\n/**\n * Vertical layout. Use it instead of `flex flex-col gap-*` or `space-y-*`.\n *\n * @example\n * <Stack gap={4}>\n *   <h2>Title</h2>\n *   <p>Body</p>\n * </Stack>\n */\nexport function Stack({\n  gap = 4,\n  align = \"stretch\",\n  justify = \"start\",\n  asChild = false,\n  className,\n  ...props\n}: StackProps) {\n  const Comp = asChild ? Slot.Root : \"div\"\n  return (\n    <Comp\n      data-slot=\"stack\"\n      className={cn(\n        \"flex flex-col\",\n        gapClass[gap],\n        alignClass[align],\n        justifyClass[justify],\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport interface InlineProps extends LayoutBaseProps {\n  /** Cross-axis (vertical) alignment of children. Defaults to `center`. */\n  align?: Align\n  /** Main-axis (horizontal) distribution of children. Defaults to `start`. */\n  justify?: Justify\n  /** Let children wrap onto the next line. Defaults to `true`. */\n  wrap?: boolean\n}\n\n/**\n * Horizontal layout that wraps. Use it for button rows, tags and toolbars,\n * instead of `flex gap-*` or `space-x-*`.\n *\n * @example\n * <Inline gap={2} justify=\"end\">\n *   <Button variant=\"outline\">Cancel</Button>\n *   <Button>Save</Button>\n * </Inline>\n */\nexport function Inline({\n  gap = 2,\n  align = \"center\",\n  justify = \"start\",\n  wrap = true,\n  asChild = false,\n  className,\n  ...props\n}: InlineProps) {\n  const Comp = asChild ? Slot.Root : \"div\"\n  return (\n    <Comp\n      data-slot=\"inline\"\n      className={cn(\n        \"flex flex-row\",\n        wrap && \"flex-wrap\",\n        gapClass[gap],\n        alignClass[align],\n        justifyClass[justify],\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/** Number of grid columns. */\nexport type Columns = 1 | 2 | 3 | 4 | 6 | 12\n\n/** Columns per breakpoint. `base` applies to all sizes, the others from that breakpoint up. */\nexport interface ResponsiveColumns {\n  base?: Columns\n  sm?: Columns\n  md?: Columns\n  lg?: Columns\n  xl?: Columns\n}\n\nconst columnClass = {\n  base: {\n    1: \"grid-cols-1\",\n    2: \"grid-cols-2\",\n    3: \"grid-cols-3\",\n    4: \"grid-cols-4\",\n    6: \"grid-cols-6\",\n    12: \"grid-cols-12\",\n  },\n  sm: {\n    1: \"sm:grid-cols-1\",\n    2: \"sm:grid-cols-2\",\n    3: \"sm:grid-cols-3\",\n    4: \"sm:grid-cols-4\",\n    6: \"sm:grid-cols-6\",\n    12: \"sm:grid-cols-12\",\n  },\n  md: {\n    1: \"md:grid-cols-1\",\n    2: \"md:grid-cols-2\",\n    3: \"md:grid-cols-3\",\n    4: \"md:grid-cols-4\",\n    6: \"md:grid-cols-6\",\n    12: \"md:grid-cols-12\",\n  },\n  lg: {\n    1: \"lg:grid-cols-1\",\n    2: \"lg:grid-cols-2\",\n    3: \"lg:grid-cols-3\",\n    4: \"lg:grid-cols-4\",\n    6: \"lg:grid-cols-6\",\n    12: \"lg:grid-cols-12\",\n  },\n  xl: {\n    1: \"xl:grid-cols-1\",\n    2: \"xl:grid-cols-2\",\n    3: \"xl:grid-cols-3\",\n    4: \"xl:grid-cols-4\",\n    6: \"xl:grid-cols-6\",\n    12: \"xl:grid-cols-12\",\n  },\n} as const satisfies Record<keyof ResponsiveColumns, Record<Columns, string>>\n\nexport interface GridProps extends LayoutBaseProps {\n  /**\n   * Number of columns, or columns per breakpoint.\n   * @example columns={3}\n   * @example columns={{ base: 1, md: 2, lg: 3 }}\n   */\n  columns?: Columns | ResponsiveColumns\n}\n\n/**\n * Grid of equal columns. Use it for card grids and form rows.\n *\n * @example\n * <Grid columns={{ base: 1, md: 3 }} gap={6}>\n *   <Card />\n *   <Card />\n *   <Card />\n * </Grid>\n */\nexport function Grid({ columns = 1, gap = 4, asChild = false, className, ...props }: GridProps) {\n  const Comp = asChild ? Slot.Root : \"div\"\n  const responsive: ResponsiveColumns = typeof columns === \"number\" ? { base: columns } : columns\n  const colClasses = (Object.keys(responsive) as (keyof ResponsiveColumns)[]).map((bp) => {\n    const n = responsive[bp]\n    return n ? columnClass[bp][n] : undefined\n  })\n  return (\n    <Comp\n      data-slot=\"grid\"\n      className={cn(\"grid\", colClasses, gapClass[gap], className)}\n      {...props}\n    />\n  )\n}\n\nconst containerSize = {\n  sm: \"max-w-2xl\",\n  md: \"max-w-4xl\",\n  lg: \"max-w-6xl\",\n  xl: \"max-w-7xl\",\n  full: \"max-w-none\",\n} as const\n\nexport interface ContainerProps extends Omit<LayoutBaseProps, \"gap\"> {\n  /** Maximum width. `sm` suits articles and forms, `lg` suits most app pages. Defaults to `lg`. */\n  size?: keyof typeof containerSize\n}\n\n/**\n * Centers page content with a max width and responsive side padding.\n * Use one per page section instead of `mx-auto max-w-* px-*`.\n *\n * @example\n * <Container size=\"md\">\n *   <Stack gap={8}>...</Stack>\n * </Container>\n */\nexport function Container({ size = \"lg\", asChild = false, className, ...props }: ContainerProps) {\n  const Comp = asChild ? Slot.Root : \"div\"\n  return (\n    <Comp\n      data-slot=\"container\"\n      className={cn(\"mx-auto w-full px-4 sm:px-6 lg:px-8\", containerSize[size], className)}\n      {...props}\n    />\n  )\n}\n"
    },
    {
      "path": "ui/layout.md",
      "type": "registry:ui",
      "content": "---\nname: layout\ntitle: Layout\ndescription: Stack, Inline, Grid and Container. Use them for all spacing between elements.\ncategory: layout\nwhenToUse:\n  - Any vertical list of elements with space between them (Stack).\n  - Rows of buttons, tags, or icon and text pairs (Inline).\n  - Card grids, stat rows and multi-column forms (Grid).\n  - The outer width and side padding of a page or page section (Container).\nwhenNotToUse:\n  - when: You need space inside an element, like padding in a card.\n    use: card\n  - when: You are laying out a data table.\n    use: table\nrelated: []\nrequiredParts: [Stack, Inline, Grid, Container]\nantiPatterns:\n  - avoid: '<div className=\"flex flex-col gap-4\">'\n    instead: \"<Stack gap={4}>\"\n  - avoid: '<div className=\"space-y-6\">'\n    instead: \"<Stack gap={6}>\"\n  - avoid: '<div className=\"flex items-center gap-2\">'\n    instead: \"<Inline gap={2}>\"\n  - avoid: '<div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">'\n    instead: \"<Grid columns={{ base: 1, md: 3 }} gap={6}>\"\n  - avoid: '<div className=\"mx-auto max-w-6xl px-4\">'\n    instead: \"<Container>\"\n  - avoid: \"gap={5} or gap={10}\"\n    instead: \"Use a step from the scale: 1, 2, 3, 4, 6, 8, 12.\"\n---\n\n# Layout\n\nFour primitives handle all layout spacing. They only accept steps from the spacing scale, so pages stay consistent.\n\n| Component   | Direction  | Default gap | Use for                          |\n| ----------- | ---------- | ----------- | -------------------------------- |\n| `Stack`     | vertical   | 4           | sections, forms, lists           |\n| `Inline`    | horizontal | 2           | button rows, tags, toolbars      |\n| `Grid`      | columns    | 4           | card grids, multi-column layouts |\n| `Container` | none       | none        | page width and side padding      |\n\nSpacing scale: `1 | 2 | 3 | 4 | 6 | 8 | 12` (4 = 1rem).\n\n## Import\n\n```tsx\nimport { Stack, Inline, Grid, Container } from \"@/components/ui/layout\"\n```\n\n## Page layout\n\n```tsx\n<Container size=\"md\">\n  <Stack gap={8}>\n    <Stack gap={2}>\n      <h1 className=\"font-heading text-3xl font-bold\">Settings</h1>\n      <p className=\"text-muted-foreground\">Manage your account.</p>\n    </Stack>\n    <Grid columns={{ base: 1, md: 2 }} gap={6}>\n      <Card>...</Card>\n      <Card>...</Card>\n    </Grid>\n    <Inline gap={2} justify=\"end\">\n      <Button variant=\"outline\">Cancel</Button>\n      <Button>Save</Button>\n    </Inline>\n  </Stack>\n</Container>\n```\n\n## Semantic elements\n\nUse `asChild` to render a different element:\n\n```tsx\n<Stack asChild gap={2}>\n  <ul>\n    <li>One</li>\n    <li>Two</li>\n  </ul>\n</Stack>\n```\n\n## Props\n\n- `Stack`: `gap`, `align` (`start | center | end | stretch | baseline`), `justify` (`start | center | end | between`), `asChild`\n- `Inline`: same as Stack, plus `wrap` (default `true`). `align` defaults to `center`.\n- `Grid`: `columns` (`1 | 2 | 3 | 4 | 6 | 12`, or `{ base, sm, md, lg, xl }`), `gap`, `asChild`\n- `Container`: `size` (`sm | md | lg | xl | full`, default `lg`), `asChild`\n"
    }
  ],
  "docs": "Read components/ui/layout.md before using Layout. Docs: https://blank.vageshwar.dev/docs/layout",
  "meta": {
    "category": "layout",
    "requiredParts": [
      "Stack",
      "Inline",
      "Grid",
      "Container"
    ],
    "related": []
  }
}
