npm package: @phrogdesign/pptx-controller
Description: PowerPoint-style formatting toolbar that works with any HTML structure. Includes Home, Insert, Shape Format, and Image Format tabs.
Author: PhrogDesign
Latest version: 1.0.1

# @phrogdesign/pptx-controller

PowerPoint-style formatting toolbar that works with **any HTML structure**. Perfect for PPTX viewers, presentation editors, and WYSIWYG editors.

## ✨ Features

- 🏠 **Home Tab:** Text formatting (Bold, Italic, Fonts, Colors, Alignment, Lists)
- ➕ **Insert Tab:** Add Shapes, Images, Text Boxes
- 🎨 **Shape Format Tab:** Style shapes (Fill, Outline, Effects, Rotate, Flip)
- 🖼️ **Image Format Tab:** Edit images (Filters, Brightness, Contrast)
- 🚀 **Zero Dependencies:** Pure vanilla JavaScript
- 📦 **Tiny:** ~7KB gzipped
- ⚡ **Universal:** Works with React, Vue, Angular, or plain HTML
- 🎯 **Smart:** Auto-switches tabs when clicking shapes/images

## 🚀 Installation

```bash
npm install @phrogdesign/pptx-controller
```

Or with yarn:
```bash
yarn add @phrogdesign/pptx-controller
```

Or via CDN:
```html
<script src="https://unpkg.com/@phrogdesign/pptx-controller"></script>
```

## 📖 Quick Start

### Vanilla JavaScript / HTML

```html
<!DOCTYPE html>
<html>
<head>
  <title>My App</title>
</head>
<body>
  
  <!-- Auto-init toolbar -->
  <div data-pptx-controller></div>

  <!-- Your content -->
  <div class="editable-content">
    <h1>Your PPTX HTML here</h1>
    <p>Any structure works!</p>
  </div>

  <!-- Include script -->
  <script src="node_modules/@phrogdesign/pptx-controller/dist/pptx-controller.js"></script>
  
</body>
</html>
```

### React

```jsx
import React, { useEffect, useRef } from 'react';
import '@phrogdesign/pptx-controller';

function Editor() {
  const contentRef = useRef(null);

  useEffect(() => {
    const controller = new window.PPTXController({
      targetSelector: '.editable-content',
      onChange: (html) => {
        console.log('Content changed:', html);
      }
    });

    return () => controller.destroy();
  }, []);

  return (
    <div>
      <div data-pptx-controller></div>
      <div ref={contentRef} className="editable-content">
        <h1>Start editing</h1>
      </div>
    </div>
  );
}

export default Editor;
```

### Vue

```vue
<template>
  <div>
    <div data-pptx-controller></div>
    <div ref="content" class="editable-content">
      <h1>Start editing</h1>
    </div>
  </div>
</template>

<script>
import '@phrogdesign/pptx-controller';

export default {
  mounted() {
    this.controller = new window.PPTXController({
      targetSelector: '.editable-content',
      onChange: (html) => {
        console.log('Content changed:', html);
      }
    });
  },
  beforeUnmount() {
    this.controller?.destroy();
  }
}
</script>
```

### Angular

```typescript
import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import '@phrogdesign/pptx-controller';

@Component({
  selector: 'app-editor',
  template: `
    <div data-pptx-controller></div>
    <div class="editable-content">
      <h1>Start editing</h1>
    </div>
  `
})
export class EditorComponent implements AfterViewInit, OnDestroy {
  private controller: any;

  ngAfterViewInit() {
    this.controller = new (window as any).PPTXController({
      targetSelector: '.editable-content',
      onChange: (html: string) => {
        console.log('Content changed:', html);
      }
    });
  }

  ngOnDestroy() {
    this.controller?.destroy();
  }
}
```

## 🎯 API Reference

### Initialization

```javascript
const controller = new PPTXController(options);
```

### Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `targetSelector` | `string` | `'.editable-content'` | CSS selector for editable elements |
| `toolbarContainer` | `HTMLElement \| string \| null` | `null` | Where to mount toolbar |
| `toolbarPosition` | `'top' \| 'sticky' \| 'floating'` | `'top'` | Toolbar positioning |
| `autoMount` | `boolean` | `true` | Auto-initialize on load |
| `showToolbar` | `boolean` | `true` | Show/hide toolbar |
| `onChange` | `function` | `null` | Callback when content changes |
| `onFormatChange` | `function` | `null` | Callback when formatting applied |
| `onShapeInsert` | `function` | `null` | Callback when shape inserted |
| `onImageInsert` | `function` | `null` | Callback when image inserted |

### Methods

```javascript
// Get content HTML
const html = controller.getContent();

// Set content HTML
controller.setContent('<h1>New content</h1>');

// Destroy controller
controller.destroy();
```

### Events

```javascript
new PPTXController({
  // Content changed
  onChange: (html, element) => {
    console.log('HTML:', html);
    console.log('Element:', element);
  },
  
  // Formatting applied
  onFormatChange: (command, value) => {
    console.log('Command:', command);
    console.log('Value:', value);
  },
  
  // Shape inserted
  onShapeInsert: (type, element) => {
    console.log('Shape type:', type);
    console.log('Element:', element);
  },
  
  // Image inserted
  onImageInsert: (element) => {
    console.log('Image:', element);
  }
});
```

## 🎨 Customization

### Custom Styling

The toolbar can be customized via CSS:

```css
/* Customize toolbar background */
.pptx-controller-toolbar .toolbar-main {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* Customize active tab color */
.pptx-controller-toolbar .tab-btn.active {
  background: #your-color;
}
```

### Custom Target Elements

```javascript
// Multiple elements
new PPTXController({
  targetSelector: '.slide-1, .slide-2, .slide-3'
});

// Specific element
const element = document.getElementById('my-editor');
new PPTXController({
  targetSelector: '#my-editor'
});
```

### Backend Integration

```javascript
new PPTXController({
  targetSelector: '.editable-content',
  onChange: async (html) => {
    // Auto-save to backend
    await fetch('/api/save', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ content: html })
    });
  }
});
```

## 🔧 Advanced Usage

### Manual Initialization

```html
<!-- Don't use auto-init -->
<div id="toolbar-container"></div>
<div class="editable-content">Content</div>

<script>
  const controller = new PPTXController({
    toolbarContainer: '#toolbar-container',
    targetSelector: '.editable-content',
    autoMount: false
  });
  
  // Initialize manually
  controller.init();
</script>
```

### Multiple Instances

```javascript
// Editor 1
const editor1 = new PPTXController({
  toolbarContainer: '#toolbar-1',
  targetSelector: '#content-1'
});

// Editor 2
const editor2 = new PPTXController({
  toolbarContainer: '#toolbar-2',
  targetSelector: '#content-2'
});
```

### With State Management (React)

```jsx
import { useState } from 'react';

function Editor() {
  const [content, setContent] = useState('<h1>Initial</h1>');

  useEffect(() => {
    const controller = new PPTXController({
      targetSelector: '.editable-content',
      onChange: (html) => {
        setContent(html);
        // Trigger re-render or save
      }
    });

    return () => controller.destroy();
  }, []);

  return (
    <div>
      <div data-pptx-controller></div>
      <div 
        className="editable-content"
        dangerouslySetInnerHTML={{ __html: content }}
      />
    </div>
  );
}
```

## ❓ FAQ

### Does it work with my HTML structure?

**Yes!** The controller uses browser's native `contentEditable` and `execCommand` APIs, which work with ANY valid HTML structure. Whether your HTML comes from PowerPoint conversion, React components, Vue templates, or handwritten HTML - it all works the same way.

### Does it require jQuery or other dependencies?

**No!** Pure vanilla JavaScript with zero dependencies.

### Can I use it with TypeScript?

**Yes!** Type definitions are included:

```typescript
import type { PPTXController, PPTXControllerOptions } from '@phrogdesign/pptx-controller';
```

### Does it work on mobile?

**Yes!** The controller works on mobile browsers, though some advanced features depend on browser support.

### Can I customize the toolbar?

**Yes!** You can customize via CSS, hide tabs, or build your own UI and just use the API methods.

### How do I save the content?

Use the `onChange` callback:

```javascript
new PPTXController({
  onChange: async (html) => {
    await saveToBackend(html);
  }
});
```

## 📦 Bundle Sizes

| Version | Size |
|---------|------|
| Full (uncompressed) | ~36KB |
| Minified | ~18KB |
| Minified + Gzipped | ~7KB |

## 🌐 Browser Support

- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- iOS Safari (latest)
- Chrome Mobile (latest)

## 📄 License

MIT License - see LICENSE file for details

## 🤝 Contributing

Contributions welcome! Please open an issue or submit a pull request.

## 📞 Support

- 📧 Email: support@phrogdesign.com
- 🐛 Issues: https://github.com/phrogdesign/pptx-controller/issues
- 📖 Docs: https://phrogdesign.com/pptx-controller/docs

## 🎉 Credits

Built with ❤️ by PhrogDesign