# 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)