npm package: @ideacrafters/puck-vue
Description: Vue 3 wrapper for Puck visual editor
Author: Idea Crafters
Latest version: 0.1.0

# @ideacrafters/puck-vue

Vue 3 wrapper for [Puck](https://github.com/measuredco/puck) - The visual editor for React

[![npm version](https://badge.fury.io/js/@ideacrafters%2Fpuck-vue.svg)](https://badge.fury.io/js/@ideacrafters%2Fpuck-vue)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- 🎯 Full TypeScript support
- 🔄 Two-way data binding with v-model
- 🎨 All Puck features available
- 📦 Composables for state management
- 🚀 Optimized React-Vue bridge
- 📱 Responsive viewport support

## Installation

```bash
npm install @ideacrafters/puck-vue
# or
yarn add @ideacrafters/puck-vue
# or
pnpm add @ideacrafters/puck-vue
```

## Quick Start

```vue
<template>
  <PuckEditor :config="config" :data="data" @change="handleChange" />
</template>

<script setup>
import { ref } from 'vue'
import { PuckEditor } from '@ideacrafters/puck-vue'
import '@ideacrafters/puck-vue/style.css'

const data = ref({ content: [], root: {} })

const config = {
  components: {
    HeadingBlock: {
      render: ({ title }) => h('h1', title),
      fields: {
        title: { type: 'text' }
      }
    }
  }
}

const handleChange = (newData) => {
  data.value = newData
}
</script>
```

## Components

### PuckEditor

The main editor component with full Puck functionality.

```vue
<template>
  <PuckEditor
    :config="config"
    :data="data"
    @change="handleChange"
    @publish="handlePublish"
    header-title="My Page Builder"
    :viewports="viewports"
    :height="600"
  />
</template>
```

#### Props

- `config` (Config) - **Required**. Puck configuration object
- `data` (Partial<Data>) - Initial data for the editor
- `onChange` (function) - Callback when data changes
- `onPublish` (function) - Callback when data is published
- `onAction` (function) - Callback for custom actions
- `headerTitle` (string) - Title for the editor header
- `headerPath` (string) - Path displayed in header
- `viewports` (Array) - Responsive viewport configurations
- `height` (string | number) - Editor height (default: '100vh')
- `width` (string | number) - Editor width (default: '100%')
- `plugins` (Array) - Puck plugins
- `overrides` (Object) - Component overrides
- `iframe` (Object) - Iframe configuration
- `dnd` (Object) - Drag and drop configuration

#### Events

- `@change` - Emitted when data changes
- `@publish` - Emitted when publish button is clicked
- `@action` - Emitted for custom actions

### PuckPreview

Read-only component for rendering Puck data.

```vue
<template>
  <PuckPreview :config="config" :data="data" />
</template>
```

#### Props

- `config` (Config) - **Required**. Puck configuration object
- `data` (Data) - **Required**. Data to render

## Composables

### usePuck

State management composable with history support.

```ts
import { usePuck } from '@ideacrafters/puck-vue'

const { data, isDirty, handleChange, handlePublish, undo, redo, reset, canUndo, canRedo } = usePuck(config, {
  initialData: { content: [], root: {} },
  onChange: (data) => console.log('Changed:', data),
  onPublish: (data) => console.log('Published:', data)
})
```

#### Options

- `initialData` (Partial<Data>) - Initial data
- `onChange` (function) - Change callback
- `onPublish` (function) - Publish callback

#### Returns

- `data` (Ref<Data>) - Current data
- `isDirty` (Ref<boolean>) - Whether data has unsaved changes
- `handleChange` (function) - Handle data changes
- `handlePublish` (function) - Handle publish action
- `undo` (function) - Undo last change
- `redo` (function) - Redo last undone change
- `reset` (function) - Reset to initial data
- `canUndo` (Ref<boolean>) - Whether undo is available
- `canRedo` (Ref<boolean>) - Whether redo is available

## Configuration

Create a Puck configuration object:

```ts
import type { Config } from '@ideacrafters/puck-vue'

const config: Config = {
  components: {
    HeadingBlock: {
      render: ({ title, level = 1 }) => {
        return h(`h${level}`, title)
      },
      fields: {
        title: { type: 'text', label: 'Title' },
        level: {
          type: 'select',
          label: 'Heading Level',
          options: [
            { label: 'H1', value: 1 },
            { label: 'H2', value: 2 },
            { label: 'H3', value: 3 }
          ]
        }
      }
    },
    TextBlock: {
      render: ({ text }) => h('p', text),
      fields: {
        text: { type: 'textarea', label: 'Text' }
      }
    }
  }
}
```

## Viewports

Configure responsive viewports:

```ts
const viewports = [
  { width: 360, label: 'Mobile' },
  { width: 768, label: 'Tablet' },
  { width: 1280, label: 'Desktop' }
]
```

## Global Plugin Installation

```ts
import { createApp } from 'vue'
import PuckVue from '@ideacrafters/puck-vue'

const app = createApp(App)
app.use(PuckVue)
```

After installation, components are available globally:

```vue
<template>
  <div>
    <puck-editor :config="config" :data="data" />
    <puck-preview :config="config" :data="data" />
  </div>
</template>
```

## Development

```bash
# Install dependencies
npm install

# Start playground
npm run dev

# Build library
npm run build

# Run tests
npm test

# Type check
npm run type-check

# Lint
npm run lint
```

## Examples

Check out the playground in the `playground/` directory for a complete example.

## Requirements

- Vue 3.3+
- Node.js 16+

## License

MIT © [Idea Crafters](https://github.com/IdeaCraftersHQ)

## Contributing

Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md).

## Support

- 📧 Email: hello@ideacrafters.com
- 🐛 Issues: [GitHub Issues](https://github.com/IdeaCraftersHQ/puck-vue/issues)
- 📖 Documentation: [GitHub Repository](https://github.com/IdeaCraftersHQ/puck-vue)