# @vigilkids/section-renderer-vue

Vue 3 rendering engine for OneX Section system. Renders section-based content with product-aware component resolution, lazy loading, inline editing, and editor preview support.

## Install

```bash
pnpm add @vigilkids/section-renderer-vue
```

**Peer Dependencies:**
- `vue` ≥ 3.4

## Usage

### Frontend (Nuxt/Vue app)

```vue
<script setup>
import { SectionRenderer, registerArticleSections, SectionRendererPlugin } from '@vigilkids/section-renderer-vue'

// Register built-in article sections (call once at app startup)
registerArticleSections()
</script>

<template>
  <SectionRenderer
    :sections-data="article.content_json"
    :product-code="'visiva'"
  />
</template>
```

### Admin Preview (iframe)

```typescript
import { createPreviewApp } from '@vigilkids/section-renderer-vue/editor'

createPreviewApp('#app', {
  bridge: { send, on },
  onSectionClick: (id) => { /* select section */ },
})
```

### Product Styles

```typescript
// Import product-specific article CSS
import '@vigilkids/section-renderer-vue/styles/vigilkids'
import '@vigilkids/section-renderer-vue/styles/visiva'
```

### Raw HTML Utility Classes

适用于 `article-custom-html` 或原始 HTML 模板，作用域限定在 `.article-content`：

- 间距：`mt-{n}` `mb-{n}` `ml-{n}` `mr-{n}` `p-{n}` `px-{n}` `py-{n}`
- 自动居中：`ml-auto` `mr-auto` `mx-auto`
- 布局：`block` `inline-block`
- 宽度：`w-full` `w-fit`
- 字号：`text-12` ~ `text-36`
- 字重：`font-normal` `font-medium` `font-semibold` `font-bold` `font-black`
- 对齐：`text-left` `text-center` `text-right`
- 行高：`leading-tight` `leading-normal` `leading-relaxed` `leading-loose`
- 表格容器：`table-fixed`（用在 `<table>`，启用固定列宽布局 + 自动换行）
- 列宽（像素）：`col-60` `col-80` `col-100` `col-120` `col-150` `col-180` `col-200` `col-250` `col-300` `col-350` `col-400` `col-500`
- 列宽（百分比）：`col-10p` `col-15p` `col-20p` `col-25p` `col-30p` `col-33p` `col-40p` `col-50p` `col-60p` `col-66p` `col-70p` `col-75p` `col-80p`

示例：

```html
<img class="block w-fit mx-auto mb-20" src="..." alt="..." />
<p class="mb-20 text-18 font-bold">%base_year%</p>

<!-- 表格列宽：必须先在 <table> 加 .table-fixed，.col-* 才会生效 -->
<table class="table-fixed">
  <colgroup>
    <col class="col-120" />
    <col class="col-300" />
    <col class="col-25p" />
  </colgroup>
  <thead>
    <tr><th>方法</th><th>说明</th><th>限制</th></tr>
  </thead>
</table>
```

## Components

| Component | Purpose |
|-----------|---------|
| `SectionRenderer` | Root renderer — iterates sections, resolves components |
| `SectionWrapper` | Per-section container with editor-mode highlights |
| `LazySection` | IntersectionObserver lazy loading with CLS prevention |
| `SectionErrorBoundary` | Graceful error fallback per section |
| `FallbackSection` | Placeholder for unregistered section types |

## Composables

| Composable | Purpose |
|------------|---------|
| `useInlineEdit` | contentEditable inline text editing (double-click to edit) |
| `useRegistry` | Product-aware section component registration and resolution |
| `useSectionStyle` | Semantic tokens → Tailwind classes + inline styles |
| `useSectionSEO` | JSON-LD structured data generation |
| `useLazyRender` | IntersectionObserver visibility detection |

## Section Components

28 article sections across 2 products (VigilKids + Visiva) + 2 shared:

`article-heading`, `article-subheading`, `article-image`, `article-bullet-list`, `article-step-list`, `article-notice`, `article-quote`, `article-question`, `article-pros-cons`, `article-feature`, `article-cta`, `article-faq`, `article-table`, `article-toc`, `article-custom-html`

## Compatibility

- Vue ≥ 3.4
- Node.js ≥ 18
- ESM only

## License

[MIT](./LICENSE)
