# flex-render

> Core framework-agnostic rendering engine for LINE Flex Messages (Bubbles & Carousels).

[![npm version](https://img.shields.io/npm/v/flex-render.svg?style=flat-square)](https://www.npmjs.com/package/flex-render)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)

`flex-render` takes raw Flex Message JSON specifications exported from the [LINE Flex Message Simulator](https://developers.line.biz/flex-simulator) or generated via `@line/bot-sdk` and parses them into pixel-accurate HTML strings with accompanying CSS styles.

---

## 📦 Installation

```bash
# pnpm
pnpm add flex-render

# npm
npm install flex-render

# yarn
yarn add flex-render

# bun
bun add flex-render
```

---

## 🚀 Usage

Import the `render` function from `flex-render` and the stylesheet `flex-render/css`:

```typescript
import { render } from 'flex-render'
import 'flex-render/css'

const flexJSON = {
  type: 'bubble',
  hero: {
    type: 'image',
    url: 'https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_1_cafe.png',
    size: 'full',
    aspectRatio: '20:13',
    aspectMode: 'cover',
  },
  body: {
    type: 'box',
    layout: 'vertical',
    contents: [
      {
        type: 'text',
        text: 'Brown Cafe',
        weight: 'bold',
        size: 'xl',
      },
      {
        type: 'text',
        text: 'Tokyo, Japan',
        size: 'sm',
        color: '#aaaaaa',
      },
    ],
  },
}

// Generates HTML markup string
const htmlString = render(flexJSON)

// Inject into HTML DOM element
document.getElementById('flex-container')!.innerHTML = htmlString
```

> **Note:** Don't forget to import `import 'flex-render/css'` in your entry file so all Flex Message styling (flexbox layouts, fonts, bubbles, carousels, action links) renders correctly.

---

## 📚 API Reference

### `render(flexJSON: FlexContainer): string`

Renders a LINE Flex Container (`FlexBubble` or `FlexCarousel`) into an HTML string ready for DOM insertion.

#### Parameters:

- `flexJSON`: A valid LINE Flex Container object conforming to the LINE Messaging API Flex Message spec (`Bubble` or `Carousel`).

#### Returns:

- `string`: Complete HTML representation wrapped in a `.flex-preview` container element.

---

## 🧩 Exported Types

`flex-render` exports TypeScript definitions for all LINE Flex Message structures:

```typescript
import type {
  FlexContainer,
  FlexBubble,
  FlexCarousel,
  FlexBox,
  FlexButton,
  FlexImage,
  FlexIcon,
  FlexText,
  FlexSpan,
  FlexSeparator,
  FlexFiller,
  FlexSpacer,
  FlexVideo,
} from 'flex-render'
```

---

## 🖼️ Framework Integration

If you are using React or Vue, official component wrappers are available:

- **React**: Use [`flex-render-react`](https://www.npmjs.com/package/flex-render-react) (`<FlexPreview json={flexJSON} />`)
- **Vue**: Use [`flex-render-vue`](https://www.npmjs.com/package/flex-render-vue) (`<FlexPreview :json="flexJSON" />`)

For demo applications, check out the [`apps/`](https://github.com/iamprompt/flex-render/tree/main/apps) folder in the GitHub repository.

---

## 🐛 Bug Reports

If you encounter any issues or rendering discrepancies, please report them on our [GitHub Issue Tracker](https://github.com/iamprompt/flex-render/issues).

---

## 📄 License

[MIT](https://opensource.org/licenses/MIT) © [Supakarn Laorattanakul (iamprompt)](https://github.com/iamprompt)
