import { Meta } from "@storybook/addon-docs/blocks";

import * as ColStories from "./col.stories";

<Meta of={ColStories} />

# Col

A column component for building responsive 12-column layouts within Row
containers.

## Overview

Col provides a type-safe React wrapper around column utility classes, allowing
developers to create responsive columns with precise control over width,
positioning, and visual order. Unlike Row, Col has **no base class** - it's pure
utility class composition following the Grid.Item pattern.

## Key Features

- **No Base Class**: Pure utility class mapping for maximum flexibility
- **Span Control**: 1-12 column widths via the `span` prop
- **Flex-Grow Columns**: Fill remaining space with `span="flex"`
- **Offset Positioning**: Push columns right with `offset` prop
- **Visual Reordering**: Change display order with `order` prop
- **Auto-Width**: Content-based width with `auto` prop
- **Polymorphic**: Render as any semantic HTML element
- **Type-Safe**: Full TypeScript support with literal types

## When to Use

Use Col when you need:

- Responsive column layouts within Row containers
- Precise control over column widths (12-column grid)
- Offset positioning to create whitespace
- Visual reordering without changing DOM order
- Content-based column widths

## Props

### span

Column span (width) from 1-12 columns, or "flex" for flex-grow behavior. Ignored
if `auto` is true.

- **Type**: `1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | "flex"`
- **Default**: `undefined`
- **CSS Class**: `.col-{span}` or `.col-flex`
- **Calculation**: `span / 12 * 100%` (for numeric values)

**Numeric Examples:**

- `span={12}` = 100% width (`.col-12`)
- `span={6}` = 50% width (`.col-6`)
- `span={4}` = 33.33% width (`.col-4`)
- `span={3}` = 25% width (`.col-3`)

**Flex Example:**

- `span="flex"` = Grows to fill remaining space (`.col-flex`)
  - Desktop: `flex: 1 1 0%` (grows to fill available space)
  - Mobile: Stacks to 100% width like other columns

### offset

Column offset (left margin) from 0-11 columns. Pushes column to the right.

- **Type**: `0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11`
- **Default**: `undefined`
- **CSS Class**: `.col-offset-{offset}`
- **Calculation**: `offset / 12 * 100%`

**Examples:**

- `offset={3}` = Push right by 25% (`.col-offset-3`)
- `offset={0}` = No offset (`.col-offset-0`)

### order

Visual display order using flexbox `order` property. Does not change DOM order.

- **Type**:
  `"first" | "last" | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12`
- **Default**: `undefined`
- **CSS Class**: `.col-order-{order}`

**Examples:**

- `order="first"` = Display first (order: -1)
- `order="last"` = Display last (order: 13)
- `order={1}` = Display in position 1

### auto

Auto-width column based on content. Takes precedence over `span` (including
`span="flex"`).

- **Type**: `boolean`
- **Default**: `false`
- **CSS Class**: `.col-auto`

When `true`, column width adjusts to fit content instead of spanning a fixed
number of columns.

**Note**: For columns that grow to fill remaining space (not content-based), use
`span="flex"` instead of `auto`.

### as

Element type to render. Supports semantic HTML elements.

- **Type**: `"div" | "section" | "article" | "li"`
- **Default**: `"div"`

### className

Additional CSS classes to merge with utility classes.

- **Type**: `string`
- **Default**: `undefined`

## Basic Usage

```jsx
import { Row, Col } from "@fpkit/acss";

function MyLayout() {
  return (
    <Row>
      <Col span={6}>Left column (50%)</Col>
      <Col span={6}>Right column (50%)</Col>
    </Row>
  );
}
```

## Examples

### Column Spans

```jsx
<Row gap="md">
  {/* Full width */}
  <Col span={12}>100% width</Col>

  {/* Half width */}
  <Col span={6}>50% width</Col>
  <Col span={6}>50% width</Col>

  {/* Thirds */}
  <Col span={4}>33.33% width</Col>
  <Col span={4}>33.33% width</Col>
  <Col span={4}>33.33% width</Col>

  {/* Quarters */}
  <Col span={3}>25%</Col>
  <Col span={3}>25%</Col>
  <Col span={3}>25%</Col>
  <Col span={3}>25%</Col>
</Row>
```

### Column Offsets

```jsx
<Row gap="md">
  {/* Centered column */}
  <Col span={6} offset={3}>
    Centered (50% width, 25% left margin)
  </Col>

  {/* Two columns with gap in middle */}
  <Col span={3}>Left column</Col>
  <Col span={3} offset={6}>
    Right column (50% gap between)
  </Col>

  {/* Multiple offsets */}
  <Col span={2} offset={2}>
    offset-2
  </Col>
  <Col span={2} offset={2}>
    offset-2
  </Col>
  <Col span={2} offset={2}>
    offset-2
  </Col>
</Row>
```

### Visual Reordering

```jsx
<Row gap="md">
  {/* Source order: 1, 2, 3 */}
  {/* Visual order: 3, 1, 2 */}
  <Col span={4} order={2}>DOM 1st, Visual 3rd</Col>
  <Col span={4} order={0}>DOM 2nd, Visual 1st</Col>
  <Col span={4} order={1}>DOM 3rd, Visual 2nd</Col>
</Row>

<Row gap="md">
  {/* order-first and order-last */}
  <Col span={6} order="last">Appears last visually</Col>
  <Col span={6} order="first">Appears first visually</Col>
</Row>
```

### Auto-Width Columns

```jsx
<Row gap="sm">
  {/* Content-based width */}
  <Col auto>Button</Col>
  <Col auto>Another Button</Col>
  <Col auto>Third Button</Col>
</Row>

<Row gap="md">
  {/* Mix fixed and auto */}
  <Col span={3}>Fixed 25%</Col>
  <Col auto>Auto width (content-based)</Col>
  <Col span={2}>Fixed 16.66%</Col>
</Row>
```

### Flex Columns (Fill Remaining Space)

Use `span="flex"` to create columns that grow to fill available space after
fixed-width columns. This is different from `auto` which sizes to content.

```jsx
{/* Flex vs Auto Comparison */}
<Row gap="md">
  <Col span={3}>Fixed 25%</Col>
  <Col span="flex">Flex (grows to fill 75%)</Col>
</Row>

<Row gap="md">
  <Col span={3}>Fixed 25%</Col>
  <Col auto>Auto (sizes to content only)</Col>
</Row>
```

**Multiple flex columns share space equally:**

```jsx
<Row gap="md">
  <Col span={2}>Fixed sidebar</Col>
  <Col span="flex">Section 1 (50% of remaining)</Col>
  <Col span="flex">Section 2 (50% of remaining)</Col>
</Row>
```

**Common Patterns:**

```jsx
{/* Sidebar layout */}
<Row gap="lg">
  <Col span={3}>Sidebar (25%)</Col>
  <Col span="flex">Main content (grows to fill 75%)</Col>
</Row>

{/* Button group with spacer */}
<Row gap="sm" align="center">
  <Col auto><Button>Save</Button></Col>
  <Col span="flex">{/* Flexible spacer */}</Col>
  <Col auto><Button>Cancel</Button></Col>
</Row>

{/* App layout */}
<Row gap="md">
  <Col span={2}>Navigation</Col>
  <Col span="flex">Main Content</Col>
  <Col span={3}>Sidebar</Col>
</Row>

{/* Form layout with label and input */}
<Row gap="sm" align="center">
  <Col auto><Label>Email:</Label></Col>
  <Col span="flex"><Input type="email" /></Col>
  <Col auto><Button>Subscribe</Button></Col>
</Row>
```

**Key Differences:**

| Feature           | `auto`                 | `span="flex"`               |
| ----------------- | ---------------------- | --------------------------- |
| **CSS**           | `flex: 0 0 auto`       | `flex: 1 1 0%`              |
| **Behavior**      | Sizes to content width | Grows to fill space         |
| **Use case**      | Buttons, labels, icons | Main content areas          |
| **Mobile**        | Content-based          | 100% width (stacked)        |
| **Desktop**       | Content-based          | Fills remaining space       |
| **Multiple cols** | Each sizes to content  | Share remaining space equally |

### Responsive Columns

The Col component supports responsive utility classes for breakpoint-specific
widths. While the `span` prop is not responsive, you can use the `className`
prop with responsive utility classes.

**Basic Responsive Pattern:**

```jsx
<Row gap="md">
  {/* Mobile: 100%, Tablet: 50%, Desktop: 33% */}
  <Col className="col-12 col-md-6 col-lg-4">Responsive column</Col>
  <Col className="col-12 col-md-6 col-lg-4">Responsive column</Col>
  <Col className="col-12 col-md-6 col-lg-4">Responsive column</Col>
</Row>
```

**Layout Progression:**

```
Mobile (< 768px):       Tablet (≥ 768px):      Desktop (≥ 1024px):
┌─────────────┐         ┌──────┬──────┐        ┌────┬────┬────┐
│   Column 1  │         │ Col1 │ Col2 │        │ C1 │ C2 │ C3 │
├─────────────┤         ├──────┼──────┤        └────┴────┴────┘
│   Column 2  │         │ Col3 │      │
├─────────────┤         └──────┘
│   Column 3  │
└─────────────┘

1 column              2 columns            3 columns
```

**Dashboard Cards Example:**

```jsx
<Row gap="lg" align="stretch">
  {/* 1 col mobile, 2 col tablet, 4 col desktop */}
  <Col className="col-12 col-md-6 col-lg-3">
    <Card>
      <h3>Total Users</h3>
      <p>1,234</p>
    </Card>
  </Col>
  <Col className="col-12 col-md-6 col-lg-3">
    <Card>
      <h3>Revenue</h3>
      <p>$12,345</p>
    </Card>
  </Col>
  <Col className="col-12 col-md-6 col-lg-3">
    <Card>
      <h3>Conversions</h3>
      <p>567</p>
    </Card>
  </Col>
  <Col className="col-12 col-md-6 col-lg-3">
    <Card>
      <h3>Growth</h3>
      <p>+23%</p>
    </Card>
  </Col>
</Row>
```

**How it works:**

- **Mobile** (< 768px): `.col-12` applies → 100% width, cards stack vertically
- **Tablet** (≥ 768px): `.col-md-6` overrides → 50% width, 2 cards per row
- **Desktop** (≥ 1024px): `.col-lg-3` overrides → 25% width, 4 cards per row

**Available Responsive Utilities:**

| Utility Type     | Classes                          | Example             | Description                  |
| ---------------- | -------------------------------- | ------------------- | ---------------------------- |
| **Span**         | `.col-{sm\|md\|lg}-{1-12}`       | `.col-md-6`         | Column width at breakpoint   |
| **Auto-width**   | `.col-{sm\|md\|lg}-auto`         | `.col-md-auto`      | Content-based width          |
| **Flex-grow**    | `.col-{sm\|md\|lg}-flex`         | `.col-lg-flex`      | Fill remaining space         |
| **Offset**       | `.col-{sm\|md\|lg}-offset-{0-11}` | `.col-md-offset-2` | Left margin push             |
| **Order**        | `.col-{sm\|md\|lg}-order-{first\|last\|0-12}` | `.col-lg-order-2`  | Visual reordering            |

**See [STYLES.mdx](./STYLES.mdx) for complete responsive utility reference.**

### Responsive Props vs Classes

**Important Limitation:** The `span` prop is **not responsive**. It applies the same
width at all screen sizes.

**To create responsive layouts:**

- Use the `className` prop with responsive utility classes
- Combine base column class with breakpoint-specific overrides

**Example:**

```jsx
// ❌ WRONG: span prop is not responsive
<Col span={12} md={6} lg={4}>
  This won't work
</Col>

// ✅ CORRECT: Use className with responsive utilities
<Col className="col-12 col-md-6 col-lg-4">This works!</Col>

// ✅ ALSO CORRECT: Combine span prop (mobile) with responsive classes
<Col span={12} className="col-md-6 col-lg-4">
  Mobile: span prop (100%), Tablet: .col-md-6, Desktop: .col-lg-4
</Col>
```

**Best Practices:**

1. **Simple Layouts:** Use `span` prop for non-responsive columns
2. **Responsive Layouts:** Use `className` with `.col-{breakpoint}-*` classes
3. **Hybrid:** Combine `span` for mobile base with responsive classes for larger
   screens
4. **Documentation:** See [STYLES.mdx](./STYLES.mdx) for complete class reference

### Semantic HTML

```jsx
{
  /* List items */
}
<Row as="ul" gap="sm">
  <Col as="li" span={4}>
    List item 1
  </Col>
  <Col as="li" span={4}>
    List item 2
  </Col>
  <Col as="li" span={4}>
    List item 3
  </Col>
</Row>;

{
  /* Article sections */
}
<Row as="section">
  <Col as="article" span={6}>
    Article content 1
  </Col>
  <Col as="article" span={6}>
    Article content 2
  </Col>
</Row>;
```

## Accessibility

### Visual vs. DOM Order

**Important**: The `order` prop changes **visual order only**, not DOM order.
Screen readers and keyboard navigation follow DOM order, not visual order.

```jsx
{
  /* Screen readers read: "Column A", "Column B"
    Visually displays: "Column B", "Column A" */
}
<Row>
  <Col span={6} order={2}>
    Column A
  </Col>
  <Col span={6} order={1}>
    Column B
  </Col>
</Row>;
```

**Best Practice**: Only use `order` when visual reordering doesn't affect
content comprehension. Avoid reordering critical content like navigation or form
fields.

### Semantic Elements

Use appropriate HTML elements via the `as` prop:

```jsx
{
  /* Good: Semantic list */
}
<Row as="ul">
  <Col as="li" span={4}>
    Item
  </Col>
</Row>;

{
  /* Good: Article sections */
}
<Row>
  <Col as="article" span={6}>
    Article 1
  </Col>
  <Col as="article" span={6}>
    Article 2
  </Col>
</Row>;
```

### Focus Order

Keyboard navigation follows DOM order, not visual `order`. Ensure tab order is
logical:

```jsx
{
  /* Tab order: Input 1 → Input 2 → Button
    Visual order may differ if using order prop */
}
<Row>
  <Col span={6} order={1}>
    <input id="input1" />
  </Col>
  <Col span={6} order={2}>
    <input id="input2" />
  </Col>
  <Col span={12} order={0}>
    <button>Submit</button>
  </Col>
</Row>;
```

## Responsive Behavior

Col uses a **mobile-first** approach:

- **Mobile** (`<768px`): Columns default to 100% width and stack vertically
- **Desktop** (`≥768px`): Columns use their specified span values

### Responsive Classes

Use responsive utility classes on Col for breakpoint-specific widths:

```jsx
<Col
  span={12} // Mobile: 100%
  className="col-md-6 col-lg-4" // Tablet: 50%, Desktop: 33%
>
  Responsive content
</Col>
```

**Available Breakpoints:**

- `col-sm-*` - Large phones and up (`≥480px`)
- `col-md-*` - Tablets and up (`≥768px`)
- `col-lg-*` - Desktops and up (`≥1024px`)

## Breakpoint Reference

The columns system uses mobile-first responsive breakpoints:

| Breakpoint    | Variable               | Min Width | Pixel Value | Target Devices                 | Utility Prefix   |
| ------------- | ---------------------- | --------- | ----------- | ------------------------------ | ---------------- |
| **xs** (base) | `--col-breakpoint-xs`  | `0rem`    | 0px         | Mobile portrait                | (none - base classes) |
| **sm**        | `--col-breakpoint-sm`  | `30rem`   | 480px       | Mobile landscape, large phones | `.col-sm-*`      |
| **md**        | `--col-breakpoint-md`  | `48rem`   | 768px       | Tablets, small laptops         | `.col-md-*`      |
| **lg**        | `--col-breakpoint-lg`  | `64rem`   | 1024px      | Desktops, large screens        | `.col-lg-*`      |

**Mobile-First Cascade:**

```
Mobile (base)    →    Tablet (≥768px)    →    Desktop (≥1024px)
.col-12              .col-md-6              .col-lg-4
100% width           50% width              33.33% width
```

Classes cascade upward: `.col-sm-6` applies at sm (480px+), md (768px+), AND lg
(1024px+) unless overridden by `.col-md-*` or `.col-lg-*`.

**For complete CSS utility reference, see [STYLES.mdx](./STYLES.mdx).**

## Advanced Patterns

### Asymmetric Layouts

```jsx
<Row gap="lg">
  <Col span={8}>Main content (66.66%)</Col>
  <Col span={4}>Sidebar (33.33%)</Col>
</Row>

<Row gap="lg">
  <Col span={3}>Nav (25%)</Col>
  <Col span={6}>Content (50%)</Col>
  <Col span={3}>Aside (25%)</Col>
</Row>
```

### Complex Grid

```jsx
<Row gap="md">
  <Col span={12}>Header</Col>
  <Col span={8} className="col-lg-9">
    Main content
  </Col>
  <Col span={4} className="col-lg-3">
    Sidebar
  </Col>
  <Col span={6} className="col-lg-3">
    Footer column 1
  </Col>
  <Col span={6} className="col-lg-3">
    Footer column 2
  </Col>
  <Col span={12} className="col-lg-6">
    Footer column 3
  </Col>
</Row>
```

### Dashboard Metrics

```jsx
<Row gap="md" align="stretch">
  {/* 4 equal columns on desktop, stacked on mobile */}
  <Col span={12} className="col-sm-6 col-lg-3">
    <Card>
      <h3>Total Users</h3>
      <p>1,234</p>
    </Card>
  </Col>
  <Col span={12} className="col-sm-6 col-lg-3">
    <Card>
      <h3>Revenue</h3>
      <p>$12,345</p>
    </Card>
  </Col>
  <Col span={12} className="col-sm-6 col-lg-3">
    <Card>
      <h3>Conversions</h3>
      <p>567</p>
    </Card>
  </Col>
  <Col span={12} className="col-sm-6 col-lg-3">
    <Card>
      <h3>Growth</h3>
      <p>+23%</p>
    </Card>
  </Col>
</Row>
```

### Form Layout

```jsx
<Row gap="md">
  <Col span={12} className="col-md-6">
    <Field>
      <FieldLabel htmlFor="first-name">First Name</FieldLabel>
      <FieldInput id="first-name" />
    </Field>
  </Col>
  <Col span={12} className="col-md-6">
    <Field>
      <FieldLabel htmlFor="last-name">Last Name</FieldLabel>
      <FieldInput id="last-name" />
    </Field>
  </Col>
  <Col span={12}>
    <Field>
      <FieldLabel htmlFor="email">Email</FieldLabel>
      <FieldInput id="email" type="email" />
    </Field>
  </Col>
  <Col span={12}>
    <button type="submit">Submit</button>
  </Col>
</Row>
```

## Common Responsive Patterns

### Blog Sidebar Layout

**Pattern:** Content stacks on mobile, sidebar appears on tablet+

```jsx
<Row gap="lg">
  <Col className="col-12 col-md-8">
    <article>Main blog content...</article>
  </Col>
  <Col className="col-12 col-md-4">
    <aside>Sidebar widgets...</aside>
  </Col>
</Row>
```

**Layout:**

```
Mobile (< 768px):       Desktop (≥ 768px):
┌─────────────┐         ┌─────────┬───────┐
│   Content   │         │ Content │ Side  │
├─────────────┤         │         │ bar   │
│   Sidebar   │         │         │       │
└─────────────┘         └─────────┴───────┘
```

### Product Grid

**Pattern:** Progressive grid (1 → 2 → 3 columns)

```jsx
<Row gap="md">
  {products.map((product) => (
    <Col key={product.id} className="col-12 col-sm-6 col-lg-4">
      <ProductCard product={product} />
    </Col>
  ))}
</Row>
```

**Result:**

- Mobile (< 480px): 1 column
- Tablet (≥ 480px): 2 columns
- Desktop (≥ 1024px): 3 columns

### Form Layout

**Pattern:** Full-width mobile, multi-column desktop

```jsx
<Row gap="md">
  <Col className="col-12 col-md-6">
    <Field>
      <FieldLabel htmlFor="firstName">First Name</FieldLabel>
      <FieldInput id="firstName" />
    </Field>
  </Col>
  <Col className="col-12 col-md-6">
    <Field>
      <FieldLabel htmlFor="lastName">Last Name</FieldLabel>
      <FieldInput id="lastName" />
    </Field>
  </Col>
  <Col className="col-12">
    <Field>
      <FieldLabel htmlFor="email">Email</FieldLabel>
      <FieldInput id="email" type="email" />
    </Field>
  </Col>
  <Col className="col-12">
    <button type="submit">Submit</button>
  </Col>
</Row>
```

### Centered Content with Progressive Margins

**Pattern:** Content gets narrower and more centered on larger screens

```jsx
<Row>
  <Col className="col-10 col-offset-1 col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3">
    <article>
      <h1>Article Title</h1>
      <p>Progressively centered content...</p>
    </article>
  </Col>
</Row>
```

**Result:**

- Mobile (< 480px): 100% width, no offset
- Small (≥ 480px): 83.33% width (10/12), 8.33% left margin
- Tablet (≥ 768px): 66.67% width (8/12), 16.67% left margin
- Desktop (≥ 1024px): 50% width (6/12), 25% left margin

## Related Components

- **Row** - Flex container for Col components
- **Grid** - Alternative grid system using CSS Grid
- **Grid.Item** - Item component for Grid (similar pattern to Col)

## Best Practices

1. **Always use Col within Row**: Col is designed for use within Row containers
2. **Total span = 12**: Columns in a row should sum to 12 (or less if
   intentional gaps)
3. **Mobile-first responsive**: Start with mobile layout, enhance for desktop
4. **Semantic HTML**: Use `as` prop for appropriate elements (li, article,
   section)
5. **Avoid order for critical content**: Only reorder decorative or non-critical
   content
6. **Consistent gaps**: Use Row's `gap` prop for uniform spacing

## Technical Notes

### CSS Classes

Col renders with **no base class**. Only utility classes are applied:

- Span: `.col-{1-12}` (fixed width columns)
- Flex: `.col-flex` (flex-grow column)
- Offset: `.col-offset-{0-11}`
- Order: `.col-order-{first|last|0-12}`
- Auto: `.col-auto` (content-based width)

### Column Width Calculation

Column widths are calculated as:

```
width = (span / 12) * 100%
```

**Examples:**

- `.col-12` = 100% (12/12)
- `.col-6` = 50% (6/12)
- `.col-4` = 33.33% (4/12)
- `.col-3` = 25% (3/12)
- `.col-1` = 8.33% (1/12)

### Offset Calculation

Offsets use margin-inline-start:

```
margin-inline-start = (offset / 12) * 100%
```

**Examples:**

- `.col-offset-3` = 25% left margin
- `.col-offset-6` = 50% left margin

### Auto-Width Behavior

`.col-auto` uses `flex: 0 0 auto` with `width: auto`, allowing the column to
size based on its content.

### Flex-Grow Behavior

`.col-flex` uses responsive flex properties to fill remaining space:

**Mobile (`< 768px`):**

```css
.col-flex {
  flex: 0 0 100%; /* Stack to full width */
  min-width: 0;
  box-sizing: border-box;
}
```

**Desktop (`≥ 768px`):**

```css
.col-flex {
  flex: 1 1 0%; /* Grow to fill available space */
}
```

**How it works:**

- `flex-grow: 1` - Column grows to fill available space
- `flex-shrink: 1` - Column can shrink if constrained
- `flex-basis: 0%` - Ensures equal distribution when multiple flex columns exist
- Multiple flex columns share remaining space equally

**Example calculations:**

```jsx
// Container width: 1200px
<Row>
  <Col span={3}>Fixed 300px (25%)</Col>
  <Col span="flex">Grows to 900px (75%)</Col>
</Row>

// Multiple flex columns
<Row>
  <Col span={2}>Fixed 200px (16.67%)</Col>
  <Col span="flex">Flex 1: 500px (41.67%)</Col>
  <Col span="flex">Flex 2: 500px (41.67%)</Col>
</Row>
```

### Performance

Col is a lightweight wrapper with no runtime overhead. All layout calculations
are handled via CSS utility classes at build time.
