# ButtonNode

CTA button node dùng component `Button` từ `@janbox/storefront-ui`. Luôn render thẻ `<button>`; gắn link qua prop `link` thì khi click sẽ điều hướng bằng JS.

## Resolved name

`Button`

## Configurable props

### Top-level props

| Prop | Type | Description |
| --- | --- | --- |
| `children` | `ReactNode` | Nội dung hiển thị trong button |
| `color` | `ColorScale` | Màu theme của button |
| `variant` | `ButtonVariant` | Kiểu hiển thị của button |
| `size` | `ButtonSizeVariant` | Kích thước button |
| `link.href` | `string` | Đường dẫn điều hướng |
| `link.target` | `'_self' \| '_blank' \| '_parent' \| '_top'` | Cách mở link, mặc định `'_self'` |

`size` hỗ trợ responsive: `size="sm"` xs, `md={{ size: 'lg' }}` desktop.

**`ColorScale`:** `'primary' | 'secondary' | 'green' | 'red' | 'orange' | 'blue' | 'neutral' | 'yellow' | 'violet'`

**`ButtonVariant`:** `'contained' | 'outlined' | 'text'`

**`ButtonSizeVariant`:** `'sm' | 'md' | 'lg'`

### `sx` props

```ts
sx?: {
  // size
  width?: number | string

  // spacing (margin only)
  marginTop?: number
  marginRight?: number
  marginBottom?: number
  marginLeft?: number

  // responsive overrides
  sm?: { /* same keys above */ }
  md?: { /* same keys above */ }
  lg?: { /* same keys above */ }
}
```

## Usage

```tsx
import { ButtonNode } from '@janbox/storefront-builder';

// Button cơ bản
<ButtonNode color="primary" variant="contained" size="md">
  Buy now
</ButtonNode>

// Link button
<ButtonNode color="primary" variant="contained" size="lg" link={{ href: '/checkout', target: '_blank' }}>
  Checkout
</ButtonNode>

// Responsive size + width
<ButtonNode
  color="orange"
  variant="outlined"
  size="sm"
  md={{ size: 'lg' }}
  sx={{
    width: '100%',
    marginTop: 16,
    md: {
      width: 'fit-content',
      marginTop: 24,
    },
  }}
>
  View products
</ButtonNode>
```

## Rules

- **Canvas**: no — không chứa node con.
- Click khi có `link.href`: gọi `onClick` trước, rồi `window.open(href, target)` (`_blank` kèm `noopener,noreferrer`). Bỏ qua điều hướng khi editor đang bật hoặc `onClick` đã gọi `e.preventDefault()`.
- Điều hướng bằng JS nên luôn tải lại trang (không đi qua router phía client), HTML không có `href` nên crawler không đọc được link và không mở được bằng chuột giữa.
- Nội dung button được chỉnh qua prop `children` trong inspector.

## Migrate dữ liệu

Từ bản dùng `@janbox/storefront-ui` v7, prop `anchor` được thay bằng `link`. Builder **không** đọc fallback `anchor`. Áp dụng cho node có `"type": { "resolvedName": "button" }` trong JSON đã lưu:

| Dữ liệu cũ | Dữ liệu mới |
| --- | --- |
| `anchor.to: '/path'` | `link.href: '/path'` |
| `anchor.to: { pathname, search, hash }` | `link.href: (pathname ?? '') + (search ?? '') + (hash ?? '')` |
| `anchor.target: 'X'` | `link.target: 'X'` |

Node còn sót `anchor` thì key này lọt xuống thẻ `<button>` thành attribute thừa kèm cảnh báo của React, nên xoá `anchor` sau khi đã thêm `link`.
