# Edison PowerPoint Add-in Developer Documentation
This document provides detailed technical information for developers working on the Edison PowerPoint Add-in.
## Architecture Overview
Edison is a PowerPoint add-in built with:
- **TypeScript** for type-safe code
- **React** for UI components
- **Office.js API** for PowerPoint integration
- **Fluent UI** for Microsoft-style interface components
The application follows a component-based architecture where each tool is encapsulated in its own React component.
## Project Structure
```
/
├── assets/ # Images and icons
├── dist/ # Build output (generated)
├── src/
│ ├── commands/ # Command handlers
│ │ ├── commands.html # HTML for command UI
│ │ └── commands.ts # Command implementations
│ └── taskpane/ # Main add-in UI
│ ├── components/ # React components
│ │ ├── ActionButton.tsx # Reusable button with error handling
│ │ ├── AlignmentButtons.tsx
│ │ ├── App.tsx # Main application component
│ │ ├── ConfidentialButtons.tsx
│ │ ├── DraftButtons.tsx
│ │ ├── GridGuidelineManager.tsx
│ │ ├── Header.tsx
│ │ ├── InsertTitles.tsx
│ │ ├── MatchProperties.tsx
│ │ ├── MatchSizes.tsx
│ │ ├── ProgressBarButtons.tsx
│ │ ├── RoundImage.tsx
│ │ ├── Section.tsx # Reusable section component
│ │ ├── SmartTextFormatter.tsx
│ │ ├── SwapPositions.tsx
│ │ └── commonStyles.tsx
│ ├── types/ # TypeScript type definitions
│ │ └── office-types.ts # Office API type utilities
│ ├── index.tsx # Entry point
│ └── taskpane.html # Main HTML container
├── babel.config.json # Babel configuration
├── manifest.xml # Add-in manifest
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── webpack.config.js # Webpack configuration
```
## Development Environment Setup
### Prerequisites
- Node.js (LTS version recommended)
- npm
- Microsoft PowerPoint (desktop version)
### Setup Steps
1. Clone the repository:
```bash
git clone https://github.com/your-org/edison-powerpoint-addin.git
cd edison-powerpoint-addin
```
2. Install dependencies:
```bash
npm install
```
3. Build the project:
```bash
npm run build:dev
```
4. Start the development server:
```bash
npm run dev-server
```
5. Start the add-in in PowerPoint:
```bash
npm run start
```
### Local Development Certificates
Office Add-ins require HTTPS even for local development. The `office-addin-dev-certs` package is used to create and install self-signed certificates for development.
If you encounter certificate issues, run:
```bash
npx office-addin-dev-certs install
```
## Component Development Guidelines
### Reusable Components
#### ActionButton
A reusable button component that handles error states, loading states, and consistent styling:
```tsx
import ActionButton from "./ActionButton";
// In your component:
}
onClick={myAsyncFunction}
/>
```
#### Section
A consistent container for organizing the UI:
```tsx
import Section from "./Section";
// In your component:
```
### Creating a New Tool
1. Create a new component file in `src/taskpane/components/`
2. Import the necessary Office.js APIs and React hooks
3. Use the StatusContext for user feedback
4. Follow the pattern of existing components:
- Use the `PowerPoint.run()` method for PowerPoint operations
- Provide clear success/error messaging
- Handle selection states appropriately
Example component structure:
```tsx
import * as React from "react";
import { useState } from "react";
import { Button } from "@fluentui/react-components";
import { useStatusContext } from "./App";
const MyNewTool: React.FC = () => {
const { setStatusMessage, setStatusType, isProcessing, setIsProcessing } = useStatusContext();
const performAction = async () => {
setIsProcessing(true);
try {
await PowerPoint.run(async (context) => {
// Implement your PowerPoint operations here
await context.sync();
});
setStatusMessage("Operation completed successfully!");
setStatusType("success");
} catch (error) {
setStatusMessage(`Error: ${error.message}`);
setStatusType("error");
console.error("Operation error:", error);
} finally {
setIsProcessing(false);
}
};
return (
);
};
export default MyNewTool;
```
### Common PowerPoint.js Operations
#### Type-Safe Utilities
The application provides type-safe utility functions in `src/taskpane/types/office-types.ts`:
```typescript
// Get error message safely from any error type
const errorMsg = getErrorMessage(error);
// Check if a shape is an image
if (isPictureShape(shape)) {
// It's a picture shape
}
// Get the first selected slide
const slide = getFirstSelectedSlide(context);
// Select shapes by ID
selectShapesById(slide, [shape1.id, shape2.id]);
```
#### Selecting Shapes
```typescript
const shapes = context.presentation.getSelectedShapes();
shapes.load("items");
await context.sync();
```
#### Working with Slide Masters
```typescript
const slideMasters = context.presentation.slideMasters;
slideMasters.load("items");
await context.sync();
```
#### Creating Shapes
```typescript
const shape = slide.shapes.addGeometricShape("Rectangle");
shape.left = 100;
shape.top = 100;
shape.height = 50;
shape.width = 50;
await context.sync();
```
## Status System
The application includes a status system that provides feedback to users:
- **Success**: Operation completed successfully
- **Warning**: Operation completed with concerns
- **Error**: Operation failed
- **Processing**: Shows a spinner while operations are in progress
Use the status context in your components:
```typescript
const {
statusMessage,
setStatusMessage,
statusType,
setStatusType,
isProcessing,
setIsProcessing
} = useStatusContext();
```
## Build and Deployment
### Development Build
```bash
npm run build:dev
```
### Production Build
```bash
npm run build
```
### Manifest Validation
```bash
npm run validate
```
This validates the manifest.xml file against the Office Add-in schema.
## Testing
Currently, the project doesn't have automated tests. This is an area for future improvement.
Recommended testing approach:
1. Manual testing in PowerPoint
2. Implementation of unit tests for individual utilities
3. Integration tests for PowerPoint API interactions
## Performance Considerations
### Optimizing context.sync() calls
A key performance optimization is to batch context.sync() calls:
```typescript
// BAD: Calling context.sync() in a loop
for (let i = 0; i < shapes.items.length; i++) {
shapes.items[i].load("name");
await context.sync(); // Slow! One network roundtrip per shape
if (shapes.items[i].name === "Target") {
// Do something
}
}
// GOOD: Batching context.sync() calls
// Load all properties at once
for (let i = 0; i < shapes.items.length; i++) {
shapes.items[i].load("name");
}
await context.sync(); // Single network roundtrip for all shapes
// Process the data locally
for (let i = 0; i < shapes.items.length; i++) {
if (shapes.items[i].name === "Target") {
// Do something
}
}
```
Additional performance tips:
- Use memoization for expensive calculations
- Ensure proper cleanup of event listeners
- Use the ActionButton component for consistent loading states
- Consider using Web Workers for heavy computations
## Common Issues and Solutions
### Add-in not loading in PowerPoint
- Verify the development server is running
- Check for certificate errors in the browser console
- Validate the manifest.xml file
### PowerPoint API errors
- Ensure correct API version is being used
- Check the sequence of operations (some operations require specific order)
- Verify selections exist before operating on them
## Best Practices
1. **Error Handling**: Always use try/catch blocks with PowerPoint API calls and use proper types (see `office-types.ts`)
2. **User Feedback**: Provide clear status messages for all operations using the StatusContext
3. **Accessibility**: Ensure all UI elements have proper ARIA attributes and support keyboard navigation
4. **Theme Support**: Use Fluent UI theme tokens for consistent theming
5. **Code Organization**: Keep component files focused on a single responsibility
6. **Performance**: Batch context.sync() calls and avoid calling them inside loops
7. **Reusability**: Use custom hooks for common operations and shared components like ActionButton and Section
8. **Type Safety**: Avoid using "any" type and leverage TypeScript's static typing
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request with a clear description of the changes
## Resources
- [Office Add-ins Documentation](https://docs.microsoft.com/en-us/office/dev/add-ins/)
- [Office.js API Reference](https://docs.microsoft.com/en-us/javascript/api/overview/office)
- [Fluent UI Documentation](https://developer.microsoft.com/en-us/fluentui)
- [React Documentation](https://reactjs.org/docs/getting-started.html)